CanobbioE
CanobbioE

Reputation: 232

c - semctl GETVAL can't read the semaphore value

I'm working on a project for my university so I can't use the semaphore.h library.

What I'm trying to do is having a semaphore initialized to a value MAX_ACCESS (default 10) and if that semaphore is available do things.

semId = semget(SEM_KEY, 1, IPC_CREAT | 0666);
if (semId == -1) errExit("semget 1");
if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");

initSem() is defined as follow:

int initSem(int semId, int semNum, int val) {
    union semun arg;

    arg.val = val;
    return semctl(semId, semNum, SETVAL, arg);
}

And as far as I can tell it works as intended. It sets the semaphore value to 10. Just to post everything, semun is:

union semun {
int val;
struct semid_ds* buf;
unsigned short* array;
#if defined(_linux_)
    struct seminfo* _buf;
#endif
};

What causes me problem is the function semAvailable()

int semAvailable(int semId, int semNum) {
union semun arg;

if (semctl(semId, semNum, GETVAL, arg) == -1) errExit("semAvailable: semctl");
return (arg.val > 0); 
}

This function should get the value of the semaphore and return if it's available (greater than zero). Although right after initSem() when I use semAvailable() as a condition, it always return 0.

if (semAvailable(semId, 0)) {
/*do things*/
}

So I tried to print the value of arg.val in semAvailable and it prints zero, then I tried printing it inside initSem, right after calling a semctl(semid, 0, GETVAL, arg) and it printed the correct value, at last I tried calling a semctl() in the main program right after the initSem() and I printed the value of arg.val, and it printed the value of the variable initialized.

if (initSem(semId, 0, MAX_ACCESS) == -1) errExit("initSem");
arg.val = 0;
semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", arg.val); /*This print 0*/

Why the value of the semaphore is not getting stored in arg.val after the semctl? Am I missing something obvious?

Upvotes: 2

Views: 6688

Answers (1)

LPs
LPs

Reputation: 16243

Value of semaphore is the return value of function semctl using GETVAL command.

int semValue = semctl(semId, 0, GETVAL, arg);
printf("Semctl val: %d\n", semValue);

You cannot expect that a function that has not parameter passed by address (pointers) could return a value into a variable passed by value..

HERE you can find a complete example of all commands of semctl function.

Upvotes: 3

Related Questions