Comment by mgaunard

3 months ago

They're not, the interactions with the memory model are different, as are the guarantees.

CPS shouldn't be able to deadlock for example?

CPS can trivially deadlock for all meaningful definitions of deadlock.

Would you consider this a mutex?

   async_mutex mux;

   co_await mux.lock();
   /* critical section */
   co_await mux.unlock();
   

What about: my_mutex mux;

   {
      std::lock_guard _{mux};
      /* critical section */
   }

where the code runs in a user space fiber.

Would you consider boost synchronized a mutex?

Don't confuse the semantics with the implementation details (yes async/await leaks implementation details).

  • You only achieved a deadlock by re-introducing mutexes.

    • Given:

          Something someting;
          async_mutex mtx;
          void my_critical_section(Data&);
      

      1:

          await mtx.lock();
          my_critical_section(something);
          await mtx.unlock();
      

      2:

          auto my_locked_critical_section() {
            await mtx.lock();
            my_critical_section(something);
            await mtx.unlock();
          }
          ...    
          await my_locked_critical_section(something);
      

      3:

          auto locked(auto mtx, auto critical_section) {
            await mtx.lock();
            critical_section();
            await mtx.unlock();
          }
      
          ...    
          await locked(mtx, [&]{ my_critical_section(something); });
      

      4:

          template<class T>
          struct synchronized {
             async_mutex mtx;
             T data;
             auto async_visit(auto fn) { locked(mtx, [fn,&data]{ fn(data); }); }
          };
      
          synchronized<Something> something;
          await something.async_visit([](Something& data) { my_critical_section(something); });
      

      If 1 is a mutex, at which point it stops being a mutex? Note that 4 is my initial example.

      3 replies →