/* Copyright (C) 2000,02 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Gaƫl Le Mignot The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * POSIX Threads Extension: Semaphores */ #include #include /* Initialize the semaphore and set the initial value - as in LinuxThreads pshared must be zero right now. */ int sem_init (sem_t *sem, int pshared, unsigned int value) { if (pshared) return -1; sem = malloc (sizeof (*sem)); if (sem == NULL) return -1; sem->count = value; pthread_cond_init (&sem->lock, NULL); pthread_mutex_init (&sem->count_lock, NULL); return 0; } /* Destroys the semaphore */ int sem_destroy (sem_t *sem) { pthread_mutex_destroy (&sem->count_lock); pthread_cond_destroy (&sem->lock); free (sem); return 0; } /* Wait until the count is > 0, and then decrease it */ int sem_wait (sem_t *sem) { pthread_mutex_lock (&sem->count_lock); while (1) { if (sem->count) { sem->count--; pthread_mutex_unlock (&sem->count_lock); return 0; } pthread_cond_wait (&sem->lock, &sem->count_lock); } pthread_mutex_unlock (&sem->count_lock); } /* Non-blocking variant of sem_wait. Returns -1 if count == 0. */ int sem_trywait (sem_t *sem) { int res = -1; pthread_mutex_lock (&sem->count_lock); if (sem->count) { res = 0; sem->count--; } pthread_mutex_unlock (&sem->count_lock); return res; } /* Increments the count */ int sem_post (sem_t *sem) { pthread_mutex_lock (&sem->count_lock); sem->count++; pthread_cond_signal (&sem->lock); pthread_mutex_unlock (&sem->count_lock); return 0; } /* Return the value of the semaphore */ int sem_getvalue (sem_t *sem, int *sval) { pthread_mutex_lock (&sem->count_lock); *sval = sem->count; pthread_mutex_unlock (&sem->count_lock); return 0; }