0

I need to resolve a synchronization problem using PThreads. At some point in the code, one thread needs to know the number of threads blocked on a semaphore (as defined in sempahore.h).

When I took a look at the man pages of sem_getvalue(sem_t *s, int *sval), it was stated that the returned value sval is 0 in Linux, but may have other semantics according to POSIX, i.e. the absolute value of sval is set to the number of threads blocked on semaphore s.

So I am looking for a Linux compiling option to make possible these alternative semantics.

I tried to simulate the number of threads blocked on a certain semaphore by keeping trace of an integer variable each time a thread executes sem_wait() on that semaphore. But I am wondering about the correctness of this method especially for the race conditions.

Oualid
  • 139
  • 9

2 Answers2

2

The question is inherently racy, and the sem_getvalue function, even if it returns a useful indication of the number of waiters, cannot provide any guarantee that the count is still correct when it returns and you use the resulting value. This sounds like an XY problem, so you should probably explain better what you imagine being able to achieve by having such a count.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Here is the situation: Two sets of threads, let's says A and B are mutually exlusive between each others: if a thread from A succeeds entering its critical section, then any other thread from A can also enters its critical section, but not the threads from B, and vice versa. – Oualid May 12 '19 at 18:40
  • When the last thread from A exits its critical section, this later becomes empty. At this point, threads from B can enter their respective critical sections (obviously, threads from A can also enter but we assume here that priority is given to threads from B). – Oualid May 12 '19 at 18:41
  • In the exit protocol of A threads, there is a call to `sem_post()` on a semaphore on which threads from B are blocked. So, the first thread from B will be released and succeeds entering its critical section. However, in its exit protocol, it only sends one wakeup signal via `sem_post()` to another thread from B. Thus, threads from B will enter their critical sections in turn (which we consider here a performance issue because all the waiting threads from B can enter their critical sections instead of one-by-one thread). – Oualid May 12 '19 at 18:41
  • Therefore, we need here to wakeup all the waiting threads from B instead of only one. That's why we need to be able to run `sem_post()` as many times as the number of waiting threads. – Oualid May 12 '19 at 18:41
2

From the manual

sem_getvalue() places the current value of the semaphore pointed to sem into the integer pointed to by sval.

The semaphore is pointed by the first argument s (sem_t *s). There is a second argument in sem_getvalue (), sval, which is a pointer to an int. The value of semaphore is returned in this integer, a pointer to which is sval.

The function sem_getvalue () retunes 0 on success and -1 on error.

kjohri
  • 1,166
  • 11
  • 10
  • Please continue reading: "If one or more processes or threads are blocked waiting to lock the semaphore with sem_wait(3), POSIX.1 permits two possibilities for the value returned in sval: either 0 is returned; or a negative number whose absolute value is the count of the number of processes and threads currently blocked in sem_wait(3). Linux adopts the former behavior." – Oualid May 12 '19 at 18:13