Home > Software engineering >  How can I fake mutex context in C/C ?
How can I fake mutex context in C/C ?

Time:12-28

I've been reading through and attempting to apply Tyler Hoffman's C/C unit testing strategies.

He offers the following as a way to fake a mutex:

#define NUM_MUTEXES 256

typedef struct Mutex {
  uint8_t lock_count;
} Mutex;

static Mutex s_mutexes[NUM_MUTEXES];
static uint32_t s_mutex_index;

// Fake Helpers

void fake_mutex_init(void) {
  memset(s_mutexes, 0, sizeof(s_mutexes));
}

bool fake_mutex_all_unlocked(void) {
  for (int i = 0; i < NUM_MUTEXES; i  ) {
    if (s_mutexes[i].lock_count > 0) {
      return false;
    }
  }
  return true;
}

// Implementation

Mutex *mutex_create(void) {
  assert(s_mutex_index < NUM_MUTEXES);
  return &s_mutexes[s_mutex_index  ];
}

void mutex_lock(Mutex *mutex) {
  mutex->lock_count  ;
}

void mutex_unlock(Mutex *mutex) {
  mutex->lock_count--;
}

For a module that has functions like:

#include "mutex/mutex.h"

static Mutex *s_mutex;

void kv_store_init(lfs_t *lfs) {
  ...
  s_mutex = mutex_create();
}

bool kv_store_write(const char *key, const void *val, uint32_t len) {
  mutex_lock(s_mutex); // New
  ...
  mutex_unlock(s_mutex); // New
  analytics_inc(kSettingsFileWrite);
  return (rv == len);
}

After being setup in a test like:

TEST_GROUP(TestKvStore) {
  void setup() {
    fake_mutex_init();
    ...
  }
  ...
}

I'm confused about a couple things:

  1. How does fake_mutex_init() cause methods using mutex_lock and mutex_unlock to use the fake lock and unlock?
  2. How does this actually fake mutex locking? Can I produce deadlocks with these fakes? Or, should I just be checking the lock count in my tests?

CodePudding user response:

How does fake_mutex_init() cause methods using mutex_lock and mutex_unlock to use the fake lock and unlock?

It doesn't. It's unrelated.

In the tutorial, the tests are linked with one of the implementations. In the case of this specific test, it is linked with this fake mutex implementation.

How does this actually fake mutex locking?

It just increments some integers inside an array. There is no "locking" involved in any way.

Can I produce deadlocks with these fakes?

No, because there is locking, there is no waiting, so there are no deadlocks, which occur when two threads wait for each other.

Or, should I just be checking the lock count in my tests?

Not, in "tests" - for tests mutex is an abstract thing.

Adding assert(mutex->lock_count > 0) to unlock to check if your tests do not unlock a mutex twice seems like an obvious improvement.

  • Related