Информация об изменениях

Сообщение Re: volatile-only lock от 29.06.2017 16:45

Изменено 29.06.2017 16:51 Кодт

Re: volatile-only lock
Здравствуйте, nikholas, Вы писали:

N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)


Делаем корявый test-and-set

struct Request {
  int oldvalue, newvalue;
  bool done, success;
};

class AtomicVar {
  volatile Request* request = nullptr;

  int var; // к ней имеет доступ только поток
  thread helper = thread([]() {
    while (true) {
      Request* r = request;
      if (!r) {
        sleep();
        continue;
      }
      if (var == r->oldvalue) { var = r->newvalue; r->success = true; } else { r->success = false; }
      r->done = true;
      // все, кто написал в этот момент, - неудачники. ничего, покрутят цикл.
      request = nullptr;
    }
  });

public:
  bool test_and_set(int oldvalue, int newvalue) {
    Request req = { oldvalue, newvalue, false, false };
    request = &req;
    while(!req.done && request == &req) sleep(); // либо нашу заявку выполнили, либо перебили, либо выполнили и затем перебили
    return req.success;
  }
};
Re: volatile-only lock
Здравствуйте, nikholas, Вы писали:

N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)


Делаем корявый test-and-set

struct Request {
  int oldvalue, newvalue;
  bool done, success;
};

class AtomicVar {
  volatile Request* request = nullptr;

  int var; // к ней имеет доступ только поток-помощник
  thread helper = thread([]() {
    while (true) {
      Request* r = request;
      if (!r) {
        sleep();
        continue;
      }
      if (var == r->oldvalue) { var = r->newvalue; r->success = true; } else { r->success = false; }
      r->done = true;
      // все, кто написал в этот момент, - неудачники. ничего, покрутят цикл.
      request = nullptr;
    }
  });

public:
  bool test_and_set(int oldvalue, int newvalue) {
    Request req = { oldvalue, newvalue, false, false };
    request = &req;
    while(!req.done && request == &req) sleep(); // либо нашу заявку выполнили, либо перебили, либо выполнили и затем перебили
    return req.success;
  }
};