diff options
| author | rpj <rpj> | 2005-04-25 00:48:05 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2005-04-25 00:48:05 +0000 | 
| commit | c2c2749315183f102d8967f37a43394fd39c5abd (patch) | |
| tree | f56b6fe441eb07ca9de08ea6cc120a45437da5f6 | |
| parent | 150a7a6e99d3cf8fd0b6315e7b184b5cce0f4ce4 (diff) | |
Fix NEED_SEM code (WinCE)
| -rw-r--r-- | implement.h | 1308 | ||||
| -rw-r--r-- | private.c | 111 | ||||
| -rw-r--r-- | ptw32_semwait.c | 255 | ||||
| -rw-r--r-- | sem_destroy.c | 300 | ||||
| -rw-r--r-- | sem_getvalue.c | 213 | ||||
| -rw-r--r-- | sem_init.c | 331 | ||||
| -rw-r--r-- | sem_post.c | 227 | ||||
| -rw-r--r-- | sem_post_multiple.c | 243 | ||||
| -rw-r--r-- | sem_trywait.c | 226 | ||||
| -rw-r--r-- | sem_wait.c | 316 | ||||
| -rw-r--r-- | semaphore.c | 142 | 
11 files changed, 1808 insertions, 1864 deletions
diff --git a/implement.h b/implement.h index d2aee1b..919d1cd 100644 --- a/implement.h +++ b/implement.h @@ -1,657 +1,651 @@ -/* - * implement.h - * - * Definitions that don't need to be public. - * - * Keeps all the internals out of pthread.h - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#ifndef _IMPLEMENT_H -#define _IMPLEMENT_H - -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x400 - -#include <windows.h> - -/* - * In case windows.h doesn't define it (e.g. WinCE perhaps) - */ -#ifdef WINCE -typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam); -#endif - -/* - * note: ETIMEDOUT is correctly defined in winsock.h - */ -#include <winsock.h> - -/* - * In case ETIMEDOUT hasn't been defined above somehow. - */ -#ifndef ETIMEDOUT -#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */ -#endif - -#if !defined(malloc) -#include <malloc.h> -#endif - -#if !defined(INT_MAX) -#include <limits.h> -#endif - -/* use local include files during development */ -#include "semaphore.h" -#include "sched.h" - -#if defined(HAVE_C_INLINE) || defined(__cplusplus) -#define INLINE inline -#else -#define INLINE -#endif - -#if defined (__MINGW32__) || (_MSC_VER >= 1300) -#define PTW32_INTERLOCKED_LONG long -#define PTW32_INTERLOCKED_LPLONG long* -#else -#define PTW32_INTERLOCKED_LONG PVOID -#define PTW32_INTERLOCKED_LPLONG PVOID* -#endif - -#if defined(__MINGW32__) -#include <stdint.h> -#else -#define int64_t _int64 -#endif - -typedef enum -{ -  /* -   * This enumeration represents the state of the thread; -   * The thread is still "alive" if the numeric value of the -   * state is greater or equal "PThreadStateRunning". -   */ -  PThreadStateInitial = 0,	/* Thread not running                   */ -  PThreadStateRunning,		/* Thread alive & kicking               */ -  PThreadStateSuspended,	/* Thread alive but suspended           */ -  PThreadStateCancelPending,	/* Thread alive but is                  */ -  /* has cancelation pending.        */ -  PThreadStateCanceling,	/* Thread alive but is                  */ -  /* in the process of terminating        */ -  /* due to a cancellation request        */ -  PThreadStateException,	/* Thread alive but exiting             */ -  /* due to an exception                  */ -  PThreadStateLast -} -PThreadState; - - -typedef struct ptw32_thread_t_ ptw32_thread_t; - -struct ptw32_thread_t_ -{ -#ifdef _UWIN -  DWORD dummy[5]; -#endif -  DWORD thread; -  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */ -  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */ -  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */ -  volatile PThreadState state; -  void *exitStatus; -  void *parms; -  int ptErrno; -  int detachState; -  pthread_mutex_t threadLock;	/* Used for serialised access to public thread state */ -  int sched_priority;		/* As set, not as currently is */ -  pthread_mutex_t cancelLock;	/* Used for async-cancel safety */ -  int cancelState; -  int cancelType; -  HANDLE cancelEvent; -#ifdef __CLEANUP_C -  jmp_buf start_mark; -#endif				/* __CLEANUP_C */ -#if HAVE_SIGSET_T -  sigset_t sigmask; -#endif				/* HAVE_SIGSET_T */ -  int implicit:1; -  void *keys; -}; - - -/*  - * Special value to mark attribute objects as valid. - */ -#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE) - -struct pthread_attr_t_ -{ -  unsigned long valid; -  void *stackaddr; -  size_t stacksize; -  int detachstate; -  struct sched_param param; -  int inheritsched; -  int contentionscope; -#if HAVE_SIGSET_T -  sigset_t sigmask; -#endif				/* HAVE_SIGSET_T */ -}; - - -/* - * ==================== - * ==================== - * Semaphores, Mutexes and Condition Variables - * ==================== - * ==================== - */ - -struct sem_t_ -{ -#ifdef NEED_SEM -  unsigned int value; -  CRITICAL_SECTION sem_lock_cs; -  HANDLE event; -#else				/* NEED_SEM */ -  int value; -  pthread_mutex_t lock; -  HANDLE sem; -#endif				/* NEED_SEM */ -}; - -#define PTW32_OBJECT_AUTO_INIT ((void *) -1) -#define PTW32_OBJECT_INVALID   NULL - -struct pthread_mutex_t_ -{ -  LONG lock_idx;		/* Provides exclusive access to mutex state -				   via the Interlocked* mechanism. -				    0: unlocked/free. -				    1: locked - no other waiters. -				   -1: locked - with possible other waiters. -				*/ -  int recursive_count;		/* Number of unlocks a thread needs to perform -				   before the lock is released (recursive -				   mutexes only). */ -  int kind;			/* Mutex type. */ -  pthread_t ownerThread; -  HANDLE event;			/* Mutex release notification to waiting -				   threads. */ -}; - -struct pthread_mutexattr_t_ -{ -  int pshared; -  int kind; -}; - -/* - * Possible values, other than PTW32_OBJECT_INVALID, - * for the "interlock" element in a spinlock. - * - * In this implementation, when a spinlock is initialised, - * the number of cpus available to the process is checked. - * If there is only one cpu then "interlock" is set equal to - * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex. - * If the number of cpus is greater than 1 then "interlock" - * is set equal to PTW32_SPIN_UNLOCKED and the number is - * stored in u.cpus. This arrangement allows the spinlock - * routines to attempt an InterlockedCompareExchange on "interlock" - * immediately and, if that fails, to try the inferior mutex. - * - * "u.cpus" isn't used for anything yet, but could be used at - * some point to optimise spinlock behaviour. - */ -#define PTW32_SPIN_UNLOCKED    (1) -#define PTW32_SPIN_LOCKED      (2) -#define PTW32_SPIN_USE_MUTEX   (3) - -struct pthread_spinlock_t_ -{ -  long interlock;		/* Locking element for multi-cpus. */ -  union -  { -    int cpus;			/* No. of cpus if multi cpus, or   */ -    pthread_mutex_t mutex;	/* mutex if single cpu.            */ -  } u; -}; - -struct pthread_barrier_t_ -{ -  unsigned int nCurrentBarrierHeight; -  unsigned int nInitialBarrierHeight; -  int iStep; -  int pshared; -  sem_t semBarrierBreeched[2]; -}; - -struct pthread_barrierattr_t_ -{ -  int pshared; -}; - -struct pthread_key_t_ -{ -  DWORD key; -  void (*destructor) (void *); -  pthread_mutex_t threadsLock; -  void *threads; -}; - - -typedef struct ThreadParms ThreadParms; -typedef struct ThreadKeyAssoc ThreadKeyAssoc; - -struct ThreadParms -{ -  pthread_t tid; -  void *(*start) (void *); -  void *arg; -}; - - -struct pthread_cond_t_ -{ -  long nWaitersBlocked;		/* Number of threads blocked            */ -  long nWaitersGone;		/* Number of threads timed out          */ -  long nWaitersToUnblock;	/* Number of threads to unblock         */ -  sem_t semBlockQueue;		/* Queue up threads waiting for the     */ -  /*   condition to become signalled      */ -  sem_t semBlockLock;		/* Semaphore that guards access to      */ -  /* | waiters blocked count/block queue  */ -  /* +-> Mandatory Sync.LEVEL-1           */ -  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */ -  /* | waiters (to)unblock(ed) counts     */ -  /* +-> Optional* Sync.LEVEL-2           */ -  pthread_cond_t next;		/* Doubly linked list                   */ -  pthread_cond_t prev; -}; - - -struct pthread_condattr_t_ -{ -  int pshared; -}; - -#define PTW32_RWLOCK_MAGIC 0xfacade2 - -struct pthread_rwlock_t_ -{ -  pthread_mutex_t mtxExclusiveAccess; -  pthread_mutex_t mtxSharedAccessCompleted; -  pthread_cond_t cndSharedAccessCompleted; -  int nSharedAccessCount; -  int nExclusiveAccessCount; -  int nCompletedSharedAccessCount; -  int nMagic; -}; - -struct pthread_rwlockattr_t_ -{ -  int pshared; -}; - -enum ptw32_once_state { -  PTW32_ONCE_CLEAR     = 0x0, -  PTW32_ONCE_DONE      = 0x1, -  PTW32_ONCE_CANCELLED = 0x2 -}; - -typedef struct { -  pthread_cond_t cond; -  pthread_mutex_t mtx; -} ptw32_once_control_t; - - -struct ThreadKeyAssoc -{ -  /* -   * Purpose: -   *      This structure creates an association between a -   *      thread and a key. -   *      It is used to implement the implicit invocation -   *      of a user defined destroy routine for thread -   *      specific data registered by a user upon exiting a -   *      thread. -   * -   * Attributes: -   *      lock -   *              protects access to the rest of the structure -   * -   *      thread -   *              reference to the thread that owns the association. -   *              As long as this is not NULL, the association remains -   *              referenced by the pthread_t. -   * -   *      key -   *              reference to the key that owns the association. -   *              As long as this is not NULL, the association remains -   *              referenced by the pthread_key_t. -   * -   *      nextKey -   *              The pthread_t->keys attribute is the head of a -   *              chain of associations that runs through the nextKey -   *              link. This chain provides the 1 to many relationship -   *              between a pthread_t and all pthread_key_t on which -   *              it called pthread_setspecific. -   * -   *      nextThread -   *              The pthread_key_t->threads attribute is the head of -   *              a chain of assoctiations that runs through the -   *              nextThreads link. This chain provides the 1 to many -   *              relationship between a pthread_key_t and all the  -   *              PThreads that have called pthread_setspecific for -   *              this pthread_key_t. -   * -   * -   * Notes: -   *      1)      As long as one of the attributes, thread or key, is -   *              not NULL, the association is being referenced; once -   *              both are NULL, the association must be released. -   * -   *      2)      Under WIN32, an association is only created by -   *              pthread_setspecific if the user provided a -   *              destroyRoutine when they created the key. -   * -   * -   */ -  pthread_mutex_t lock; -  pthread_t thread; -  pthread_key_t key; -  ThreadKeyAssoc *nextKey; -  ThreadKeyAssoc *nextThread; -}; - - -#ifdef __CLEANUP_SEH -/* - * -------------------------------------------------------------- - * MAKE_SOFTWARE_EXCEPTION - *      This macro constructs a software exception code following - *      the same format as the standard Win32 error codes as defined - *      in WINERROR.H - *  Values are 32 bit values layed out as follows: - * - *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - *  +---+-+-+-----------------------+-------------------------------+ - *  |Sev|C|R|     Facility          |               Code            | - *  +---+-+-+-----------------------+-------------------------------+ - * - * Severity Values: - */ -#define SE_SUCCESS              0x00 -#define SE_INFORMATION          0x01 -#define SE_WARNING              0x02 -#define SE_ERROR                0x03 - -#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \ -( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \ -            ( 1 << 29 ) |               /* MS=0, User=1         */ \ -            ( 0 << 28 ) |               /* Reserved             */ \ -            ( (_facility) << 16 ) |     /* Facility Code        */ \ -            ( (_exception) <<  0 )      /* Exception Code       */ \ -            ) ) - -/* - * We choose one specific Facility/Error code combination to - * identify our software exceptions vs. WIN32 exceptions. - * We store our actual component and error code within - * the optional information array. - */ -#define EXCEPTION_PTW32_SERVICES        \ -     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \ -                              PTW32_SERVICES_FACILITY, \ -                              PTW32_SERVICES_ERROR ) - -#define PTW32_SERVICES_FACILITY         0xBAD -#define PTW32_SERVICES_ERROR            0xDEED - -#endif /* __CLEANUP_SEH */ - -/* - * Services available through EXCEPTION_PTW32_SERVICES - * and also used [as parameters to ptw32_throw()] as - * generic exception selectors. - */ - -#define PTW32_EPS_EXIT                  (1) -#define PTW32_EPS_CANCEL                (2) - - -/* Useful macros */ -#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a)) -#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a)) - - -/* Declared in global.c */ -extern PTW32_INTERLOCKED_LONG (WINAPI * -			       ptw32_interlocked_compare_exchange) -  (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG); - -/* Declared in pthread_cancel.c */ -extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD); - -/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */ -#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1) - -extern int ptw32_processInitialized; -extern ptw32_thread_t * ptw32_threadReuseTop; -extern ptw32_thread_t * ptw32_threadReuseBottom; -extern pthread_key_t ptw32_selfThreadKey; -extern pthread_key_t ptw32_cleanupKey; -extern pthread_cond_t ptw32_cond_list_head; -extern pthread_cond_t ptw32_cond_list_tail; - -extern int ptw32_mutex_default_kind; - -extern int ptw32_concurrency; - -extern int ptw32_features; - -extern BOOL ptw32_smp_system;  /* True: SMP system, False: Uni-processor system */ - -extern CRITICAL_SECTION ptw32_thread_reuse_lock; -extern CRITICAL_SECTION ptw32_mutex_test_init_lock; -extern CRITICAL_SECTION ptw32_cond_list_lock; -extern CRITICAL_SECTION ptw32_cond_test_init_lock; -extern CRITICAL_SECTION ptw32_rwlock_test_init_lock; -extern CRITICAL_SECTION ptw32_spinlock_test_init_lock; -extern CRITICAL_SECTION ptw32_once_event_lock; - -#ifdef _UWIN -extern int pthread_count; -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif				/* __cplusplus */ - -/* - * ===================== - * ===================== - * Forward Declarations - * ===================== - * ===================== - */ - -  int ptw32_is_attr (const pthread_attr_t * attr); - -  int ptw32_cond_check_need_init (pthread_cond_t * cond); -  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex); -  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock); - -  PTW32_INTERLOCKED_LONG WINAPI -    ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location, -				      PTW32_INTERLOCKED_LONG value, -				      PTW32_INTERLOCKED_LONG comparand); - -  LONG WINAPI -    ptw32_InterlockedExchange (LPLONG location, -			       LONG value); - -  DWORD -    ptw32_RegisterCancelation (PAPCFUNC callback, -			       HANDLE threadH, DWORD callback_arg); - -  int ptw32_processInitialize (void); - -  void ptw32_processTerminate (void); - -  void ptw32_threadDestroy (pthread_t tid); - -  void ptw32_pop_cleanup_all (int execute); - -  pthread_t ptw32_new (void); - -  pthread_t ptw32_threadReusePop (void); - -  void ptw32_threadReusePush (pthread_t thread); - -  int ptw32_getprocessors (int *count); - -  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority); - -  void ptw32_rwlock_cancelwrwait (void *arg); - -#if ! defined (__MINGW32__) || defined (__MSVCRT__) -  unsigned __stdcall -#else -  void -#endif -    ptw32_threadStart (void *vthreadParms); - -  void ptw32_callUserDestroyRoutines (pthread_t thread); - -  int ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP, -			   pthread_t thread, pthread_key_t key); - -  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc); - -  int ptw32_semwait (sem_t * sem); - -#ifdef NEED_SEM -  void ptw32_decrease_semaphore (sem_t * sem); -  BOOL ptw32_increase_semaphore (sem_t * sem, unsigned int n); -#endif				/* NEED_SEM */ - -#ifdef NEED_FTIME -  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft); -  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts); -#endif - -/* Declared in misc.c */ -#ifdef NEED_CALLOC -#define calloc(n, s) ptw32_calloc(n, s) -  void *ptw32_calloc (size_t n, size_t s); -#endif - -/* Declared in private.c */ -  void ptw32_throw (DWORD exception); - -#ifdef __cplusplus -} -#endif				/* __cplusplus */ - - -#ifdef _UWIN_ -#   ifdef       _MT -#       ifdef __cplusplus -extern "C" -{ -#       endif -  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *), -					      unsigned, void *); -  _CRTIMP void __cdecl _endthread (void); -  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned, -						unsigned (__stdcall *) (void *), -						void *, unsigned, unsigned *); -  _CRTIMP void __cdecl _endthreadex (unsigned); -#       ifdef __cplusplus -} -#       endif -#   endif -#else -#   include <process.h> -#endif - - -/* - * Defaults. Could be overridden when building the inlined version of the dll. - * See ptw32_InterlockedCompareExchange.c - */ -#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE -#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange -#endif - -#ifndef PTW32_INTERLOCKED_EXCHANGE -#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange -#endif - - -/* - * Check for old and new versions of cygwin. See the FAQ file: - * - * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32? - * - * Patch by Anders Norlander <anorland@hem2.passagen.se> - */ -#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD) - -/*  - * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE - * in order to avoid warnings because of return type - */ - -#define _beginthreadex(security, \ -                       stack_size, \ -                       start_proc, \ -                       arg, \ -                       flags, \ -                       pid) \ -        CreateThread(security, \ -                     stack_size, \ -                     (LPTHREAD_START_ROUTINE) start_proc, \ -                     arg, \ -                     flags, \ -                     pid) - -#define _endthreadex ExitThread - -#endif				/* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */ - - -#endif				/* _IMPLEMENT_H */ +/*
 + * implement.h
 + *
 + * Definitions that don't need to be public.
 + *
 + * Keeps all the internals out of pthread.h
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#ifndef _IMPLEMENT_H
 +#define _IMPLEMENT_H
 +
 +#ifdef _WIN32_WINNT
 +#undef _WIN32_WINNT
 +#endif
 +#define _WIN32_WINNT 0x400
 +
 +#include <windows.h>
 +
 +/*
 + * In case windows.h doesn't define it (e.g. WinCE perhaps)
 + */
 +#ifdef WINCE
 +typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
 +#endif
 +
 +/*
 + * note: ETIMEDOUT is correctly defined in winsock.h
 + */
 +#include <winsock.h>
 +
 +/*
 + * In case ETIMEDOUT hasn't been defined above somehow.
 + */
 +#ifndef ETIMEDOUT
 +#  define ETIMEDOUT 10060	/* This is the value in winsock.h. */
 +#endif
 +
 +#if !defined(malloc)
 +#include <malloc.h>
 +#endif
 +
 +#if !defined(INT_MAX)
 +#include <limits.h>
 +#endif
 +
 +/* use local include files during development */
 +#include "semaphore.h"
 +#include "sched.h"
 +
 +#if defined(HAVE_C_INLINE) || defined(__cplusplus)
 +#define INLINE inline
 +#else
 +#define INLINE
 +#endif
 +
 +#if defined (__MINGW32__) || (_MSC_VER >= 1300)
 +#define PTW32_INTERLOCKED_LONG long
 +#define PTW32_INTERLOCKED_LPLONG long*
 +#else
 +#define PTW32_INTERLOCKED_LONG PVOID
 +#define PTW32_INTERLOCKED_LPLONG PVOID*
 +#endif
 +
 +#if defined(__MINGW32__)
 +#include <stdint.h>
 +#else
 +#define int64_t _int64
 +#endif
 +
 +typedef enum
 +{
 +  /*
 +   * This enumeration represents the state of the thread;
 +   * The thread is still "alive" if the numeric value of the
 +   * state is greater or equal "PThreadStateRunning".
 +   */
 +  PThreadStateInitial = 0,	/* Thread not running                   */
 +  PThreadStateRunning,		/* Thread alive & kicking               */
 +  PThreadStateSuspended,	/* Thread alive but suspended           */
 +  PThreadStateCancelPending,	/* Thread alive but is                  */
 +  /* has cancelation pending.        */
 +  PThreadStateCanceling,	/* Thread alive but is                  */
 +  /* in the process of terminating        */
 +  /* due to a cancellation request        */
 +  PThreadStateException,	/* Thread alive but exiting             */
 +  /* due to an exception                  */
 +  PThreadStateLast
 +}
 +PThreadState;
 +
 +
 +typedef struct ptw32_thread_t_ ptw32_thread_t;
 +
 +struct ptw32_thread_t_
 +{
 +#ifdef _UWIN
 +  DWORD dummy[5];
 +#endif
 +  DWORD thread;
 +  HANDLE threadH;		/* Win32 thread handle - POSIX thread is invalid if threadH == 0 */
 +  pthread_t ptHandle;		/* This thread's permanent pthread_t handle */
 +  ptw32_thread_t * prevReuse;	/* Links threads on reuse stack */
 +  volatile PThreadState state;
 +  void *exitStatus;
 +  void *parms;
 +  int ptErrno;
 +  int detachState;
 +  pthread_mutex_t threadLock;	/* Used for serialised access to public thread state */
 +  int sched_priority;		/* As set, not as currently is */
 +  pthread_mutex_t cancelLock;	/* Used for async-cancel safety */
 +  int cancelState;
 +  int cancelType;
 +  HANDLE cancelEvent;
 +#ifdef __CLEANUP_C
 +  jmp_buf start_mark;
 +#endif				/* __CLEANUP_C */
 +#if HAVE_SIGSET_T
 +  sigset_t sigmask;
 +#endif				/* HAVE_SIGSET_T */
 +  int implicit:1;
 +  void *keys;
 +};
 +
 +
 +/* 
 + * Special value to mark attribute objects as valid.
 + */
 +#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
 +
 +struct pthread_attr_t_
 +{
 +  unsigned long valid;
 +  void *stackaddr;
 +  size_t stacksize;
 +  int detachstate;
 +  struct sched_param param;
 +  int inheritsched;
 +  int contentionscope;
 +#if HAVE_SIGSET_T
 +  sigset_t sigmask;
 +#endif				/* HAVE_SIGSET_T */
 +};
 +
 +
 +/*
 + * ====================
 + * ====================
 + * Semaphores, Mutexes and Condition Variables
 + * ====================
 + * ====================
 + */
 +
 +struct sem_t_
 +{
 +  int value;
 +  pthread_mutex_t lock;
 +  HANDLE sem;
 +#ifdef NEED_SEM
 +  int leftToUnblock;
 +#endif
 +};
 +
 +#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
 +#define PTW32_OBJECT_INVALID   NULL
 +
 +struct pthread_mutex_t_
 +{
 +  LONG lock_idx;		/* Provides exclusive access to mutex state
 +				   via the Interlocked* mechanism.
 +				    0: unlocked/free.
 +				    1: locked - no other waiters.
 +				   -1: locked - with possible other waiters.
 +				*/
 +  int recursive_count;		/* Number of unlocks a thread needs to perform
 +				   before the lock is released (recursive
 +				   mutexes only). */
 +  int kind;			/* Mutex type. */
 +  pthread_t ownerThread;
 +  HANDLE event;			/* Mutex release notification to waiting
 +				   threads. */
 +};
 +
 +struct pthread_mutexattr_t_
 +{
 +  int pshared;
 +  int kind;
 +};
 +
 +/*
 + * Possible values, other than PTW32_OBJECT_INVALID,
 + * for the "interlock" element in a spinlock.
 + *
 + * In this implementation, when a spinlock is initialised,
 + * the number of cpus available to the process is checked.
 + * If there is only one cpu then "interlock" is set equal to
 + * PTW32_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
 + * If the number of cpus is greater than 1 then "interlock"
 + * is set equal to PTW32_SPIN_UNLOCKED and the number is
 + * stored in u.cpus. This arrangement allows the spinlock
 + * routines to attempt an InterlockedCompareExchange on "interlock"
 + * immediately and, if that fails, to try the inferior mutex.
 + *
 + * "u.cpus" isn't used for anything yet, but could be used at
 + * some point to optimise spinlock behaviour.
 + */
 +#define PTW32_SPIN_UNLOCKED    (1)
 +#define PTW32_SPIN_LOCKED      (2)
 +#define PTW32_SPIN_USE_MUTEX   (3)
 +
 +struct pthread_spinlock_t_
 +{
 +  long interlock;		/* Locking element for multi-cpus. */
 +  union
 +  {
 +    int cpus;			/* No. of cpus if multi cpus, or   */
 +    pthread_mutex_t mutex;	/* mutex if single cpu.            */
 +  } u;
 +};
 +
 +struct pthread_barrier_t_
 +{
 +  unsigned int nCurrentBarrierHeight;
 +  unsigned int nInitialBarrierHeight;
 +  int iStep;
 +  int pshared;
 +  sem_t semBarrierBreeched[2];
 +};
 +
 +struct pthread_barrierattr_t_
 +{
 +  int pshared;
 +};
 +
 +struct pthread_key_t_
 +{
 +  DWORD key;
 +  void (*destructor) (void *);
 +  pthread_mutex_t threadsLock;
 +  void *threads;
 +};
 +
 +
 +typedef struct ThreadParms ThreadParms;
 +typedef struct ThreadKeyAssoc ThreadKeyAssoc;
 +
 +struct ThreadParms
 +{
 +  pthread_t tid;
 +  void *(*start) (void *);
 +  void *arg;
 +};
 +
 +
 +struct pthread_cond_t_
 +{
 +  long nWaitersBlocked;		/* Number of threads blocked            */
 +  long nWaitersGone;		/* Number of threads timed out          */
 +  long nWaitersToUnblock;	/* Number of threads to unblock         */
 +  sem_t semBlockQueue;		/* Queue up threads waiting for the     */
 +  /*   condition to become signalled      */
 +  sem_t semBlockLock;		/* Semaphore that guards access to      */
 +  /* | waiters blocked count/block queue  */
 +  /* +-> Mandatory Sync.LEVEL-1           */
 +  pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */
 +  /* | waiters (to)unblock(ed) counts     */
 +  /* +-> Optional* Sync.LEVEL-2           */
 +  pthread_cond_t next;		/* Doubly linked list                   */
 +  pthread_cond_t prev;
 +};
 +
 +
 +struct pthread_condattr_t_
 +{
 +  int pshared;
 +};
 +
 +#define PTW32_RWLOCK_MAGIC 0xfacade2
 +
 +struct pthread_rwlock_t_
 +{
 +  pthread_mutex_t mtxExclusiveAccess;
 +  pthread_mutex_t mtxSharedAccessCompleted;
 +  pthread_cond_t cndSharedAccessCompleted;
 +  int nSharedAccessCount;
 +  int nExclusiveAccessCount;
 +  int nCompletedSharedAccessCount;
 +  int nMagic;
 +};
 +
 +struct pthread_rwlockattr_t_
 +{
 +  int pshared;
 +};
 +
 +enum ptw32_once_state {
 +  PTW32_ONCE_CLEAR     = 0x0,
 +  PTW32_ONCE_DONE      = 0x1,
 +  PTW32_ONCE_CANCELLED = 0x2
 +};
 +
 +typedef struct {
 +  pthread_cond_t cond;
 +  pthread_mutex_t mtx;
 +} ptw32_once_control_t;
 +
 +
 +struct ThreadKeyAssoc
 +{
 +  /*
 +   * Purpose:
 +   *      This structure creates an association between a
 +   *      thread and a key.
 +   *      It is used to implement the implicit invocation
 +   *      of a user defined destroy routine for thread
 +   *      specific data registered by a user upon exiting a
 +   *      thread.
 +   *
 +   * Attributes:
 +   *      lock
 +   *              protects access to the rest of the structure
 +   *
 +   *      thread
 +   *              reference to the thread that owns the association.
 +   *              As long as this is not NULL, the association remains
 +   *              referenced by the pthread_t.
 +   *
 +   *      key
 +   *              reference to the key that owns the association.
 +   *              As long as this is not NULL, the association remains
 +   *              referenced by the pthread_key_t.
 +   *
 +   *      nextKey
 +   *              The pthread_t->keys attribute is the head of a
 +   *              chain of associations that runs through the nextKey
 +   *              link. This chain provides the 1 to many relationship
 +   *              between a pthread_t and all pthread_key_t on which
 +   *              it called pthread_setspecific.
 +   *
 +   *      nextThread
 +   *              The pthread_key_t->threads attribute is the head of
 +   *              a chain of assoctiations that runs through the
 +   *              nextThreads link. This chain provides the 1 to many
 +   *              relationship between a pthread_key_t and all the 
 +   *              PThreads that have called pthread_setspecific for
 +   *              this pthread_key_t.
 +   *
 +   *
 +   * Notes:
 +   *      1)      As long as one of the attributes, thread or key, is
 +   *              not NULL, the association is being referenced; once
 +   *              both are NULL, the association must be released.
 +   *
 +   *      2)      Under WIN32, an association is only created by
 +   *              pthread_setspecific if the user provided a
 +   *              destroyRoutine when they created the key.
 +   *
 +   *
 +   */
 +  pthread_mutex_t lock;
 +  pthread_t thread;
 +  pthread_key_t key;
 +  ThreadKeyAssoc *nextKey;
 +  ThreadKeyAssoc *nextThread;
 +};
 +
 +
 +#ifdef __CLEANUP_SEH
 +/*
 + * --------------------------------------------------------------
 + * MAKE_SOFTWARE_EXCEPTION
 + *      This macro constructs a software exception code following
 + *      the same format as the standard Win32 error codes as defined
 + *      in WINERROR.H
 + *  Values are 32 bit values layed out as follows:
 + *
 + *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 + *  +---+-+-+-----------------------+-------------------------------+
 + *  |Sev|C|R|     Facility          |               Code            |
 + *  +---+-+-+-----------------------+-------------------------------+
 + *
 + * Severity Values:
 + */
 +#define SE_SUCCESS              0x00
 +#define SE_INFORMATION          0x01
 +#define SE_WARNING              0x02
 +#define SE_ERROR                0x03
 +
 +#define MAKE_SOFTWARE_EXCEPTION( _severity, _facility, _exception ) \
 +( (DWORD) ( ( (_severity) << 30 ) |     /* Severity code        */ \
 +            ( 1 << 29 ) |               /* MS=0, User=1         */ \
 +            ( 0 << 28 ) |               /* Reserved             */ \
 +            ( (_facility) << 16 ) |     /* Facility Code        */ \
 +            ( (_exception) <<  0 )      /* Exception Code       */ \
 +            ) )
 +
 +/*
 + * We choose one specific Facility/Error code combination to
 + * identify our software exceptions vs. WIN32 exceptions.
 + * We store our actual component and error code within
 + * the optional information array.
 + */
 +#define EXCEPTION_PTW32_SERVICES        \
 +     MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
 +                              PTW32_SERVICES_FACILITY, \
 +                              PTW32_SERVICES_ERROR )
 +
 +#define PTW32_SERVICES_FACILITY         0xBAD
 +#define PTW32_SERVICES_ERROR            0xDEED
 +
 +#endif /* __CLEANUP_SEH */
 +
 +/*
 + * Services available through EXCEPTION_PTW32_SERVICES
 + * and also used [as parameters to ptw32_throw()] as
 + * generic exception selectors.
 + */
 +
 +#define PTW32_EPS_EXIT                  (1)
 +#define PTW32_EPS_CANCEL                (2)
 +
 +
 +/* Useful macros */
 +#define PTW32_MAX(a,b)  ((a)<(b)?(b):(a))
 +#define PTW32_MIN(a,b)  ((a)>(b)?(b):(a))
 +
 +
 +/* Declared in global.c */
 +extern PTW32_INTERLOCKED_LONG (WINAPI *
 +			       ptw32_interlocked_compare_exchange)
 +  (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG);
 +
 +/* Declared in pthread_cancel.c */
 +extern DWORD (*ptw32_register_cancelation) (PAPCFUNC, HANDLE, DWORD);
 +
 +/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
 +#define PTW32_THREAD_REUSE_EMPTY ((ptw32_thread_t *) 1)
 +
 +extern int ptw32_processInitialized;
 +extern ptw32_thread_t * ptw32_threadReuseTop;
 +extern ptw32_thread_t * ptw32_threadReuseBottom;
 +extern pthread_key_t ptw32_selfThreadKey;
 +extern pthread_key_t ptw32_cleanupKey;
 +extern pthread_cond_t ptw32_cond_list_head;
 +extern pthread_cond_t ptw32_cond_list_tail;
 +
 +extern int ptw32_mutex_default_kind;
 +
 +extern int ptw32_concurrency;
 +
 +extern int ptw32_features;
 +
 +extern BOOL ptw32_smp_system;  /* True: SMP system, False: Uni-processor system */
 +
 +extern CRITICAL_SECTION ptw32_thread_reuse_lock;
 +extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
 +extern CRITICAL_SECTION ptw32_cond_list_lock;
 +extern CRITICAL_SECTION ptw32_cond_test_init_lock;
 +extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
 +extern CRITICAL_SECTION ptw32_spinlock_test_init_lock;
 +extern CRITICAL_SECTION ptw32_once_event_lock;
 +
 +#ifdef _UWIN
 +extern int pthread_count;
 +#endif
 +
 +#ifdef __cplusplus
 +extern "C"
 +{
 +#endif				/* __cplusplus */
 +
 +/*
 + * =====================
 + * =====================
 + * Forward Declarations
 + * =====================
 + * =====================
 + */
 +
 +  int ptw32_is_attr (const pthread_attr_t * attr);
 +
 +  int ptw32_cond_check_need_init (pthread_cond_t * cond);
 +  int ptw32_mutex_check_need_init (pthread_mutex_t * mutex);
 +  int ptw32_rwlock_check_need_init (pthread_rwlock_t * rwlock);
 +
 +  PTW32_INTERLOCKED_LONG WINAPI
 +    ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location,
 +				      PTW32_INTERLOCKED_LONG value,
 +				      PTW32_INTERLOCKED_LONG comparand);
 +
 +  LONG WINAPI
 +    ptw32_InterlockedExchange (LPLONG location,
 +			       LONG value);
 +
 +  DWORD
 +    ptw32_RegisterCancelation (PAPCFUNC callback,
 +			       HANDLE threadH, DWORD callback_arg);
 +
 +  int ptw32_processInitialize (void);
 +
 +  void ptw32_processTerminate (void);
 +
 +  void ptw32_threadDestroy (pthread_t tid);
 +
 +  void ptw32_pop_cleanup_all (int execute);
 +
 +  pthread_t ptw32_new (void);
 +
 +  pthread_t ptw32_threadReusePop (void);
 +
 +  void ptw32_threadReusePush (pthread_t thread);
 +
 +  int ptw32_getprocessors (int *count);
 +
 +  int ptw32_setthreadpriority (pthread_t thread, int policy, int priority);
 +
 +  void ptw32_rwlock_cancelwrwait (void *arg);
 +
 +#if ! defined (__MINGW32__) || defined (__MSVCRT__)
 +  unsigned __stdcall
 +#else
 +  void
 +#endif
 +    ptw32_threadStart (void *vthreadParms);
 +
 +  void ptw32_callUserDestroyRoutines (pthread_t thread);
 +
 +  int ptw32_tkAssocCreate (ThreadKeyAssoc ** assocP,
 +			   pthread_t thread, pthread_key_t key);
 +
 +  void ptw32_tkAssocDestroy (ThreadKeyAssoc * assoc);
 +
 +  int ptw32_semwait (sem_t * sem);
 +
 +  DWORD ptw32_relmillisecs (const struct timespec * abstime);
 +
 +#ifdef NEED_FTIME
 +  void ptw32_timespec_to_filetime (const struct timespec *ts, FILETIME * ft);
 +  void ptw32_filetime_to_timespec (const FILETIME * ft, struct timespec *ts);
 +#endif
 +
 +/* Declared in misc.c */
 +#ifdef NEED_CALLOC
 +#define calloc(n, s) ptw32_calloc(n, s)
 +  void *ptw32_calloc (size_t n, size_t s);
 +#endif
 +
 +/* Declared in private.c */
 +  void ptw32_throw (DWORD exception);
 +
 +#ifdef __cplusplus
 +}
 +#endif				/* __cplusplus */
 +
 +
 +#ifdef _UWIN_
 +#   ifdef       _MT
 +#       ifdef __cplusplus
 +extern "C"
 +{
 +#       endif
 +  _CRTIMP unsigned long __cdecl _beginthread (void (__cdecl *) (void *),
 +					      unsigned, void *);
 +  _CRTIMP void __cdecl _endthread (void);
 +  _CRTIMP unsigned long __cdecl _beginthreadex (void *, unsigned,
 +						unsigned (__stdcall *) (void *),
 +						void *, unsigned, unsigned *);
 +  _CRTIMP void __cdecl _endthreadex (unsigned);
 +#       ifdef __cplusplus
 +}
 +#       endif
 +#   endif
 +#else
 +#   include <process.h>
 +#endif
 +
 +
 +/*
 + * Defaults. Could be overridden when building the inlined version of the dll.
 + * See ptw32_InterlockedCompareExchange.c
 + */
 +#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE
 +#define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange
 +#endif
 +
 +#ifndef PTW32_INTERLOCKED_EXCHANGE
 +#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange
 +#endif
 +
 +
 +/*
 + * Check for old and new versions of cygwin. See the FAQ file:
 + *
 + * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32?
 + *
 + * Patch by Anders Norlander <anorland@hem2.passagen.se>
 + */
 +#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
 +
 +/* 
 + * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
 + * in order to avoid warnings because of return type
 + */
 +
 +#define _beginthreadex(security, \
 +                       stack_size, \
 +                       start_proc, \
 +                       arg, \
 +                       flags, \
 +                       pid) \
 +        CreateThread(security, \
 +                     stack_size, \
 +                     (LPTHREAD_START_ROUTINE) start_proc, \
 +                     arg, \
 +                     flags, \
 +                     pid)
 +
 +#define _endthreadex ExitThread
 +
 +#endif				/* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */
 +
 +
 +#endif				/* _IMPLEMENT_H */
 @@ -1,55 +1,56 @@ -/* - * private.c - * - * Description: - * This translation unit implements routines which are private to - * the implementation and may be used throughout it. - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "implement.h" - -/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */ -#include "ptw32_InterlockedCompareExchange.c" - -#include "ptw32_is_attr.c" -#include "ptw32_processInitialize.c" -#include "ptw32_processTerminate.c" -#include "ptw32_threadStart.c" -#include "ptw32_threadDestroy.c" -#include "ptw32_tkAssocCreate.c" -#include "ptw32_tkAssocDestroy.c" -#include "ptw32_callUserDestroyRoutines.c" -#include "ptw32_semwait.c" -#include "ptw32_timespec.c" -#include "ptw32_throw.c" -#include "ptw32_getprocessors.c" +/*
 + * private.c
 + *
 + * Description:
 + * This translation unit implements routines which are private to
 + * the implementation and may be used throughout it.
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "implement.h"
 +
 +/* Must be first to define HAVE_INLINABLE_INTERLOCKED_CMPXCHG */
 +#include "ptw32_InterlockedCompareExchange.c"
 +
 +#include "ptw32_is_attr.c"
 +#include "ptw32_processInitialize.c"
 +#include "ptw32_processTerminate.c"
 +#include "ptw32_threadStart.c"
 +#include "ptw32_threadDestroy.c"
 +#include "ptw32_tkAssocCreate.c"
 +#include "ptw32_tkAssocDestroy.c"
 +#include "ptw32_callUserDestroyRoutines.c"
 +#include "ptw32_semwait.c"
 +#include "ptw32_timespec.c"
 +#include "ptw32_relmillisecs.c"
 +#include "ptw32_throw.c"
 +#include "ptw32_getprocessors.c"
 diff --git a/ptw32_semwait.c b/ptw32_semwait.c index 98b665d..209c8a6 100644 --- a/ptw32_semwait.c +++ b/ptw32_semwait.c @@ -1,137 +1,118 @@ -/* - * ptw32_semwait.c - * - * Description: - * This translation unit implements mutual exclusion (mutex) primitives. - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#ifndef _UWIN -//#   include <process.h> -#endif -#include "pthread.h" -#include "implement.h" - - -int -ptw32_semwait (sem_t * sem) -     /* -      * ------------------------------------------------------ -      * DESCRIPTION -      *      This function waits on a POSIX 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. -      * -      *      Unlike sem_wait(), this routine is non-cancelable. -      * -      * 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; -  DWORD status; -  sem_t s = *sem; - -  if (s == NULL) -    { -      result = EINVAL; -    } -  else -    { - -#ifdef NEED_SEM - -      status = WaitForSingleObject (s->event, INFINITE); - -#else /* NEED_SEM */ - -      if ((result = pthread_mutex_lock (&s->lock)) == 0) -        { -          int v = --s->value; - -          (void) pthread_mutex_unlock (&s->lock); - -          if (v < 0) -            { -              /* Must wait */ -              status = WaitForSingleObject (s->sem, INFINITE); -            } -          else -	    { -	      return 0; -	    } -        } -      else -        { -          return result; -        } - -#endif - -      if (status == WAIT_OBJECT_0) -	{ - -#ifdef NEED_SEM - -	  ptw32_decrease_semaphore (sem); - -#endif /* NEED_SEM */ - -	  return 0; -	} -      else -	{ -#ifndef NEED_SEM -	  (void) InterlockedIncrement((LPLONG) &s->value); -#endif -	  result = EINVAL; -	} -    } - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  return 0; - -}				/* ptw32_semwait */ +/*
 + * ptw32_semwait.c
 + *
 + * Description:
 + * This translation unit implements mutual exclusion (mutex) primitives.
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#ifndef _UWIN
 +//#   include <process.h>
 +#endif
 +#include "pthread.h"
 +#include "implement.h"
 +
 +
 +int
 +ptw32_semwait (sem_t * sem)
 +     /*
 +      * ------------------------------------------------------
 +      * DESCRIPTION
 +      *      This function waits on a POSIX 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.
 +      *
 +      *      Unlike sem_wait(), this routine is non-cancelable.
 +      *
 +      * 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;
 +  sem_t s = *sem;
 +
 +  if (s == NULL)
 +    {
 +      result = EINVAL;
 +    }
 +  else
 +    {
 +      if ((result = pthread_mutex_lock (&s->lock)) == 0)
 +        {
 +          int v = --s->value;
 +
 +          (void) pthread_mutex_unlock (&s->lock);
 +
 +          if (v < 0)
 +            {
 +              /* Must wait */
 +              if (WaitForSingleObject (s->sem, INFINITE) == WAIT_OBJECT_0)
 +		{
 +#ifdef NEED_SEM
 +		  if (pthread_mutex_lock (&s->lock) == 0)
 +		    {
 +		      if (s->leftToUnblock > 0)
 +			{
 +			  --s->leftToUnblock;
 +			  SetEvent(s->sem);
 +			}
 +		      (void) pthread_mutex_unlock (&s->lock);
 +		    }
 +#endif
 +		  return 0;
 +		}
 +            }
 +          else
 +	    {
 +	      return 0;
 +	    }
 +        }
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  return 0;
 +
 +}				/* ptw32_semwait */
 diff --git a/sem_destroy.c b/sem_destroy.c index c6cbc22..c260d41 100644 --- a/sem_destroy.c +++ b/sem_destroy.c @@ -1,154 +1,146 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_destroy.c - * - * Purpose: - *	Semaphores aren't actually part of the PThreads standard. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -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 = NULL; - -  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 ((result = pthread_mutex_trylock (&s->lock)) == 0) -        { -          if (s->value >= 0) -            { -              (void) pthread_mutex_unlock (&s->lock); - -              if (!CloseHandle (s->sem)) -	        { -	          *sem = s; -	          result = EINVAL; -	        } -              else if ((result = pthread_mutex_destroy (&s->lock)) != 0) -                { -                  s->sem = CreateSemaphore (NULL,      /* Always NULL */ -                                            (long) 0,  /* Force threads to wait */ -                                            (long) _POSIX_SEM_VALUE_MAX,       /* Maximum value */ -                                            NULL);     /* Name */ -                  if (s->sem == 0) -                    { -                      /* We just have to pretend that we've destroyed the semaphore -                       * even though we're leaving a mutex around. -                       */ -                      result = 0; -                    } -                  else -                    { -                      *sem = s; -                      if (result != EBUSY) -                        result = EINVAL; -                    } -                } -            } -          else -            { -              (void) pthread_mutex_unlock (&s->lock); -              result = EBUSY; -            } -        } - -#endif /* NEED_SEM */ - -    } - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  free (s); - -  return 0; - -}				/* sem_destroy */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_destroy.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of the PThreads standard.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +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 = NULL;
 +
 +  if (sem == NULL || *sem == NULL)
 +    {
 +      result = EINVAL;
 +    }
 +  else
 +    {
 +      s = *sem;
 +      *sem = NULL;
 +
 +      if ((result = pthread_mutex_trylock (&s->lock)) == 0)
 +        {
 +          if (s->value >= 0)
 +            {
 +              (void) pthread_mutex_unlock (&s->lock);
 +
 +              if (!CloseHandle (s->sem))
 +	        {
 +	          *sem = s;
 +	          result = EINVAL;
 +	        }
 +              else if ((result = pthread_mutex_destroy (&s->lock)) != 0)
 +                {
 +
 +#ifdef NEED_SEM
 +		  s->sem = CreateEvent (NULL,
 +					PTW32_FALSE,    /* manual reset is false */
 +					PTW32_FALSE,    /* initial state is unset */
 +					NULL);
 +#else
 +                  s->sem = CreateSemaphore (NULL,      /* Always NULL */
 +                                            (long) 0,  /* Force threads to wait */
 +                                            (long) _POSIX_SEM_VALUE_MAX,       /* Maximum value */
 +                                            NULL);     /* Name */
 +#endif
 +
 +                  if (s->sem == 0)
 +                    {
 +                      /* We just have to pretend that we've destroyed the semaphore
 +                       * even though we're leaving a mutex around.
 +                       */
 +                      result = 0;
 +                    }
 +                  else
 +                    {
 +                      *sem = s;
 +                      if (result != EBUSY)
 +                        result = EINVAL;
 +                    }
 +                }
 +            }
 +          else
 +            {
 +              (void) pthread_mutex_unlock (&s->lock);
 +              result = EBUSY;
 +            }
 +        }
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  free (s);
 +
 +  return 0;
 +
 +}				/* sem_destroy */
 diff --git a/sem_getvalue.c b/sem_getvalue.c index 693ed57..f1a7e4b 100644 --- a/sem_getvalue.c +++ b/sem_getvalue.c @@ -1,112 +1,101 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_getvalue.c - * - * Purpose: - *	Semaphores aren't actually part of PThreads. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1-2001 - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -int -sem_getvalue (sem_t * sem, int *sval) -     /* -      * ------------------------------------------------------ -      * DOCPUBLIC -      *      This function stores the current count value of the -      *      semaphore. -      * RESULTS -      * -      * Return value -      * -      *       0                  sval has been set. -      *      -1                  failed, error in errno -      * -      *  in global errno -      * -      *      EINVAL              'sem' is not a valid semaphore, -      *      ENOSYS              this function is not supported, -      * -      * -      * PARAMETERS -      * -      *      sem                 pointer to an instance of sem_t -      * -      *      sval                pointer to int. -      * -      * DESCRIPTION -      *      This function stores the current count value of the semaphore -      *      pointed to by sem in the int pointed to by sval. -      */ -{ -  if (sem == NULL || *sem == NULL || sval == NULL) -    { -      errno = EINVAL; -      return -1; -    } -  else -    { -      long value; -      register sem_t s = *sem; -      int result = 0; - -#ifdef NEED_SEM - -      EnterCriticalSection (&s->sem_lock_cs); -      value = s->value; -      LeaveCriticalSection (&s->sem_lock_cs); -      *sval = value; - -#else - -      if ((result = pthread_mutex_lock(&s->lock)) == 0) -        { -          value = s->value; -          (void) pthread_mutex_unlock(&s->lock); -          *sval = value; -        } - -#endif - -      return result; -    } - -}				/* sem_getvalue */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_getvalue.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of PThreads.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1-2001
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +int
 +sem_getvalue (sem_t * sem, int *sval)
 +     /*
 +      * ------------------------------------------------------
 +      * DOCPUBLIC
 +      *      This function stores the current count value of the
 +      *      semaphore.
 +      * RESULTS
 +      *
 +      * Return value
 +      *
 +      *       0                  sval has been set.
 +      *      -1                  failed, error in errno
 +      *
 +      *  in global errno
 +      *
 +      *      EINVAL              'sem' is not a valid semaphore,
 +      *      ENOSYS              this function is not supported,
 +      *
 +      *
 +      * PARAMETERS
 +      *
 +      *      sem                 pointer to an instance of sem_t
 +      *
 +      *      sval                pointer to int.
 +      *
 +      * DESCRIPTION
 +      *      This function stores the current count value of the semaphore
 +      *      pointed to by sem in the int pointed to by sval.
 +      */
 +{
 +  if (sem == NULL || *sem == NULL || sval == NULL)
 +    {
 +      errno = EINVAL;
 +      return -1;
 +    }
 +  else
 +    {
 +      long value;
 +      register sem_t s = *sem;
 +      int result = 0;
 +
 +      if ((result = pthread_mutex_lock(&s->lock)) == 0)
 +        {
 +          value = s->value;
 +          (void) pthread_mutex_unlock(&s->lock);
 +          *sval = value;
 +        }
 +
 +      return result;
 +    }
 +
 +}				/* sem_getvalue */
 @@ -1,167 +1,164 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_init.c - * - * Purpose: - *	Semaphores aren't actually part of PThreads. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1-2001 - * - * ------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - -int -sem_init (sem_t * sem, int pshared, unsigned int value) -     /* -      * ------------------------------------------------------ -      * DOCPUBLIC -      *      This function initializes a 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 a 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, -      *              ENOMEM          out of memory, -      *              ENOSPC          a required resource has been exhausted, -      *              ENOSYS          semaphores are not supported, -      *              EPERM           the process lacks appropriate privilege -      * -      * ------------------------------------------------------ -      */ -{ -  int result = 0; -  sem_t s = NULL; - -  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; -	} -      else -	{ - -#ifdef NEED_SEM - -	  s->value = value; -	  s->event = CreateEvent (NULL, PTW32_FALSE,	/* manual reset */ -				  PTW32_FALSE,	/* initial state */ -				  NULL); - -	  if (0 == s->event) -	    { -	      free (s); -	      result = ENOSPC; -	    } -	  else -	    { -	      if (value != 0) -		{ -		  SetEvent (s->event); -		} - -	      InitializeCriticalSection (&s->sem_lock_cs); -	    } - -#else /* NEED_SEM */ - -	  s->value = value; -	  if (pthread_mutex_init(&s->lock, NULL) == 0) -	    { -	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */ -					     (long) 0,	/* Force threads to wait */ -					     (long) _POSIX_SEM_VALUE_MAX,	/* Maximum value */ -					     NULL)) == 0)	/* Name */ -		{ -		  (void) pthread_mutex_destroy(&s->lock); -		  result = ENOSPC; -		} -	    } -	  else -	    { -	      result = ENOSPC; -	    } - -	  if (result != 0) -	    { -	      free(s); -	    } - -#endif /* NEED_SEM */ - -	} -    } - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  *sem = s; - -  return 0; - -}				/* sem_init */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_init.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of PThreads.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1-2001
 + *
 + * -------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +int
 +sem_init (sem_t * sem, int pshared, unsigned int value)
 +     /*
 +      * ------------------------------------------------------
 +      * DOCPUBLIC
 +      *      This function initializes a 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 a 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,
 +      *              ENOMEM          out of memory,
 +      *              ENOSPC          a required resource has been exhausted,
 +      *              ENOSYS          semaphores are not supported,
 +      *              EPERM           the process lacks appropriate privilege
 +      *
 +      * ------------------------------------------------------
 +      */
 +{
 +  int result = 0;
 +  sem_t s = NULL;
 +
 +  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;
 +	}
 +      else
 +	{
 +
 +	  s->value = value;
 +	  if (pthread_mutex_init(&s->lock, NULL) == 0)
 +	    {
 +
 +#ifdef NEED_SEM
 +
 +	  s->sem = CreateEvent (NULL,
 +				PTW32_FALSE,	/* auto (not manual) reset */
 +				PTW32_FALSE,	/* initial state is unset */
 +				NULL);
 +
 +	  if (0 == s->sem)
 +	    {
 +	      free (s);
 +	      (void) pthread_mutex_destroy(&s->lock);
 +	      result = ENOSPC;
 +	    }
 +	  else
 +	    {
 +	      s->leftToUnblock = 0;
 +	    }
 +
 +#else /* NEED_SEM */
 +
 +	      if ((s->sem = CreateSemaphore (NULL,	/* Always NULL */
 +					     (long) 0,	/* Force threads to wait */
 +					     (long) _POSIX_SEM_VALUE_MAX,	/* Maximum value */
 +					     NULL)) == 0)	/* Name */
 +		{
 +		  (void) pthread_mutex_destroy(&s->lock);
 +		  result = ENOSPC;
 +		}
 +
 +#endif /* NEED_SEM */
 +
 +	    }
 +	  else
 +	    {
 +	      result = ENOSPC;
 +	    }
 +
 +	  if (result != 0)
 +	    {
 +	      free(s);
 +	    }
 +	}
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  *sem = s;
 +
 +  return 0;
 +
 +}				/* sem_init */
 @@ -1,115 +1,112 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_post.c - * - * Purpose: - *	Semaphores aren't actually part of the PThreads standard. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -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; -#ifndef NEED_SEM -  sem_t s = *sem; -#endif - -  if (s == NULL) -    { -      result = EINVAL; -    } - -#ifdef NEED_SEM - -  else if (!ptw32_increase_semaphore (sem, 1)) -    { -      result = EINVAL; -    } - -#else /* NEED_SEM */ - -  else if ((result = pthread_mutex_lock (&s->lock)) == 0) -    { -      if (++s->value <= 0 -	  && !ReleaseSemaphore (s->sem, 1, NULL)) -	{ -	  result = EINVAL; -	} -       -      (void) pthread_mutex_unlock (&s->lock); -    } - -#endif /* NEED_SEM */ - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  return 0; - -}				/* sem_post */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_post.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of the PThreads standard.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +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;
 +  sem_t s = *sem;
 +
 +  if (s == NULL)
 +    {
 +      result = EINVAL;
 +    }
 +  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 +    {
 +#ifdef NEED_SEM
 +
 +      if (++s->value <= 0)
 +	{
 +	  if (!SetEvent(s->sem))
 +	    {
 +	      result = EINVAL;
 +	    }
 +	}
 +#else
 +      if (++s->value <= 0
 +	  && !ReleaseSemaphore (s->sem, 1, NULL))
 +	{
 +	  result = EINVAL;
 +	}
 +#endif /* NEED_SEM */
 +      
 +      (void) pthread_mutex_unlock (&s->lock);
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  return 0;
 +
 +}				/* sem_post */
 diff --git a/sem_post_multiple.c b/sem_post_multiple.c index 64c120b..6c582e2 100644 --- a/sem_post_multiple.c +++ b/sem_post_multiple.c @@ -1,122 +1,121 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_post_multiple.c - * - * Purpose: - *	Semaphores aren't actually part of the PThreads standard. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -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; -#ifndef NEED_SEM -  long waiters; -  sem_t s = *sem; -#endif - -  if (s == NULL || count <= 0) -    { -      result = EINVAL; -    } - -#ifdef NEED_SEM - -  else if (!ptw32_increase_semaphore (sem, count)) -    { -      result = EINVAL; -    } - -#else /* NEED_SEM */ - -  else if ((result = pthread_mutex_lock (&s->lock)) == 0) -    { -      waiters = -s->value; -      s->value += count; -      if (waiters > 0) -        { -          if (!ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0)) -            { -              result = EINVAL; -            } -        } -      (void) pthread_mutex_unlock (&s->lock); -    } - -#endif /* NEED_SEM */ - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  return 0; - -}				/* sem_post_multiple */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_post_multiple.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of the PThreads standard.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +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;
 +  long waiters;
 +  sem_t s = *sem;
 +
 +  if (s == NULL || count <= 0)
 +    {
 +      result = EINVAL;
 +    }
 +  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 +    {
 +      waiters = -s->value;
 +      s->value += count;
 +      if (waiters > 0)
 +        {
 +#ifdef NEED_SEM
 +	  if (SetEvent(s->sem))
 +	    {
 +	      waiters--;
 +	      s->leftToUnblock += count - 1;
 +	      if (s->leftToUnblock > waiters)
 +		{
 +		  s->leftToUnblock = waiters;
 +		}
 +	    }
 +	  else
 +#else
 +          if (!ReleaseSemaphore (s->sem,  (waiters<=count)?waiters:count, 0))
 +#endif
 +            {
 +              result = EINVAL;
 +            }
 +        }
 +      (void) pthread_mutex_unlock (&s->lock);
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  return 0;
 +
 +}				/* sem_post_multiple */
 diff --git a/sem_trywait.c b/sem_trywait.c index 640d190..2116222 100644 --- a/sem_trywait.c +++ b/sem_trywait.c @@ -1,118 +1,108 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_trywait.c - * - * Purpose: - *	Semaphores aren't actually part of the PThreads standard. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - -#include <stdio.h> - -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; -  sem_t s = *sem; - -  if (s == NULL) -    { -      result = EINVAL; -    } -  else if ((result = pthread_mutex_lock (&s->lock)) == 0) -    { -      if (--s->value < 0) -	{ -	  s->value++; -	  result = EAGAIN; -	} - -      (void) pthread_mutex_unlock (&s->lock); -    } - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -  return 0; - -#endif /* NEED_SEM */ - -}				/* sem_trywait */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_trywait.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of the PThreads standard.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +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.
 +      *
 +      * ------------------------------------------------------
 +      */
 +{
 +  int result = 0;
 +  sem_t s = *sem;
 +
 +  if (s == NULL)
 +    {
 +      result = EINVAL;
 +    }
 +  else if ((result = pthread_mutex_lock (&s->lock)) == 0)
 +    {
 +      if (s->value > 0)
 +	{
 +	  s->value--;
 +	}
 +      else
 +	{
 +	  result = EAGAIN;
 +	}
 +
 +      (void) pthread_mutex_unlock (&s->lock);
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  return 0;
 +
 +}				/* sem_trywait */
 @@ -1,154 +1,162 @@ -/* - * ------------------------------------------------------------- - * - * Module: sem_wait.c - * - * Purpose: - *	Semaphores aren't actually part of the PThreads standard. - *	They are defined by the POSIX Standard: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -static void PTW32_CDECL -ptw32_sem_wait_cleanup(void * sem) -{ -  sem_t s = (sem_t) sem; - -  if (pthread_mutex_lock (&s->lock) == 0) -    { -      ++s->value; -      /* Don't release the W32 sema, it should always == 0. */ -      (void) pthread_mutex_unlock (&s->lock); -    } -} - -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; -  sem_t s = *sem; - -  if (s == NULL) -    { -      result = EINVAL; -    } -  else -    { - -#ifdef NEED_SEM - -      result = pthreadCancelableWait (s->event); - -#else /* NEED_SEM */ - -      /* -       * sem_wait is a cancelation point and it's easy to test before -       * modifying the sem value -       */ -      pthread_testcancel(); - -      if ((result = pthread_mutex_lock (&s->lock)) == 0) -	{ -	  int v = --s->value; - -	  (void) pthread_mutex_unlock (&s->lock); - -	  if (v < 0) -	    { -	      /* Must wait */ -#ifdef _MSC_VER -#pragma inline_depth(0) -#endif -	      pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s); -	      result = pthreadCancelableWait (s->sem); -	      pthread_cleanup_pop(result != 0); -#ifdef _MSC_VER -#pragma inline_depth() -#endif -	    } -	} - -#endif /* NEED_SEM */ - -    } - -  if (result != 0) -    { -      errno = result; -      return -1; -    } - -#ifdef NEED_SEM - -  ptw32_decrease_semaphore (sem); - -#endif /* NEED_SEM */ - -  return 0; - -}				/* sem_wait */ +/*
 + * -------------------------------------------------------------
 + *
 + * Module: sem_wait.c
 + *
 + * Purpose:
 + *	Semaphores aren't actually part of the PThreads standard.
 + *	They are defined by the POSIX Standard:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +static void PTW32_CDECL
 +ptw32_sem_wait_cleanup(void * sem)
 +{
 +  sem_t s = (sem_t) sem;
 +
 +  if (pthread_mutex_lock (&s->lock) == 0)
 +    {
 +      ++s->value;
 +#ifdef NEED_SEM
 +          
 +      if (s->value > 0)
 +	{
 +	  s->leftToUnblock = 0;
 +	}   
 +#else 
 +      /*
 +       * Don't release the W32 sema, it doesn't need adjustment
 +       * because it doesn't record the number of waiters.
 +       */
 +#endif /* NEED_SEM */
 +      (void) pthread_mutex_unlock (&s->lock);
 +    }
 +}
 +
 +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;
 +  sem_t s = *sem;
 +
 +  if (s == NULL)
 +    {
 +      result = EINVAL;
 +    }
 +  else
 +    {
 +
 +      /* Faster to test before adjusting the count */
 +      pthread_testcancel();
 +
 +      if ((result = pthread_mutex_lock (&s->lock)) == 0)
 +	{
 +	  int v = --s->value;
 +
 +	  (void) pthread_mutex_unlock (&s->lock);
 +
 +	  if (v < 0)
 +	    {
 +#ifdef _MSC_VER
 +#pragma inline_depth(0)
 +#endif
 +	      /* Must wait */
 +	      pthread_cleanup_push(ptw32_sem_wait_cleanup, (void *) s);
 +	      result = pthreadCancelableWait (s->sem);
 +	      pthread_cleanup_pop(result);
 +#ifdef _MSC_VER
 +#pragma inline_depth()
 +#endif
 +	    }
 +#ifdef NEED_SEM
 +
 +	  if (!result && pthread_mutex_lock (&s->lock) == 0)
 +	    {
 +	      if (s->leftToUnblock > 0)
 +		{
 +		  --s->leftToUnblock;
 +		  SetEvent(s->sem);
 +		}
 +	      (void) pthread_mutex_unlock (&s->lock);
 +	    }
 +
 +#endif /* NEED_SEM */
 +
 +	}
 +
 +    }
 +
 +  if (result != 0)
 +    {
 +      errno = result;
 +      return -1;
 +    }
 +
 +  return 0;
 +
 +}				/* sem_wait */
 diff --git a/semaphore.c b/semaphore.c index de0340f..0a5131f 100644 --- a/semaphore.c +++ b/semaphore.c @@ -1,73 +1,69 @@ -/* - * ------------------------------------------------------------- - * - * 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: - * - *		POSIX 1003.1b-1993	(POSIX.1b) - * - * ------------------------------------------------------------- - * - * -------------------------------------------------------------------------- - * - *      Pthreads-win32 - POSIX Threads Library for Win32 - *      Copyright(C) 1998 John E. Bossom - *      Copyright(C) 1999,2005 Pthreads-win32 contributors - *  - *      Contact Email: rpj@callisto.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 - */ - -#ifndef NEED_FTIME -#  include <sys/timeb.h> -#endif - -#include <limits.h> - -#include "pthread.h" -#include "semaphore.h" -#include "implement.h" - - -#include "sem_init.c" -#include "sem_destroy.c" -#include "sem_trywait.c" -#include "sem_wait.c" -#include "sem_timedwait.c" -#include "sem_post.c" -#include "sem_post_multiple.c" -#include "sem_getvalue.c" -#include "sem_open.c" -#include "sem_close.c" -#include "sem_unlink.c" -#ifdef NEED_SEM -#include "ptw32_decrease_semaphore.c" -#include "ptw32_increase_semaphore.c" -#endif +/*
 + * -------------------------------------------------------------
 + *
 + * 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:
 + *
 + *		POSIX 1003.1b-1993	(POSIX.1b)
 + *
 + * -------------------------------------------------------------
 + *
 + * --------------------------------------------------------------------------
 + *
 + *      Pthreads-win32 - POSIX Threads Library for Win32
 + *      Copyright(C) 1998 John E. Bossom
 + *      Copyright(C) 1999,2005 Pthreads-win32 contributors
 + * 
 + *      Contact Email: rpj@callisto.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
 + */
 +
 +#ifndef NEED_FTIME
 +#  include <sys/timeb.h>
 +#endif
 +
 +#include <limits.h>
 +
 +#include "pthread.h"
 +#include "semaphore.h"
 +#include "implement.h"
 +
 +
 +#include "sem_init.c"
 +#include "sem_destroy.c"
 +#include "sem_trywait.c"
 +#include "sem_wait.c"
 +#include "sem_timedwait.c"
 +#include "sem_post.c"
 +#include "sem_post_multiple.c"
 +#include "sem_getvalue.c"
 +#include "sem_open.c"
 +#include "sem_close.c"
 +#include "sem_unlink.c"
  | 
