Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

One approach for preventing data races in concurrent programming is the mutex. When properly observed by all threads, a mutex can provide safe and secure access to a common shared object. However, mutexs provide no guarantees with regard to other objects that might be accessed when the mutex is not controlled by the accessing thread. Unfortunately, there is no portable way to determine which adjacent variables may be stored along with a certain variable.

...

Code Block
bgColor#ccccff
langc
#include <threads.h>
#include <assert.h>
 
struct multi_threaded_flags {
  unsigned int flag1 : 2;
  unsigned int flag2 : 2;
};

union mtf_protect {
  struct multi_threaded_flags s;
  long padding;
};
struct mtf_mutex {
  union mtf_protect u;
  mtx_t mutex;
};

struct mtf_mutex flags;

void chk_flags(void) {
  static_assert(
    sizeof(long) >=
              sizeof(struct multi_threaded_flags),
              "A long type will not hold the flags on this architecture."
  );
}

int thread1(void *arg) {
  if (thrd_success != mtx_lock(&flags.mutex)) {
    /* Handle error */
  }
  flags.u.s.flag1 = 1;
  if (thrd_success != mtx_unlock(&flags.mutex)) {
    /* Handle error */
  }
  return 0;
}
 
int thread2(void *arg) {
  if (thrd_success != mtx_lock(&flags.mutex)) {
    /* Handle error */
  }
  flags.u.s.flag2 = 2;
  if (thrd_success != mtx_unlock(&flags.mutex)) {
    /* Handle error */
  }
  return 0;
}

...