Semop: Invalid argument - c

I have this code that basically makes a P on the semaphore with number sem. The semaphore is in a pool. The problem is that sometimes I get Invalid argument and I can't figure out why.
bool sem_p(key_t key, int sem){
int semid = semget(key, sem, 0666);
struct sembuf sb = {sem, -1, 0};
if(semop(semid, &sb, 1) == -1){
perror("sem p");
printf("sem %d\n", sem);
return FALSE;
}
return TRUE;
}
When that function gets called, it prints
sem p: Invalid argument

Check if
int semid = semget(key, sem, 0666);
returns success or failure. As #VladLazaranenko mentioned there could be a lot of possible errors. Check every single return code for every single function you call (if they return a value) - for production systems.

Related

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?
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.

Using sys/sem.h in C, How to get the semaphore value?

I am using sys/sem.h in C to implement semaphore, but now I am stuck with a strange problem so I want to check the semaphore value. I write such a function:
int sem_set(int semid, int sem_val)
{
union semun sem_union;
sem_union.val = sem_val;
if (semctl(semid, 0 , SETVAL , sem_union) == -1) return 0;
return 1;
}
int sem_get(int semid)
{
union semun sem_union;
return semctl(semid, 0 , GETVAL , sem_union);
}
int sem_wait(int semid)
{
struct sembuf sb;
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = SEM_UNDO;
if (semop(semid, &sb, 1) == -1)
{
printf("error/n");
return 0;
}
return 1;
}
But the function is going wrong when I have such two processes running:
initially sem.val is set to 0;
process1:
...
printf("%d", sem_get(sem_id));
sem_wait(semid);
...
process2:
...
printf("%d", sem_get(sem_id));
sem_wait(semid);
...
Assuming process 1 run first and executed sem_wait(semid), I guess process 2 should output -1 but actually 0 is printed. How could this happen? is my function wrong? Or the semaphore implementation in sem.h is different to what I learned in the class?
there is already the function sem_getvalue()
here is an example
int sem_getvalue(sem_t *sem, int *valp);
strongly suggest performing a bit of googling for 'how to use semaphores in C'
one such web page is:
http://www.csc.villanova.edu/~mdamian/threads/posixsem.html#getvalue
here is an excerpt from the man page for sem_getvalue
sem_getvalue() places the current value of the semaphore pointed to sem
into the integer pointed to by sval.

Semaphore in C for shared memory can't initialize

The command semctl always returns -1 (returns "Fail2" in console). What am I doing wrong?
union semun{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
} forsem;
forsem.val = 0;
int sem;
if((sem= semget(key, 1, 0666 | IPC_CREAT) == -1)) {
fprintf(stderr, "Fail1");
}
if (semctl(sem, 0, SETVAL, forsem) == -1) {
fprintf(stderr, "Fail2");
}
Errno writes Invalid argument
You make a simple mistake: in
if((sem= semget(key, 1, 0666 | IPC_CREAT) == -1)) {
fprintf(stderr, "Fail1");
}
You should write
if((sem= semget(key, 1, 0666 | IPC_CREAT)) == -1) {
fprintf(stderr, "Fail1");
}
Notice the brackets?
By the way, the error is EIDRM because sem is 0 in your code, not Invalid Argument.
Thanks for your answer! It does not matter. The only thing it's not giving error is for semctl with the second argument 0 (number of the semaphore in the semaphore set), if I put 1 or 30 there, it returns -1.

Semaphore counter: program hangs

I want create a semaphore counter, with this code:
union semun arg_assistant;
int max_ass = atoi(argv[1]);
printf("Num massimo di assistant %d\n", max_ass);
fflush(stdout);
if ((sem_a = semget(IPC_PRIVATE, 1, 0600)) == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
arg_assistant.val = max_ass;
if (semctl(sem_a, 0, SETALL, arg_assistant) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
When I executed my program, I have no errors but it hangs and it don't create this sem. Any suggestion about what could be the problem? Have I make some mistake with falgs?
Thaks
From documentation
SETALL
Set semval for all semaphores of the set using arg.array,
For SETALL you need array of values
unsigned short int sem_array[1] ;
sem_array[0] = max_ass;
arg_assistant.array = sem_array;
if (semctl(sem_a, 0, SETALL, arg_assistant) == -1) {
perror("semctl");
exit(EXIT_FAILURE);
}
sem_array[1] becaues you create only one semaphore.

Locking semaphores in C problem sys/sem

EDIT: This peace of code is pretty fine (so take it as example of semaphores ;). Bug in my program was in another place - found by my friend.
I have problem with my functions. Sometimes two processes enter into critical section. I can't find problem in this after I spent 10 hours by debugging. On what I should aim? Is there any possibility to have bud in this piece of code?
// lock semaphore
static int P(int sem_id)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = 0;
if (semop(sem_id, &sem_b, 1) == -1) {
// error
return(0);
}
return(1);
}
// unlock semaphore
static int V(int sem_id)
{
struct sembuf sem_b[1];
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = 0;
if (semop(sem_id, &sem_b, 1) == -1) {
// error
return(0);
}
return(1);
}
static int set_semval(int sem_id) {
// set to 1 (opened semaphore)
if (semctl(sem_id, 0, SETVAL, 1) == -1) {
// error
return(0);
}
return(1);
}
static int get_val(int sem_id)
{
union semun sem_union;
//sem_union.val = 0; ?
return semctl(sem_id, 0, GETVAL, sem_union);
}
The action loop:
// semaphores init
int mutex;
if ((mutex=semget(key+2, 1, 0666))>=0) {
// semaphore exists
fprintf(stderr,"semaphore exists for key %d\n", key+2);
}
if ((mutex=semget(key+2, 1, 0666 | IPC_CREAT)) == -1) {
exit(EXIT_FAILURE);
}
if (!set_semval(mutex)) {
exit(EXIT_FAILURE);
}
fork() // some times with good conditionals
// in some children
while(1) {
P(mutex);
assert(get_val(mutex)==0); // always ok
action(); // sometimes made by two processes at same time - fault
V(mutex);
}
Pls, feel free to edit my question.
Many thanks
in your 'action loop' what do you do if your semaphore does not exist?
currently your 3rd parameter to semget is 0666 or the PERMISSION_RW constant. You may want to use:
shmget(key, 1, PERMISSION_RW | IPC_CREAT);
this way if your semaphore does not exist it will create one.
So bug was at another place...

Resources