Squadrick / shadesmar

Fast C++ IPC using shared memory
MIT License
550 stars 84 forks source link

Clarification about RobustLock::lock #51

Closed liuxw7 closed 2 years ago

liuxw7 commented 2 years ago
void RobustLock::lock() {
  while (!mutex_.try_lock()) {
    if (exclusive_owner.load() != 0) {
      auto ex_proc = exclusive_owner.load();
      if (proc_dead(ex_proc)) {
        // Here, I thought, ex_proc is always equal to exclusive_owner.
        // Why not remove the compare_exchange_strong check?
        if (exclusive_owner.compare_exchange_strong(ex_proc, 0)) {
          mutex_.unlock();
          continue;
        }
      }
    } else {
      prune_readers();
    }

    std::this_thread::sleep_for(std::chrono::microseconds(1));
  }
  exclusive_owner = getpid();
}
Squadrick commented 2 years ago

I've written about the need for the extra compare_exchange_strong in this blog. If that isn't clear, I can elucidate further.

liuxw7 commented 2 years ago

Perfect! When I tested it, I found CPU is very high: 100%, 75%. How to improve it?

Squadrick commented 2 years ago

@liuxw7 That's mostly due to pub-sub being a poll, rather than a signal. The ideal way would be to limit the rate at which spin is called:

while (true) {
  std::this_thread::sleep_for(milliseconds(10));
  subscriber.spin_once();
}

The above will run the subscriber 100 times per second (ignoring the time taken for callback). This will reduce CPU usage.

I'm currently trying to figure out ways to replace this poll with a signal (similar to how RPC works), but for now, rate limiting is your best option.