linux-kernel.vger.kernel.org archive mirror
 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
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).