2

I am trying to implement a mutex in c using the fetch and increment algorithm (sort of like the bakery algorithm). I have implemented the fetch and add part atomically. I have every thread obtain a ticket number and wait for their number to be "displayed". However, I have not found a way to tackle the issue of waiting for your ticket to be displayed. I have thought of using a queue to store your thread ID and descheudle/yield yourself until someone who has the lock, wakes you up. However, I would need a lock for the queue as well! :(

Are there any recommendations on what I could do to make the queue insertion safe or perhaps a different approach to using a queue?

Here is some code of my initial implementation:

void mutex_lock( mutex_t *mp ) {
  while (compareAndSwap(&(mp->guard), 0, 1) == 1) {
    // This will loop for a short period of time, Need to change this <--
  }
  if ( mp->lock == 1 ) {
    queue_elem_t elem;
    elem.data.tid = gettid();
    enq( &(mp->queue), &(elem) );
    mp->guard = 0;
    deschedule();
  }
  else {
    mp->lock = 1; // Lock the mutex
    mp->guard = 0; // Allow others to enq themselves
  }
}

Also, lets for now ignore the potential race condition where someone can call make_runnable before you call deschedule, I can write another system call that will say we are about to deschedule so queue make_runnable calls.

CR7
  • 61
  • 1
  • 7
  • You could write the thread ID's to a file and use the unix file lock (http://stackoverflow.com/questions/575328/fcntl-lockf-which-is-better-to-use-for-file-locking) – noMAD Mar 30 '15 at 20:41
  • Why are you doing this? Are you aware that for doing a correct implementation of things like this you need atomic operations? Are you aware that there is no way to have non-busy wait without support from the OS? – Jens Gustedt Mar 30 '15 at 21:06
  • ... though the OS support can be pretty trivial, e.g. `pause()` + guard for false wakeups + `signal()` – abligh Mar 30 '15 at 21:29
  • I have two functions from an OS, I wrote myself. The first is called deschedule, which when called will make a process not runnable. Its counter part, is make_runnable(int tid) which makes a given thread runnable. So its sort of the like park and unpark system calls provided by the Solaris OS. – CR7 Mar 31 '15 at 16:15
  • 1
    Go ahead bro, keep searching and exploring!!!. When someone tries this trip is because one feels the NEED to understand it better, from bare bones... like it should always be!!!. – fante Jan 18 '17 at 12:43

0 Answers0