All of lore.kernel.org
 help / color / mirror / Atom feed
From: John M Collins <jmc@xisl.com>
To: linux-kernel@vger.kernel.org
Subject: Semaphores and threads anomaly and bug?
Date: Tue, 04 Nov 2003 16:45:21 +0000	[thread overview]
Message-ID: <3FA7D7A1.2030307@xisl.com> (raw)

(Please CC me in any reply as I'm not subscribed)

I know this isn't defined anywhere but the seems to be an ambiguity and 
discrepancy between versions of Unix and Linux over threads and semaphores.

Do the "SEM_UNDO"s get applied when a thread terminates or when the 
"whole thing" terminates?

I tried the following C++ program

#include <iostream>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>

using    namespace  std;

int    semchan;

union semun {
      int val;                  /* value for SETVAL */
      struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
      unsigned short *array;    /* array for GETALL, SETALL */
                                /* Linux specific part: */
      struct seminfo *__buf;    /* buffer for IPC_INFO */
};

int    getsemv()
{
    return  semctl(semchan, 0, GETVAL, 0);
}

void    *tfunc(void *arg)
{
    cout << "About to set sema4 current=" << getsemv() << endl;
    sembuf  sv;
    sv.sem_op = 77;
    sv.sem_flg = SEM_UNDO;
    sv.sem_num = 0;
    semop(semchan, &sv, 1);
    cout << "Done,sem now=" << getsemv() << endl;
    return  0;
}

int    main()
{
    semchan = semget(999, 1, 0666 | IPC_CREAT);
    semun  z;
    z.val = 1;
    semctl(semchan, 0, SETVAL, z);
    cout << "Created sema4 initial value=" << getsemv() << endl;
    cout << "Creating thread" << endl;
    pthread_t  th;
    pthread_create(&th, 0, tfunc, 0);
    pthread_join(th, 0);
    cout << "After thread value=" << getsemv() << endl;
    return  0;
}

Trying it on Linux (2.4.21 kernel) it says:

Created sema4 initial value=1
Creating thread
About to set sema4 current=1
Done,sem now=78
After thread value=1

Implying that the thread exit applies the SEM_UNDOs whereas trying on 
Solaris 2.9 and HP/UX 11 I get

Created sema4 initial value=1
Creating thread
About to set sema4 current=1
Done,sem now=78
After thread value=78

After which the value is 1, implying that the SEM_UNDOs get applied on 
process exit.

There is another anomaly which applies to SEM_UNDO in that when a 
process exits, every semaphore in the set has its "sempid" set to the 
process id of the exiting process, even ones that the process left 
alone. I think that in ipc/sem.c line 1062 the line should be made 
conditional on "u->semadj[i]" being non-zero.

I know all this isn't defined anywhere but I hit on this trying to write 
an application involving a server process using threads and a 
semaphore-protected shared memory segment accessed by client processes. 
The semaphore might be set to "locked" by a different thread from the 
one that "unlocks" it (I'm using "Mutexes" inside the server process). I 
know you probably don't want SEM_UNDO in a fully-debugged server 
process, only in the clients but it's all a question of getting the said 
server process into the glorious state of being "fully-debugged" or 
somewhere near there.

There is a potential problem here in that the code in ipc/sem.c doesn't 
allow the adjustment to yield a negative value but what if it starts at 
zero, thread A increments it, thread B decrements it back to zero (both 
with SEM_UNDO) and thread A exits first? Thread A's undo won't work and 
then thread B's undo will increment it again leaving it in an incorrect 
state which is different from thread B exiting first.

-- 
John Collins Xi Software Ltd www.xisl.com



             reply	other threads:[~2003-11-04 16:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-04 16:45 John M Collins [this message]
2003-11-04 17:29 ` Semaphores and threads anomaly and bug? Linus Torvalds
2003-11-04 18:09   ` John M Collins
  -- strict thread matches above, loose matches on Subject: below --
2003-11-04 17:59 Manfred Spraul

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3FA7D7A1.2030307@xisl.com \
    --to=jmc@xisl.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.