1

So I think I understand the source code for a signal and a wait (the wait being a lock) but I am not sure how to implement a try lock. Here is my code for a wait:

//if s->type is zero it is a binary semaphore type
if (s->type == 0)
    {
            // binary semaphore
            // if state is zero, then block task

            if (s->state == 0)
            {
                             // block task


                    // ?? move task from ready queue to blocked queue

                              //reschedule the tasks
                    return 1;
            }
            // state is non-zero (semaphore already signaled)
            s->state = 0;                // reset state, and don't block
            return 0;
    }
    else
    {
            // counting semaphore
            s->state--;
            // ?? implement counting semaphore
            if (s->state < 0)
            {


            }
    }

This is what I have for a try lock so far:

if (s->type == 0)
{
            // binary semaphore
            // if state is zero, then block task

            if (s->state == 0)
            {
                    tcb[curTask].event = s;         // block task
                    tcb[curTask].state = S_BLOCKED;

                    removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
                    enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
                    return 1;
            }
            // state is non-zero (semaphore already signaled)
            s->state = 1;                                           // reset state, and don't block
            return 0;
}
else
{
        s->state--;
        if (s->state >= 0)
        {
            s->state++;
        }
        else
        {
            tcb[curTask].event = s;
            tcb[curTask].state = S_BLOCKED;
            removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
            enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
        }
}
Guybrush Threepwood
  • 3,333
  • 2
  • 19
  • 26
  • 1
    try-wait/try-lock you try locking on semaphore, return immediately(non-blocking) with some error-code if it has been locked by other process. – जलजनक Oct 13 '12 at 20:51

2 Answers2

4

A regular spin lock is implemented something like this (pseudo-C-codish):

void lock(locktype_t* LockVariable)
{
  while (CompareAndSwap(LockVariable,
                        STATE_UNLOCKED /* state to wait for */,
                        STATE_LOCKED /* new state to try to set */) !=
         STATE_UNLOCKED /* expected state at the beginning of CAS() */)
  {
    // spin here, doing nothing useful, waiting for *LockVariable to
    // first become STATE_UNLOCKED (CAS() returns its last value), after
    // which we will set it to STATE_LOCKED (CAS() will do that atomically)
  }
}

void unlock(locktype_t* LockVariable)
{
  *LockVariable = STATE_UNLOCKED;
}

In case where indefinite spinning and waiting for the lock to become first unlocked is undesirable, we use a loop-less variant of the above something like this:

int tryToLock(locktype_t* LockVariable)
{
  if (CompareAndSwap(LockVariable,
                     STATE_UNLOCKED /* state to wait for */,
                     STATE_LOCKED /* new state to try to set */) !=
      STATE_UNLOCKED /* expected state at the beginning of CAS() */)
  {
    return 0; // the lock is still held by someone else, bail out
  }
  return 1; // the lock is now held by us, hurray!
}

Compare-and-swap

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Would `if (AtomicSwap(LockVariable, STATE_LOCKED) == STATE_LOCKED) return 0;` work too? – a3f Mar 18 '16 at 12:38
  • Answering my own question: Ye, it would. [This answer](http://stackoverflow.com/questions/5339769/relative-performance-of-swap-vs-compare-and-swap-locks-on-x86) might be relevant. – a3f Aug 03 '16 at 15:20
0

I was looking for a non-spin lock trylock. I have figured out what to do. If it is a counting semaphore, then I decrement if the count is positive and I consume the resource. If it is zero or less, I do nothing but return an error code. I do not decrement the count or consume the resource. The program is then able to continue past that point. If it is a binary semaphore, I consume it if the resource is available. I then change the value of the binary semaphore to consumed. If it isn't available, then I return an error code.

Guybrush Threepwood
  • 3,333
  • 2
  • 19
  • 26