views:

79

answers:

2

Are there locks in Linux where the waiting queue is FIFO? This seems like such an obvious thing, and yet I just discovered that pthread mutexes aren't FIFO, and semaphores apparently aren't FIFO either (I'm working on kernel 2.4 (homework))...

Does Linux have a lock with FIFO waiting queue, or is there an easy way to make one with existing mechanisms?

+2  A: 

If you are asking what I think you are asking the short answer is no. Threads/processes are controlled by the OS scheduler. One random thread is going to get the lock, the others aren't. Well, potentially more than one if you are using a counting semaphore but that's probably not what you are asking.

You might want to look at pthread_setschedparam but it's not going to get you where I suspect you want to go.

You could probably write something but I suspect it will end up being inefficient and defeat using threads in the first place since you will just end up randomly yielding each thread until the one you want gets control.

Chances are good you are just thinking about the problem in the wrong way. You might want to describe your goal and get better suggestions.

Duck
I have a server-client situation going on and the server needs to keep a log file in such a way that writing into it will not interfere with its I/O, meaning that a server-clent connection thread cannot go to wait because it is waitingfor a mutex for the log faile that another such thread locked. I was thinking about throwing each entry into a separate "write to logfile" thread which can go to wait without interfering with it's parent thread. The messages in logfile can be mixedup, but must maintain proper chronology per connection, which is why I need a FIFO.
EpsilonVector
Set up a queue. The c-s connections write their log info to the queue. A separate thread reads the queue and writes to the file. You still have to acquire a lock on the queue but unless you know otherwise this should be irrelevant. The amount of time acquiring the queue lock will be dwarfed by the relative slowness of file and network I/O. Since any given c-s thread is writing to the queue in order your log output will likewise be in order per thread.
Duck
Yeah that's what I wanted to avoid doing (would require more changes than a FIFIO lock), but I guess I don't have a choice anymore...
EpsilonVector
+2  A: 

Here is a way to create a simple queueing "ticket lock", built on pthreads primitives. It should give you some ideas:

#include <pthread.h>

typedef struct ticket_lock {
    pthread_cond_t cond;
    pthread_mutex_t mutex;
    unsigned long queue_head, queue_tail;
} ticket_lock_t;

#define TICKET_LOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }

void ticket_lock(ticket_lock_t *ticket)
{
    unsigned long queue_me;

    pthread_mutex_lock(&ticket->mutex);
    queue_me = ticket->queue_tail++;
    while (queue_me != ticket->queue_head)
    {
        pthread_cond_wait(&ticket->cond, &ticket->mutex);
    }
    pthread_mutex_unlock(&ticket->mutex);
}

void ticket_unlock(ticket_lock_t *ticket)
{
    pthread_mutex_lock(&ticket->mutex);
    ticket->queue_head++;
    pthread_cond_broadcast(&ticket->cond);
    pthread_mutex_unlock(&ticket->mutex);
}
caf