Home | History | Annotate | Download | only in pthreads-win32
      1 /*
      2  * -------------------------------------------------------------
      3  *
      4  * Module: sem_post_multiple.c
      5  *
      6  * Purpose:
      7  *	Semaphores aren't actually part of the PThreads standard.
      8  *	They are defined by the POSIX Standard:
      9  *
     10  *		POSIX 1003.1b-1993	(POSIX.1b)
     11  *
     12  * -------------------------------------------------------------
     13  *
     14  * --------------------------------------------------------------------------
     15  *
     16  *      Pthreads-win32 - POSIX Threads Library for Win32
     17  *      Copyright(C) 1998 John E. Bossom
     18  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
     19  *
     20  *      Contact Email: rpj (at) callisto.canberra.edu.au
     21  *
     22  *      The current list of contributors is contained
     23  *      in the file CONTRIBUTORS included with the source
     24  *      code distribution. The list can also be seen at the
     25  *      following World Wide Web location:
     26  *      http://sources.redhat.com/pthreads-win32/contributors.html
     27  *
     28  *      This library is free software; you can redistribute it and/or
     29  *      modify it under the terms of the GNU Lesser General Public
     30  *      License as published by the Free Software Foundation; either
     31  *      version 2 of the License, or (at your option) any later version.
     32  *
     33  *      This library is distributed in the hope that it will be useful,
     34  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
     35  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     36  *      Lesser General Public License for more details.
     37  *
     38  *      You should have received a copy of the GNU Lesser General Public
     39  *      License along with this library in the file COPYING.LIB;
     40  *      if not, write to the Free Software Foundation, Inc.,
     41  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
     42  */
     43 
     44 #include "pthread.h"
     45 #include "semaphore.h"
     46 #include "implement.h"
     47 
     48 
     49 int
     50 sem_post_multiple (sem_t * sem, int count)
     51      /*
     52       * ------------------------------------------------------
     53       * DOCPUBLIC
     54       *      This function posts multiple wakeups to a semaphore.
     55       *
     56       * PARAMETERS
     57       *      sem
     58       *              pointer to an instance of sem_t
     59       *
     60       *      count
     61       *              counter, must be greater than zero.
     62       *
     63       * DESCRIPTION
     64       *      This function posts multiple wakeups to a semaphore. If there
     65       *      are waiting threads (or processes), n <= count are awakened;
     66       *      the semaphore value is incremented by count - n.
     67       *
     68       * RESULTS
     69       *              0               successfully posted semaphore,
     70       *              -1              failed, error in errno
     71       * ERRNO
     72       *              EINVAL          'sem' is not a valid semaphore
     73       *                              or count is less than or equal to zero.
     74       *              ERANGE          semaphore count is too big
     75       *
     76       * ------------------------------------------------------
     77       */
     78 {
     79   int result = 0;
     80   long waiters;
     81   sem_t s = *sem;
     82 
     83   if (s == NULL || count <= 0)
     84     {
     85       result = EINVAL;
     86     }
     87   else if ((result = pthread_mutex_lock (&s->lock)) == 0)
     88     {
     89       /* See sem_destroy.c
     90        */
     91       if (*sem == NULL)
     92         {
     93           (void) pthread_mutex_unlock (&s->lock);
     94           result = EINVAL;
     95           return -1;
     96         }
     97 
     98       if (s->value <= (SEM_VALUE_MAX - count))
     99 	{
    100 	  waiters = -s->value;
    101 	  s->value += count;
    102 	  if (waiters > 0)
    103 	    {
    104 #if defined(NEED_SEM)
    105 	      if (SetEvent(s->sem))
    106 		{
    107 		  waiters--;
    108 		  s->leftToUnblock += count - 1;
    109 		  if (s->leftToUnblock > waiters)
    110 		    {
    111 		      s->leftToUnblock = waiters;
    112 		    }
    113 		}
    114 #else
    115 	      if (ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0))
    116 		{
    117 		  /* No action */
    118 		}
    119 #endif
    120 	      else
    121 		{
    122 		  s->value -= count;
    123 		  result = EINVAL;
    124 		}
    125 	    }
    126 	}
    127       else
    128 	{
    129 	  result = ERANGE;
    130 	}
    131       (void) pthread_mutex_unlock (&s->lock);
    132     }
    133 
    134   if (result != 0)
    135     {
    136       errno = result;
    137       return -1;
    138     }
    139 
    140   return 0;
    141 
    142 }				/* sem_post_multiple */
    143