summaryrefslogtreecommitdiff
path: root/semaphore.c
diff options
context:
space:
mode:
authorrpj <rpj>2002-02-08 01:51:17 +0000
committerrpj <rpj>2002-02-08 01:51:17 +0000
commitb29903300adc22ed277bbaa356aca8ed0c245957 (patch)
tree02921a99a145dda1e78a315cc75016443839f2e0 /semaphore.c
parent14118935d2d6863a4746223d8e22c2e58ffebab5 (diff)
Copyright notice updates; module splitting; POSIX version
conditional compilation; refinements; bug fixes. See the ChangeLog.
Diffstat (limited to 'semaphore.c')
-rw-r--r--semaphore.c735
1 files changed, 49 insertions, 686 deletions
diff --git a/semaphore.c b/semaphore.c
index 86222ec..713a904 100644
--- a/semaphore.c
+++ b/semaphore.c
@@ -4,6 +4,10 @@
* Module: semaphore.c
*
* Purpose:
+ * Concatenated version of separate modules to allow
+ * inlining optimisation, which it is assumed can only
+ * be effective within a single module.
+ *
* Semaphores aren't actually part of the PThreads standard.
* They are defined by the POSIX Standard:
*
@@ -11,704 +15,63 @@
*
* -------------------------------------------------------------
*
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright (C) 1998 Ben Elliston and Ross Johnson
- * Copyright (C) 1999,2000,2001 Ross Johnson
- *
- * Contact Email: rpj@ise.canberra.edu.au
- *
- * This 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.
+ * --------------------------------------------------------------------------
*
- * This 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 this library; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2002 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@ise.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-/* ignore warning "unreferenced formal parameter" */
-#ifdef _MSC_VER
-#pragma warning( disable : 4100 )
-#endif
-
#ifndef _UWIN
-# include <process.h>
+# include <process.h>
#endif
#ifndef NEED_FTIME
-#include <sys/timeb.h>
+# include <sys/timeb.h>
#endif
+
+#include <limits.h>
+
#include "pthread.h"
#include "semaphore.h"
#include "implement.h"
-int
-sem_init (sem_t * sem, int pshared, unsigned int value)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function initializes an unnamed semaphore. the
- * initial value of the semaphore is 'value'
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * pshared
- * if zero, this semaphore may only be shared between
- * threads in the same process.
- * if nonzero, the semaphore can be shared between
- * processes
- *
- * value
- * initial value of the semaphore counter
- *
- * DESCRIPTION
- * This function initializes an unnamed semaphore. The
- * initial value of the semaphore is set to 'value'.
- *
- * RESULTS
- * 0 successfully created semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSPC a required resource has been exhausted,
- * ENOSYS semaphores are not supported,
- * EPERM the process lacks appropriate privilege
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
- sem_t s;
-
- if (pshared != 0)
- {
- /*
- * Creating a semaphore that can be shared between
- * processes
- */
- result = EPERM;
-
- }
- else
- {
-
- s = (sem_t) calloc (1, sizeof (*s));
-
- if (NULL == s)
- {
- result = ENOMEM;
- }
-
-#ifdef NEED_SEM
-
- else
- {
- s->value = value;
- s->event = CreateEvent (NULL,
- FALSE, /* manual reset */
- FALSE, /* initial state */
- NULL);
- if (0 == s->event)
- {
- result = ENOSPC;
- }
- else
- {
- if (value != 0)
- {
- SetEvent(s->event);
- }
-
- InitializeCriticalSection(&s->sem_lock_cs);
- }
- }
-
-#else /* NEED_SEM */
-
- s->sem = CreateSemaphore (NULL, /* Always NULL */
- value, /* Initial value */
- 0x7FFFFFFFL, /* Maximum value */
- NULL); /* Name */
-
- if (0 == s->sem)
- {
- result = ENOSPC;
- }
-
-#endif /* NEED_SEM */
-
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
- *sem = s;
-
- return 0;
-
-} /* sem_init */
-
-
-int
-sem_destroy (sem_t * sem)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function destroys an unnamed semaphore.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * DESCRIPTION
- * This function destroys an unnamed semaphore.
- *
- * RESULTS
- * 0 successfully destroyed semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSYS semaphores are not supported,
- * EBUSY threads (or processes) are currently
- * blocked on 'sem'
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
- sem_t s;
-
- if (sem == NULL || *sem == NULL)
- {
- result = EINVAL;
- }
- else
- {
- s = *sem;
- *sem = NULL;
-
-#ifdef NEED_SEM
-
- if (! CloseHandle(s->event))
- {
- *sem = s;
- result = EINVAL;
- }
- else
- {
- DeleteCriticalSection(&s->sem_lock_cs);
- }
-
-#else /* NEED_SEM */
-
- if (! CloseHandle (s->sem))
- {
- *sem = s;
- result = EINVAL;
- }
-
-#endif /* NEED_SEM */
-
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
- free(s);
-
- return 0;
-
-} /* sem_destroy */
-
-
-int
-sem_trywait (sem_t * sem)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function tries to wait on a semaphore.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * DESCRIPTION
- * This function tries to wait on a semaphore. If the
- * semaphore value is greater than zero, it decreases
- * its value by one. If the semaphore value is zero, then
- * this function returns immediately with the error EAGAIN
- *
- * RESULTS
- * 0 successfully decreased semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EAGAIN the semaphore was already locked,
- * EINVAL 'sem' is not a valid semaphore,
- * ENOTSUP sem_trywait is not supported,
- * EINTR the function was interrupted by a signal,
- * EDEADLK a deadlock condition was detected.
- *
- * ------------------------------------------------------
- */
-{
-#ifdef NEED_SEM
-
- /*
- * not yet implemented!
- */
- errno = ENOTSUP;
- return -1;
-
-#else /* NEED_SEM */
-
- int result = 0;
-
- if (sem == NULL || *sem == NULL)
- {
- result = EINVAL;
- }
- else if (WaitForSingleObject ((*sem)->sem, 0) == WAIT_TIMEOUT)
- {
- result = EAGAIN;
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
- return 0;
-
-#endif /* NEED_SEM */
-
-} /* sem_trywait */
-
-
-#ifdef NEED_SEM
-
-void
-ptw32_decrease_semaphore(sem_t * sem)
-{
- register sem_t s = *sem;
-
- EnterCriticalSection(&s->sem_lock_cs);
-
- if (s->value != 0)
- {
- s->value--;
- if (s->value != 0)
- {
- SetEvent(s->event);
- }
- }
- else
- {
- /* this case should not happen! */
- }
-
- LeaveCriticalSection(&s->sem_lock_cs);
-}
-
-BOOL
-ptw32_increase_semaphore(sem_t * sem, unsigned int n)
-{
- BOOL result;
- register sem_t s = *sem;
-
- EnterCriticalSection(&s->sem_lock_cs);
-
- if (s->value + n > s->value)
- {
- s->value += n;
- SetEvent(s->event);
- result = TRUE;
- }
- else
- {
- result = FALSE;
- }
-
- LeaveCriticalSection(&s->sem_lock_cs);
- return result;
-}
-
-#endif /* NEED_SEM */
-
-int
-sem_wait (sem_t * sem)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function waits on a semaphore.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * DESCRIPTION
- * This function waits on a semaphore. If the
- * semaphore value is greater than zero, it decreases
- * its value by one. If the semaphore value is zero, then
- * the calling thread (or process) is blocked until it can
- * successfully decrease the value or until interrupted by
- * a signal.
- *
- * RESULTS
- * 0 successfully decreased semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSYS semaphores are not supported,
- * EINTR the function was interrupted by a signal,
- * EDEADLK a deadlock condition was detected.
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
-
- if (sem == NULL || *sem == NULL)
- {
- result = EINVAL;
- }
- else
- {
-
-#ifdef NEED_SEM
-
- result = pthreadCancelableWait ((*sem)->event);
-
-#else /* NEED_SEM */
-
- result = pthreadCancelableWait ((*sem)->sem);
-
-#endif /* NEED_SEM */
-
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
-#ifdef NEED_SEM
-
- ptw32_decrease_semaphore(sem);
-
-#endif /* NEED_SEM */
-
- return 0;
-
-} /* sem_wait */
-
-
-int
-sem_timedwait (sem_t * sem, const struct timespec * abstime)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function waits on a semaphore possibly until
- * 'abstime' time.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * abstime
- * pointer to an instance of struct timespec
- *
- * DESCRIPTION
- * This function waits on a semaphore. If the
- * semaphore value is greater than zero, it decreases
- * its value by one. If the semaphore value is zero, then
- * the calling thread (or process) is blocked until it can
- * successfully decrease the value or until interrupted by
- * a signal.
- *
- * If 'abstime' is a NULL pointer then this function will
- * block until it can successfully decrease the value or
- * until interrupted by a signal.
- *
- * RESULTS
- * 0 successfully decreased semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSYS semaphores are not supported,
- * EINTR the function was interrupted by a signal,
- * EDEADLK a deadlock condition was detected.
- * ETIMEDOUT abstime elapsed before success.
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
-
-#ifdef NEED_FTIME
-
- struct timespec currSysTime;
-
-#else /* NEED_FTIME */
-
- struct _timeb currSysTime;
-
-#endif /* NEED_FTIME */
-
- const DWORD NANOSEC_PER_MILLISEC = 1000000;
- const DWORD MILLISEC_PER_SEC = 1000;
- DWORD milliseconds;
-
- if (sem == NULL)
- {
- result = EINVAL;
- }
- else
- {
- if (abstime == NULL)
- {
- milliseconds = INFINITE;
- }
- else
- {
- /*
- * Calculate timeout as milliseconds from current system time.
- */
-
- /* get current system time */
-
-#ifdef NEED_FTIME
-
- {
- FILETIME ft;
- SYSTEMTIME st;
-
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
- /*
- * GetSystemTimeAsFileTime(&ft); would be faster,
- * but it does not exist on WinCE
- */
-
- filetime_to_timespec(&ft, &currSysTime);
- }
-
- /*
- * subtract current system time from abstime
- */
- milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC;
- milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
-
-#else /* NEED_FTIME */
- _ftime(&currSysTime);
-
- /*
- * subtract current system time from abstime
- */
- milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC;
- milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) -
- currSysTime.millitm;
-
-#endif /* NEED_FTIME */
-
-
- if (((int) milliseconds) < 0)
- milliseconds = 0;
- }
+#include "semaphore_init.c"
+#include "semaphore_destroy.c"
+#include "semaphore_trywait.c"
+#include "semaphore_wait.c"
+#include "semaphore_timedwait.c"
+#include "semaphore_post.c"
+#include "semaphore_postmultiple.c"
+#include "semaphore_getvalue.c"
+#include "semaphore_open.c"
+#include "semaphore_close.c"
+#include "semaphore_unlink.c"
#ifdef NEED_SEM
-
- result = (pthreadCancelableTimedWait ((*sem)->event, milliseconds));
-
-#else /* NEED_SEM */
-
- result = (pthreadCancelableTimedWait ((*sem)->sem, milliseconds));
-
+#include "semaphore_decrease.c"
+#include "semaphore_increase.c"
#endif
- }
-
- if (result != 0)
- {
-
- errno = result;
- return -1;
-
- }
-
-#ifdef NEED_SEM
-
- ptw32_decrease_semaphore(sem);
-
-#endif /* NEED_SEM */
-
- return 0;
-
-} /* sem_timedwait */
-
-
-int
-sem_post (sem_t * sem)
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function posts a wakeup to a semaphore.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * DESCRIPTION
- * This function posts a wakeup to a semaphore. If there
- * are waiting threads (or processes), one is awakened;
- * otherwise, the semaphore value is incremented by one.
- *
- * RESULTS
- * 0 successfully posted semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore,
- * ENOSYS semaphores are not supported,
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
-
- if (sem == NULL || *sem == NULL)
- {
- result = EINVAL;
- }
-
-#ifdef NEED_SEM
-
- else if (! ptw32_increase_semaphore (sem, 1))
-
-#else /* NEED_SEM */
-
- else if (! ReleaseSemaphore ((*sem)->sem, 1, 0))
-
-#endif /* NEED_SEM */
-
- {
- result = EINVAL;
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
- return 0;
-
-} /* sem_post */
-
-
-int
-sem_post_multiple (sem_t * sem, int count )
- /*
- * ------------------------------------------------------
- * DOCPUBLIC
- * This function posts multiple wakeups to a semaphore.
- *
- * PARAMETERS
- * sem
- * pointer to an instance of sem_t
- *
- * count
- * counter, must be greater than zero.
- *
- * DESCRIPTION
- * This function posts multiple wakeups to a semaphore. If there
- * are waiting threads (or processes), n <= count are awakened;
- * the semaphore value is incremented by count - n.
- *
- * RESULTS
- * 0 successfully posted semaphore,
- * -1 failed, error in errno
- * ERRNO
- * EINVAL 'sem' is not a valid semaphore
- * or count is less than or equal to zero.
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
-
- if (sem == NULL || *sem == NULL || count <= 0)
- {
- result = EINVAL;
- }
-
-#ifdef NEED_SEM
-
- else if (! ptw32_increase_semaphore (sem, count))
-
-#else /* NEED_SEM */
-
- else if (! ReleaseSemaphore ((*sem)->sem, count, 0))
-
-#endif /* NEED_SEM */
-
- {
- result = EINVAL;
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
- }
-
- return 0;
-
-} /* sem_post_multiple */
-
-
-int
-sem_open (const char * name, int oflag, mode_t mode, unsigned int value)
-{
- errno = ENOSYS;
- return -1;
-} /* sem_open */
-
-
-int
-sem_close (sem_t * sem)
-{
- errno = ENOSYS;
- return -1;
-} /* sem_close */
-
-
-int
-sem_unlink (const char * name)
-{
- errno = ENOSYS;
- return -1;
-} /* sem_unlink */
-
-
-int
-sem_getvalue (sem_t * sem, int * sval)
-{
- errno = ENOSYS;
- return -1;
-} /* sem_getvalue */
-