views:

81

answers:

4

I have this requirement wherein I have to increment the value of a POSIX semaphore by more than 1.

Apparently, there is no way in POSIX specification to do this. There is no sem_setvalue() similar to sem_getvalue(). I do not want to go back to System V semaphores just because of this constraint.

Is there any alternative way to accomplish this? Or will I have to go the System V way?

I am programming in C on GNU/Linux.

Great thanks in advance.

A: 

If that is the complete specification, I think your teacher wants you to come up with a mechanism that will allow you to increment a semaphore by more than one atomically. So my guess is that one of your tasks is to synchronize the incrementation.

soulmerge
That is partly true. One of the options is to make the incrementation atomic. But I would like to know whether or not there is an "elegant" alternative to that in POSIX (the way there is in SysV)
puffadder
+1  A: 

semctl and semop are what you need.Use GETVAL SETVAL in smectl for getter and setter.Set sem_op in sembuf struct to what you want to do with the semaphore when using semop. See man for more.

schemacs
These work on System V semaphores, which the OP explicitly excluded.
Jens Gustedt
A: 

No there is no such alternative when working with sem_t. If you have not yet done so, read the sem_overview man page on linux. The calls that are listed there are all you can get: initialization to a specific value, increment and decrement by one.

Jens Gustedt
+1  A: 

I have this requirement wherein I have to increment the value of a POSIX semaphore by more than 1. Is there any alternative way to accomplish this? Or will I have to go the System V way?

So what is your question really? How to implement something not supported by interface? Or how to create a structure behaving like semaphore using POSIX?

If this is later, before resorting to heavy guns like SysV, you can always use the pthread_mutex_t/pthread_cond_t pair to implement pretty much any multi-threading synchronization primitive, semaphore included.

E.g., untested:

typedef cool_sem {
    pthread_mutex_t guard;
    pthread_cond_t cond;
    int count;
} cool_sem_t;

void init( cool_sem_t *s )
{
    pthread_mutex_init( &s->guard, 0 );
    pthread_cond_init( &s->cond, 0 );
    s->S = 0;
}

void incr( cool_sem_t *s, unsigned delta )
{
    assert( s );
    pthread_mutex_lock( &s->guard );
    s->S += delta;
    pthread_cond_broadcast( &s->cond );
    pthread_mutex_unlock( &s->guard );
}

void decr( cool_sem_t *s, unsigned delta )
{
    assert( s );
    pthread_mutex_lock( &s->guard );
    do {
        if (s->S >= delta) {
            s->S -= delta;
            break;
        }
        pthread_cond_wait( &s->cond, &s->guard );
    } while (1);
    pthread_mutex_unlock( &s->guard );
}
Dummy00001