public inbox for pthreads-win32@sourceware.org
 help / color / mirror / Atom feed
From: Ross Johnson <rpj@callisto.canberra.edu.au>
To: Shantanu Gogate <sagogate@yahoo.com>, pthreads-win32@sources.redhat.com
Subject: Re: help: weird behaviour of sem_getvalue
Date: Tue, 09 Dec 2003 13:56:00 -0000	[thread overview]
Message-ID: <3FD5D4BD.1070205@callisto.canberra.edu.au> (raw)
In-Reply-To: <20031209063011.31491.qmail@web60710.mail.yahoo.com>

Hi Shantanu,

The sem_getvalue.c file contains the following comments:-

      /*
       * There appears to be NO atomic means of determining the
       * value of the semaphore. Using only ReleaseSemaphore()
       * with either a zero or oversized count parameter has been
       * suggested but this trick doesn't produce consistent results
       * across Windows versions (the technique uses values that are
       * knowingly illegal but hopes to extract the current value
       * anyway - the zero parameter appears to work for Win9x but
       * neither work reliably for WinNT).
       *
       * The intrusive method below will give false results
       * at times but it at least errs on the side of
       * caution. Competing threads might occasionally believe
       * the semaphore has a count of one less than it actually
       * would have and possibly block momentarily unecessarily,
       * but they will never see a higher semaphore value than
       * there should be.
       *
       *
       * Multiple threads calling sem_getvalue() at the same time
       * may not all return the same value (assuming no calls to
       * other semaphore routines). They will always return the
       * correct value or a lesser value. This problem could be fixed
       * with a global or a per-semaphore critical section here.
       *
       * An equally approximate but IMO slightly riskier approach
       * would be to keep a separate per-semaphore counter and
       * decrement/increment it inside of sem_wait() and sem_post()
       * etc using the Interlocked* functions.
       */

The method used performs a WaitForSingleObject() call on the (underlying 
Win32) semaphore with a 0 timeout. If it returns WAIT_TIMEOUT then the 
semaphore was 0, otherwise it immediately releases the sema and gets the 
(value-1) through ReleaseSemaphore().

Wrapping all this in a critical section would add overhead to every 
other sem_*() call.

Regards.
Ross

Shantanu Gogate wrote:

>Hi,
>I am using pthreads-win32 package( was using pthreads-win32-2003-05-10.exe and also tried the
>latest 2003-09-18.exe) but facing a weird problem using sem_getvalue. I have replicated what I am
>trying to do thru this snippet of code which you can test for yourself. Basically there is a
>semaphore which is set to one before the threads are launched. one or more threads continuously
>check the value of this semaphore to see if it has become zero and if it has, then the thread
>exits. Interestingly if you comment out the pthread_exit line then you that the sem_getvalue
>returns the value of semaphore as zero for a brief period of time and then starts reporting it as
>one again !! if i compile the same code on a linux box this anomaly is not observed. Is this is a
>bug in win32-pthreads ? Any help would be appreciated.
>
>Shantanu Gogate.
>
>the code:
>
><<<<
>#include <pthread.h>
>#include <semaphore.h>
>#include <stdio.h>      
>                        
>static sem_t g_sem_ready,g_sem_queue;
>                
>void *consumer(void *args) {
>        int count=0,value;
>        while(1) {
>                sem_getvalue(&g_sem_ready,&value);
>                printf("consumer ready= %d\n",value);
>                if(value <= 0 ) {
>                        sem_getvalue(&g_sem_queue,&value);
>                //      printf("consumer exiting, with %d pending\n", value);
>                        pthread_exit(0);
>                }       
>                else {
>                        sem_wait(&g_sem_queue);
>                        count++;
>                //      printf("consumed %d\n",count);
>                }
>        }               
>}          
>
>void *producer(void *args) {
>        int value,count=0;
>        while(1) {
>                sem_getvalue(&g_sem_ready,&value);
>                printf("producer ready= %d\n",value);
>                if(value <= 0 ) {
>                        printf("producer exiting\n");
>                //      pthread_exit(0);
>                }
>                else {
>                        count++;
>                //      printf("produced %d\n",count);
>                        sem_post(&g_sem_queue);
>                        if(count > 200)
>                                pthread_exit(0);
>                }
>        }
>}
>int main(int argc, char *argv[]) {
>        pthread_t th1, th2;
>        int status;
>
>        sem_init(&g_sem_ready,0,0);
>        sem_init(&g_sem_queue,0,0);
>
>        sem_post(&g_sem_ready);
>        pthread_create(&th1,NULL, consumer, NULL);
>        pthread_create(&th2,NULL, producer, NULL);
>        sleep(10);
>        printf("going down baby\n");
>        sem_wait(&g_sem_ready);
>        pthread_join(th2,(void **)&status);
>        pthread_join(th1,(void **)&status);
>}
>
>
>
>  
>
>
>__________________________________
>Do you Yahoo!?
>Protect your identity with Yahoo! Mail AddressGuard
>http://antispam.yahoo.com/whatsnewfree
>  
>

       reply	other threads:[~2003-12-09 13:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20031209063011.31491.qmail@web60710.mail.yahoo.com>
2003-12-09 13:56 ` Ross Johnson [this message]
2003-12-08  7:59 Shantanu Gogate

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=3FD5D4BD.1070205@callisto.canberra.edu.au \
    --to=rpj@callisto.canberra.edu.au \
    --cc=pthreads-win32@sources.redhat.com \
    --cc=sagogate@yahoo.com \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).