Skip to main content
2 of 8
added 8 characters in body
DannyNiu
  • 374
  • 1
  • 19

I thought of 2 solutions, both valid, yet each suited for particular purposes the other doesn't.

  1. Use RW-Lock provided by the host, and include explicit memory fencing call when releasing he reader lock. Example of releasing reader lock:
#include <stdatomic.h>
#include <pthread.h>
...
    atomic_thread_fence(memory_order_release);
    pthread_rwlock_unlock(&gc->thr_xor_gc);
...

Advantages:

  • performance optimized by OS,
  • realtime-aware,
  1. Use regular mutices and condition variables. Example of releasing reader lock:
#include <pthread.h>
...
    pthread_lock(&gc->lock_main); // the master lock of the entire GC structure.
    if( &gc->inprogress_gc ) // the boolean indicating whether GC thread is active
    {
        pthread_unlock(&gc->lock_main);
        return; // may return a value if appropriate.
    }
    gc->inprogress_threads --; // count of reading threads.
    pthread_cond_signal(&gc->cv_writer);
    pthread_unlock(&gc->lock_main);
...

Advantages:

  • If I want application threads to stall when there's any thread that's blocked attempting to do GC, I can customimze this behavior (where as regular RW-Lock cannot do that explicitly, unless optional POSIX APIs that alters scheduling are available).

  • All fences are implicit.


The latest GCC and Clang compilers support the atomic_thread_fence function, and Single Unix Specification mandate implementations to support all pthread interfaces. For earlier versions of the compilers and OSes, compiler built-ins and vendor-specific APIs may be available. For toolchains and platforms LACKING ALL of these, probably they'll not be supporting multi-threading in the first place.

DannyNiu
  • 374
  • 1
  • 19