summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS1
-rw-r--r--ChangeLog7
-rw-r--r--README.WinCE15
-rw-r--r--WinCE-PORT208
-rw-r--r--condvar.c16
-rw-r--r--config.h22
-rw-r--r--config.h.in19
-rw-r--r--errno.c4
-rw-r--r--implement.h19
-rw-r--r--misc.c20
-rw-r--r--mutex.c5
-rw-r--r--need_errno.h132
-rw-r--r--private.c111
-rw-r--r--pthread.def4
-rw-r--r--pthread.h37
-rw-r--r--sched.h4
-rw-r--r--semaphore.c126
-rw-r--r--semaphore.h13
-rw-r--r--signal.c3
-rw-r--r--tsd.c5
20 files changed, 736 insertions, 35 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index be8aaec..c9818bd 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -15,5 +15,6 @@ Mumit Khan khan@xraylith.wisc.edu
Aurelio Medina aureliom@crt.com
Milan Gardian mg@tatramed.sk
Graham Dumpleton Graham.Dumpleton@ra.pad.otc.telstra.com.au
+Tristan Savatier tristan@mpegtv.com
Erik Hensema erik.hensema@group2000.nl
Rich Peters rpeters@micro-magic.com
diff --git a/ChangeLog b/ChangeLog
index 5e20044..dbed53e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+1999-11-05 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * general: Patched for portability to WinCE. The details are
+ described in the file WinCE-PORT. Follow the instructions
+ in README.WinCE to make the appropriate changes in config.h.
+ - Tristan Savatier <tristan@mpegtv.com>
+
1999-10-30 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* create.c (pthread_create): Explicitly initialise thread state to
diff --git a/README.WinCE b/README.WinCE
new file mode 100644
index 0000000..2d4212e
--- /dev/null
+++ b/README.WinCE
@@ -0,0 +1,15 @@
+WinCE port
+----------
+(See the file WinCE-PORT for a detailed explanation.)
+
+In config.h:
+
+you need to define the following which are undefined by default:
+
+#define NEED_DUPLICATEHANDLE
+#define NEED_CREATETHREAD
+#define NEED_ERRNO
+#define NEED_CALLOC
+#define NEED_FTIME
+#define NEED_SEM
+
diff --git a/WinCE-PORT b/WinCE-PORT
new file mode 100644
index 0000000..9de284d
--- /dev/null
+++ b/WinCE-PORT
@@ -0,0 +1,208 @@
+Some interesting news:
+
+I have been able to port pthread-win32 to Windows-CE,
+which uses a subset of the WIN32 API.
+
+Since we intend to keep using pthread-win32 for our
+Commercial WinCE developments, I would be very interested
+if WinCE support could be added to the main source tree
+of pthread-win32. Also, I would like to be credited
+for this port :-)
+
+Now, here is the story...
+
+The port was performed and tested on a Casio "Cassiopeia"
+PalmSize PC, which runs a MIP processor. The OS in the
+Casio is WinCE version 2.11, but I used VC++ 6.0 with
+the WinCE SDK for version 2.01.
+
+I used pthread-win32 to port a heavily multithreaded
+commercial application (real-time MPEG video player)
+from Linux to WinCE. I consider the changes that
+I have done to be quite well tested.
+
+Overall the modifications that we had to do are minor.
+
+The WinCE port were based on pthread-win32-snap-1999-05-30,
+but I am certain that they can be integrated very easiely
+to more recent versions of the source.
+
+I have attached the modified source code:
+pthread-win32-snap-1999-05-30-WinCE.
+
+All the changes do not affect the code compiled on non-WinCE
+environment, provided that the macros used for WinCE compilation
+are not used, of course!
+
+Overall description of the WinCE port:
+-------------------------------------
+
+Most of the changes had to be made in areas where
+pthread-win32 was relying on some standard-C librairies
+(e.g. _ftime, calloc, errno), which are not available
+on WinCE. We have changed the code to use native Win32
+API instead (or in some cases we made wrappers).
+
+The Win32 Semaphores are not available,
+so we had to re-implement Semaphores using mutexes
+and events.
+
+Limitations / known problems of the WinCE port:
+----------------------------------------------
+
+Not all the semaphore routines have been ported
+(semaphores are defined by Posix but are not part
+pf pthread). I have just done enough to make
+pthread routines (that rely internally on semaphores)
+work, like signal conditions.
+
+I noticed that the Win32 threads work slightly
+differently on WinCE. This may have some impact
+on some tricky parts of pthread-win32, but I have
+not really investigated. For example, on WinCE,
+the process is killed if the main thread falls off
+the bottom (or calls pthread_exit), regardless
+of the existence of any other detached thread.
+Microsoft manual indicates that this behavior is
+deffirent from that of Windows Threads for other
+Win32 platforms.
+
+
+Detailed descriptions of the changes and rationals:
+
+------------------------------------
+- use a new macro NEED_ERRNO.
+
+If defined, the code in errno.c that defines a reentrant errno
+is compiled, regardless of _MT and _REENTRANT.
+
+Rational: On WinCE, there is no support for <stdio.h>, <errno.h> or
+any other standard C library, i.e. even if _MT or _REENTRANT
+is defined, errno is not provided by any library. NEED_ERRNO
+must be set to compile for WinCE.
+
+------------------------------------
+- In implement.h, change #include <semaphore.h> to #include "semaphore.h".
+
+Rational: semaphore.h is provided in pthread-win32 and should not
+be searched in the systems standard include. would not compile.
+This change does not seem to create problems on "classic" win32
+(e.g. win95).
+
+------------------------------------
+- use a new macro NEED_CALLOC.
+
+If defined, some code in misc.c will provide a replacement
+for calloc, which is not available on Win32.
+
+
+------------------------------------
+- use a new macro NEED_CREATETHREAD.
+
+If defined, implement.h defines the macro _beginthreadex
+and _endthreadex.
+
+Rational: On WinCE, the wrappers _beginthreadex and _endthreadex
+do not exist. The native Win32 routines must be used.
+
+------------------------------------
+- in misc.c:
+
+#ifdef NEED_DUPLICATEHANDLE
+ /* DuplicateHandle does not exist on WinCE */
+ self->threadH = GetCurrentThread();
+#else
+ if( !DuplicateHandle(
+ GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &self->threadH,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS ) )
+ {
+ free( self );
+ return (NULL);
+ }
+#endif
+
+Rational: On WinCE, DuplicateHandle does not exist. I could not understand
+why DuplicateHandle must be used. It seems to me that getting the current
+thread handle with GetCurrentThread() is sufficient, and it seems to work
+perfectly fine, so maybe DuplicateHandle was just plain useless to begin with ?
+
+------------------------------------
+- In private.c, added some code at the beginning of _pthread_processInitialize
+to detect the case of multiple calls to _pthread_processInitialize.
+
+Rational: In order to debug pthread-win32, it is easier to compile
+it as a regular library (it is not possible to debug DLL's on winCE).
+In that case, the application must call _pthread_processInitialize()
+explicitely, to initialize pthread-win32. It is safer in this circumstance
+to handle the case where _pthread_processInitialize() is called on
+an already initialized library:
+
+int
+_pthread_processInitialize (void)
+{
+ if (_pthread_processInitialized) {
+ /*
+ * ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. such programs must call _pthread_processInitialize() explicitely,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return TRUE;
+ }
+ _pthread_processInitialized = TRUE;
+ [...]
+}
+
+------------------------------------
+- in private.c, if macro NEED_FTIME is defined, add routines to
+convert timespec_to_filetime and filetime_to_timespec, and modified
+code that was using _ftime() to use Win32 API instead.
+
+Rational: _ftime is not available on WinCE. It is necessary to use
+the native Win32 time API instead.
+
+Note: the routine timespec_to_filetime is provided as a convenience and a mean
+to test that filetime_to_timespec works, but it is not used by the library.
+
+------------------------------------
+- in semaphore.c, if macro NEED_SEM is defined, add code for the routines
+_increase_semaphore and _decrease_semaphore, and modify significantly
+the implementation of the semaphores so that it does not use CreateSemaphore.
+
+Rational: CreateSemaphore is not available on WinCE. I had to re-implement
+semaphores using mutexes and Events.
+
+Note: Only the semaphore routines that are used by pthread are implemented
+(i.e. signal conditions rely on a subset of the semaphores routines, and
+this subset works). Some other semaphore routines (e.g. sem_trywait) are
+not yet supported on my WinCE port (and since I don't need them, I am not
+planning to do anything about them).
+
+------------------------------------
+- in tsd.c, changed the code that defines TLS_OUT_OF_INDEXES
+
+/* TLS_OUT_OF_INDEXES not defined on WinCE */
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
+Rational: TLS_OUT_OF_INDEXES is not defined in any standard include file
+on WinCE.
+
+------------------------------------
+- added file need_errno.h
+
+Rational: On WinCE, there is no errno.h file. need_errno.h is just a
+copy of windows version of errno.h, with minor modifications due to the fact
+that some of the error codes are defined by the WinCE socket library.
+In pthread.h, if NEED_ERRNO is defined, the file need_errno.h is
+included (instead of <errno.h>).
+
+
+-- eof
diff --git a/condvar.c b/condvar.c
index 4b41a23..69ce69f 100644
--- a/condvar.c
+++ b/condvar.c
@@ -946,9 +946,21 @@ pthread_cond_broadcast (pthread_cond_t * cond)
/*
* Wake up all waiters
*/
+
+#ifdef NEED_SEM
+
+ result = (_pthread_increase_semaphore( &cv->sema, cv->waiters )
+ ? 0
+ : EINVAL);
+
+#else /* NEED_SEM */
+
result = (ReleaseSemaphore( cv->sema, cv->waiters, NULL )
- ? 0
- : EINVAL );
+ ? 0
+ : EINVAL);
+
+#endif /* NEED_SEM */
+
}
(void) pthread_mutex_unlock(&(cv->waitersLock));
diff --git a/config.h b/config.h
index 920b9c4..41f703f 100644
--- a/config.h
+++ b/config.h
@@ -3,11 +3,23 @@
/* Do we know about the C type sigset_t? */
#undef HAVE_SIGSET_T
-/* Do we have the `_stdcall' keyword? */
-#undef STDCALL
-
/* Define if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
-/* Define if you have the <windows.h> header file. */
-#undef HAVE_WINDOWS_H
+/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */
+#undef NEED_DUPLICATEHANDLE
+
+/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */
+#undef NEED_CREATETHREAD
+
+/* Define if you don't have Win32 errno. (eg. WinCE) */
+#undef NEED_ERRNO
+
+/* Define if you don't have Win32 calloc. (eg. WinCE) */
+#undef NEED_CALLOC
+
+/* Define if you don't have Win32 ftime. (eg. WinCE) */
+#undef NEED_FTIME
+
+/* Define if you don't have Win32 semaphores. (eg. WinCE) */
+#undef NEED_SEM
diff --git a/config.h.in b/config.h.in
index 6671c7f..41f703f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -6,5 +6,20 @@
/* Define if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
-/* Define if you have the <windows.h> header file. */
-#undef HAVE_WINDOWS_H
+/* Define if you don't have Win32 DuplicateHandle. (eg. WinCE) */
+#undef NEED_DUPLICATEHANDLE
+
+/* Define if you don't have Win32 _beginthreadex. (eg. WinCE) */
+#undef NEED_CREATETHREAD
+
+/* Define if you don't have Win32 errno. (eg. WinCE) */
+#undef NEED_ERRNO
+
+/* Define if you don't have Win32 calloc. (eg. WinCE) */
+#undef NEED_CALLOC
+
+/* Define if you don't have Win32 ftime. (eg. WinCE) */
+#undef NEED_FTIME
+
+/* Define if you don't have Win32 semaphores. (eg. WinCE) */
+#undef NEED_SEM
diff --git a/errno.c b/errno.c
index c457dd7..77c747a 100644
--- a/errno.c
+++ b/errno.c
@@ -24,7 +24,7 @@
* MA 02111-1307, USA
*/
-#if ! defined( _REENTRANT ) && ! defined( _MT )
+#if (! defined(HAVE_ERRNO)) || (! defined( _REENTRANT ) && ! defined( _MT ))
#include "pthread.h"
#include "implement.h"
@@ -79,4 +79,4 @@ int * _errno( void )
} /* _errno */
-#endif /* !_REENTRANT && !_MT */
+#endif /* (! HAVE_ERRNO) || (!_REENTRANT && !_MT) */
diff --git a/implement.h b/implement.h
index 70836dc..bc76dec 100644
--- a/implement.h
+++ b/implement.h
@@ -27,7 +27,8 @@
#ifndef _IMPLEMENT_H
#define _IMPLEMENT_H
-#define PT_STDCALL __stdcall
+/* changed include from <semaphore.h> to use local file during development */
+#include "semaphore.h"
#include <semaphore.h>
@@ -315,6 +316,12 @@ extern CRITICAL_SECTION _pthread_mutex_test_init_lock;
extern CRITICAL_SECTION _pthread_cond_test_init_lock;
extern CRITICAL_SECTION _pthread_rwlock_test_init_lock;
+/* Declared in misc.c */
+#ifdef NEED_CALLOC
+#define calloc(n, s) _pthread_calloc(n, s)
+void *_pthread_calloc(size_t n, size_t s);
+#endif
+
#ifdef __cplusplus
extern "C" {
@@ -353,6 +360,12 @@ void _pthread_tkAssocDestroy (ThreadKeyAssoc * assoc);
int _pthread_sem_timedwait (sem_t * sem,
const struct timespec * abstime);
+#ifdef NEED_SEM
+void _pthread_decrease_semaphore(sem_t * sem);
+BOOL _pthread_increase_semaphore(sem_t * sem,
+ unsigned int n);
+#endif /* NEED_SEM */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -365,7 +378,7 @@ int _pthread_sem_timedwait (sem_t * sem,
*
* Patch by Anders Norlander <anorland@hem2.passagen.se>
*/
-#if defined(__CYGWIN32__) || defined(__CYGWIN__)
+#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD)
/*
* Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE
@@ -387,7 +400,7 @@ int _pthread_sem_timedwait (sem_t * sem,
#define _endthreadex ExitThread
-#endif /* __CYGWIN32__ || __CYGWIN__ */
+#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD*/
#endif /* _IMPLEMENT_H */
diff --git a/misc.c b/misc.c
index 208541a..84dc6eb 100644
--- a/misc.c
+++ b/misc.c
@@ -163,6 +163,10 @@ pthread_self (void)
self->thread = GetCurrentThreadId ();
+#ifdef NEED_DUPLICATEHANDLE
+ /* DuplicateHandle does not exist on WinCE */
+ self->threadH = GetCurrentThread();
+#else
if( !DuplicateHandle(
GetCurrentProcess(),
GetCurrentThread(),
@@ -175,6 +179,7 @@ pthread_self (void)
free( self );
return (NULL);
}
+#endif
}
pthread_setspecific (_pthread_selfThreadKey, self);
@@ -361,4 +366,17 @@ pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout)
return (CancelableWait(waitHandle, timeout));
}
-
+#ifdef NEED_CALLOC
+void
+*_pthread_calloc(size_t n, size_t s) {
+ unsigned int m = n*s;
+ void *p;
+
+ p = malloc(m);
+ if (p == NULL) return NULL;
+
+ memset(p, 0, m);
+
+ return p;
+}
+#endif
diff --git a/mutex.c b/mutex.c
index 16e911c..bef116e 100644
--- a/mutex.c
+++ b/mutex.c
@@ -22,8 +22,9 @@
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*/
-
-#include <errno.h>
+
+/* errno.h or a replacement file is included by pthread.h */
+//#include <errno.h>
#include "pthread.h"
#include "implement.h"
diff --git a/need_errno.h b/need_errno.h
new file mode 100644
index 0000000..d10f951
--- /dev/null
+++ b/need_errno.h
@@ -0,0 +1,132 @@
+/***
+*errno.h - system wide error numbers (set by system calls)
+*
+* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* This file defines the system-wide error numbers (set by
+* system calls). Conforms to the XENIX standard. Extended
+* for compatibility with Uniforum standard.
+* [System V]
+*
+* [Public]
+*
+****/
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#ifndef _INC_ERRNO
+#define _INC_ERRNO
+
+#if !defined(_WIN32) && !defined(_MAC)
+#error ERROR: Only Mac or Win32 targets supported!
+#endif
+
+#include <winsock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/* Define _CRTIMP */
+
+#ifndef _CRTIMP
+#ifdef _DLL
+#define _CRTIMP __declspec(dllimport)
+#else /* ndef _DLL */
+#define _CRTIMP
+#endif /* _DLL */
+#endif /* _CRTIMP */
+
+
+/* Define __cdecl for non-Microsoft compilers */
+
+#if ( !defined(_MSC_VER) && !defined(__cdecl) )
+#define __cdecl
+#endif
+
+/* Define _CRTAPI1 (for compatibility with the NT SDK) */
+
+#ifndef _CRTAPI1
+#if _MSC_VER >= 800 && _M_IX86 >= 300
+#define _CRTAPI1 __cdecl
+#else
+#define _CRTAPI1
+#endif
+#endif
+
+
+/* declare reference to errno */
+
+#if (defined(_MT) || defined(_DLL)) && !defined(_MAC)
+_CRTIMP extern int * __cdecl _errno(void);
+#define errno (*_errno())
+#else /* ndef _MT && ndef _DLL */
+_CRTIMP extern int errno;
+#endif /* _MT || _DLL */
+
+/* Error Codes */
+
+#define EPERM 1
+#define ENOENT 2
+#define ESRCH 3
+#define EINTR 4
+#define EIO 5
+#define ENXIO 6
+#define E2BIG 7
+#define ENOEXEC 8
+#define EBADF 9
+#define ECHILD 10
+#define EAGAIN 11
+#define ENOMEM 12
+#define EACCES 13
+#define EFAULT 14
+#define EBUSY 16
+#define EEXIST 17
+#define EXDEV 18
+#define ENODEV 19
+#define ENOTDIR 20
+#define EISDIR 21
+#define EINVAL 22
+#define ENFILE 23
+#define EMFILE 24
+#define ENOTTY 25
+#define EFBIG 27
+#define ENOSPC 28
+#define ESPIPE 29
+#define EROFS 30
+#define EMLINK 31
+#define EPIPE 32
+#define EDOM 33
+#define ERANGE 34
+#define EDEADLK 36
+
+/* defined differently in winsock.h on WinCE */
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 38
+#endif
+
+#define ENOLCK 39
+#define ENOSYS 40
+
+/* defined differently in winsock.h on WinCE */
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 41
+#endif
+
+#define EILSEQ 42
+
+/*
+ * Support EDEADLOCK for compatibiity with older MS-C versions.
+ */
+#define EDEADLOCK EDEADLK
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _INC_ERRNO */
diff --git a/private.c b/private.c
index cd01fe5..2e0f53f 100644
--- a/private.c
+++ b/private.c
@@ -30,7 +30,9 @@
#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */
+#ifndef NEED_FTIME
#include <sys/timeb.h>
+#endif
#include "pthread.h"
#include "semaphore.h"
#include "implement.h"
@@ -60,6 +62,17 @@ _pthread_processInitialize (void)
* ------------------------------------------------------
*/
{
+ if (_pthread_processInitialized) {
+ /*
+ * ignore if already initialized. this is useful for
+ * programs that uses a non-dll pthread
+ * library. such programs must call _pthread_processInitialize() explicitely,
+ * since this initialization routine is automatically called only when
+ * the dll is loaded.
+ */
+ return TRUE;
+ }
+
_pthread_processInitialized = TRUE;
/*
@@ -586,6 +599,46 @@ _pthread_callUserDestroyRoutines (pthread_t thread)
} /* _pthread_callUserDestroyRoutines */
+
+#ifdef NEED_FTIME
+
+/*
+ * time between jan 1, 1601 and jan 1, 1970 in units of 100 nanoseconds
+ */
+#define TIMESPEC_TO_FILETIME_OFFSET \
+ ( ((LONGLONG) 27111902 << 32) + (LONGLONG) 3577643008 )
+
+static void
+timespec_to_filetime(const struct timespec *ts, FILETIME *ft)
+ /*
+ * -------------------------------------------------------------------
+ * converts struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * into FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * -------------------------------------------------------------------
+ */
+{
+ *(LONGLONG *)ft = ts->tv_sec * 10000000 + (ts->tv_nsec + 50) / 100 + TIMESPEC_TO_FILETIME_OFFSET;
+}
+
+static void
+filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
+ /*
+ * -------------------------------------------------------------------
+ * converts FILETIME (as set by GetSystemTimeAsFileTime), where the time is
+ * expressed in 100 nanoseconds from Jan 1, 1601,
+ * into struct timespec
+ * where the time is expressed in seconds and nanoseconds from Jan 1, 1970.
+ * -------------------------------------------------------------------
+ */
+{
+ ts->tv_sec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
+ ts->tv_nsec = (int)((*(LONGLONG *)ft - TIMESPEC_TO_FILETIME_OFFSET - ((LONGLONG)ts->tv_sec * (LONGLONG)10000000)) * 100);
+}
+
+#endif /* NEED_FTIME */
+
int
_pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)
/*
@@ -628,15 +681,21 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)
{
int result = 0;
+#ifdef NEED_FTIME
+
+ struct timespec currSysTime;
+
+#else /* NEED_FTIME */
#if defined(__MINGW32__)
struct timeb currSysTime;
-#else
+#else /* __MINGW32__ */
struct _timeb currSysTime;
-#endif
+#endif /* __MINGW32__ */
+#endif /* NEED_FTIME */
const DWORD NANOSEC_PER_MILLISEC = 1000000;
const DWORD MILLISEC_PER_SEC = 1000;
@@ -659,18 +718,56 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)
*/
/* get current system time */
+
+#ifdef NEED_FTIME
+
+ {
+ FILETIME ft;
+ SYSTEMTIME st;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ /*
+ * GetSystemTimeAsFileTime(&ft); would be faster,
+ * but it does not exist on WinCE
+ */
+
+ filetime_to_timespec(&ft, &currSysTime);
+ }
+
+ /*
+ * subtract current system time from abstime
+ */
+ milliseconds = (abstime->tv_sec - currSysTime.tv_sec) * MILLISEC_PER_SEC;
+ milliseconds += ((abstime->tv_nsec - currSysTime.tv_nsec) + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
+
+#else /* NEED_FTIME */
_ftime(&currSysTime);
- /* subtract current system time from abstime */
+ /*
+ * subtract current system time from abstime
+ */
milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC;
- milliseconds += (abstime->tv_nsec / NANOSEC_PER_MILLISEC) -
+ milliseconds += ((abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC) -
currSysTime.millitm;
+#endif /* NEED_FTIME */
+
+
if (((int) milliseconds) < 0)
milliseconds = 0;
}
+#ifdef NEED_SEM
+
+ result = (pthreadCancelableTimedWait (sem->event, milliseconds));
+
+#else /* NEED_SEM */
+
result = (pthreadCancelableTimedWait (*sem, milliseconds));
+
+#endif
+
}
if (result != 0)
@@ -681,6 +778,12 @@ _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime)
}
+#ifdef NEED_SEM
+
+ _pthread_decrease_semaphore(sem);
+
+#endif /* NEED_SEM */
+
return 0;
} /* _pthread_sem_timedwait */
diff --git a/pthread.def b/pthread.def
index 6920d5a..9a4efac 100644
--- a/pthread.def
+++ b/pthread.def
@@ -1,11 +1,12 @@
; pthread.def
-; Last updated: $Date: 1999/09/15 00:56:22 $
+; Last updated: $Date: 1999/11/04 17:18:43 $
; Currently unimplemented functions are commented out.
LIBRARY pthread
EXPORTS
+_pthread_processInitialize
;pthread_atfork
pthread_attr_destroy
pthread_attr_getdetachstate
@@ -108,3 +109,4 @@ pthreadCancelableTimedWait
;
pthread_push_cleanup
pthread_pop_cleanup
+
diff --git a/pthread.h b/pthread.h
index 87f769e..54d00ba 100644
--- a/pthread.h
+++ b/pthread.h
@@ -215,7 +215,12 @@
#endif /* HAVE_CONFIG_H */
#include <windows.h>
+
+#ifndef NEED_FTIME
#include <time.h>
+#else /* NEED_FTIME */
+/* use native WIN32 time API */
+#endif /* NEED_FTIME */
#if HAVE_SIGNAL_H
#include <signal.h>
@@ -242,15 +247,24 @@ struct timespec {
#define SIG_SETMASK 2
#endif /* SIG_SETMASK */
-
#include <process.h>
+
+/*
+ * note: ETIMEDOUT is correctly defined in winsock.h on winCE
+ */
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
#include <errno.h>
+#endif
-#ifdef _WIN32
#ifndef ETIMEDOUT
-#define ETIMEDOUT 19981220 /* Let's hope this is unique */
+#define ETIMEDOUT 19981220 /* FIXME: Need the proper value here. */
#endif
-#endif /* _WIN32 */
#ifdef _MSC_VER
/*
@@ -264,6 +278,13 @@ struct timespec {
#define FALSE 0
#endif /* !TRUE */
+#ifdef __MINGW32__
+#define PT_STDCALL
+#else
+#define PT_STDCALL __stdcall
+#endif
+
+
/*
* This should perhaps be in autoconf or
* possibly fixed in Mingw32 to
@@ -704,6 +725,12 @@ struct _pthread_cleanup_t
*/
/*
+ * Useful if an application wants to statically link
+ * the lib rather than load the DLL at run-time.
+ */
+int pthread_win32_initialize_np(void);
+
+/*
* PThread Attribute Functions
*/
int pthread_attr_init (pthread_attr_t * attr);
@@ -902,7 +929,7 @@ int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);
/*
* Thread-Safe C Runtime Library Mappings.
*/
-#if ! defined( _REENTRANT ) && ! defined( _MT )
+#if (! defined(NEED_ERRNO)) || (! defined( _REENTRANT ) && ! defined( _MT ))
int * _errno( void );
#endif
diff --git a/sched.h b/sched.h
index 2f498d3..197ac7b 100644
--- a/sched.h
+++ b/sched.h
@@ -43,8 +43,8 @@
#endif
#include <windows.h>
-#include <process.h>
-#include <errno.h>
+//#include <process.h>
+//#include <errno.h>
#ifdef _MSC_VER
/*
diff --git a/semaphore.c b/semaphore.c
index 0fcfc94..a8c346e 100644
--- a/semaphore.c
+++ b/semaphore.c
@@ -43,14 +43,13 @@
*/
#include <windows.h>
-#include <process.h>
-#include <sys/timeb.h>
+//#include <process.h>
+//#include <sys/timeb.h>
#include <string.h>
#include "pthread.h"
#include "semaphore.h"
-
int
sem_init (sem_t * sem, int pshared, unsigned int value)
/*
@@ -90,6 +89,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value)
{
int result = 0;
+
if (pshared != 0)
{
/*
@@ -101,6 +101,22 @@ sem_init (sem_t * sem, int pshared, unsigned int value)
}
else
{
+
+#ifdef NEED_SEM
+
+ sem->value = value;
+ pthread_mutex_init(&sem->mutex, NULL);
+ sem->event = CreateEvent (NULL,
+ FALSE, /* manual reset */
+ FALSE, /* initial state */
+ NULL);
+ if (value != 0)
+ {
+ SetEvent(sem->event);
+ }
+
+#else /* NEED_SEM */
+
/*
* NOTE: Taking advantage of the fact that
* sem_t is a simple structure with one entry;
@@ -116,6 +132,9 @@ sem_init (sem_t * sem, int pshared, unsigned int value)
{
result = ENOSPC;
}
+
+#endif /* NEED_SEM */
+
}
if (result != 0)
@@ -161,11 +180,27 @@ sem_destroy (sem_t * sem)
{
result = EINVAL;
}
+
+#ifdef NEED_SEM
+
+ else
+ {
+ pthread_mutex_destroy(&sem->mutex);
+ if (!CloseHandle(sem->event))
+ {
+ result = EINVAL;
+ }
+ }
+
+#else /* NEED_SEM */
+
else if (! CloseHandle (*sem))
{
result = EINVAL;
}
+#endif /* NEED_SEM */
+
if (result != 0)
{
errno = result;
@@ -213,11 +248,22 @@ sem_trywait (sem_t * sem)
{
result = EINVAL;
}
+
+#ifdef NEED_SEM
+
+ /* not yet implemented! */
+ result = EINVAL;
+ return -1;
+
+#else /* NEED_SEM */
+
else if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
{
result = EAGAIN;
}
+#endif /* NEED_SEM */
+
if (result != 0)
{
errno = result;
@@ -229,6 +275,53 @@ sem_trywait (sem_t * sem)
} /* sem_trywait */
+#ifdef NEED_SEM
+
+void
+_pthread_decrease_semaphore(sem_t * sem)
+{
+ pthread_mutex_lock(&sem->mutex);
+
+ if (sem->value != 0)
+ {
+ sem->value--;
+ if (sem->value != 0)
+ {
+ SetEvent(sem->event);
+ }
+ }
+ else
+ {
+ /* this case should not happen! */
+ }
+
+ pthread_mutex_unlock(&sem->mutex);
+}
+
+BOOL
+_pthread_increase_semaphore(sem_t * sem, unsigned int n)
+{
+ BOOL result;
+
+ pthread_mutex_lock(&sem->mutex);
+
+ if (sem->value + n > sem->value)
+ {
+ sem->value += n;
+ SetEvent(sem->event);
+ result = TRUE;
+ }
+ else
+ {
+ result = FALSE;
+ }
+
+ pthread_mutex_unlock(&sem->mutex);
+ return result;
+}
+
+#endif /* NEED_SEM */
+
int
sem_wait (sem_t * sem)
/*
@@ -268,7 +361,17 @@ sem_wait (sem_t * sem)
}
else
{
+
+#ifdef NEED_SEM
+
+ result = pthreadCancelableWait (sem->event);
+
+#else /* NEED_SEM */
+
result = pthreadCancelableWait (*sem);
+
+#endif /* NEED_SEM */
+
}
if (result != 0)
@@ -277,6 +380,12 @@ sem_wait (sem_t * sem)
return -1;
}
+#ifdef NEED_SEM
+
+ _decrease_semaphore(sem);
+
+#endif /* NEED_SEM */
+
return 0;
} /* sem_wait */
@@ -314,12 +423,21 @@ sem_post (sem_t * sem)
{
result = EINVAL;
}
+
+#ifdef NEED_SEM
+
+ else if (! _increase_semaphore (sem, 1))
+
+#else /* NEED_SEM */
+
else if (! ReleaseSemaphore (*sem, 1, 0))
+
+#endif /* NEED_SEM */
+
{
result = EINVAL;
}
-
if (result != 0)
{
errno = result;
diff --git a/semaphore.h b/semaphore.h
index fb475a0..8af8be8 100644
--- a/semaphore.h
+++ b/semaphore.h
@@ -28,8 +28,11 @@
#if !defined( SEMAPHORE_H )
#define SEMAPHORE_H
-#include <process.h>
+#ifdef NEED_ERRNO
+#include "need_errno.h"
+#else
#include <errno.h>
+#endif
#define _POSIX_SEMAPHORES
@@ -42,7 +45,15 @@ extern "C"
typedef unsigned int mode_t;
#endif
+#ifdef NEED_SEM
+typedef struct {
+ unsigned int value;
+ pthread_mutex_t mutex;
+ HANDLE event;
+} sem_t;
+#else /* NEED_SEM */
typedef HANDLE sem_t;
+#endif /* NEED_SEM */
int sem_init (sem_t * sem,
int pshared,
diff --git a/signal.c b/signal.c
index 504b235..db0feec 100644
--- a/signal.c
+++ b/signal.c
@@ -23,7 +23,8 @@
* MA 02111-1307, USA
*/
-#include <errno.h>
+/* errno.h or a replacement file is included by pthread.h */
+//#include <errno.h>
#include "pthread.h"
#include "implement.h"
diff --git a/tsd.c b/tsd.c
index 0766744..f8656ce 100644
--- a/tsd.c
+++ b/tsd.c
@@ -25,6 +25,11 @@
#include "pthread.h"
#include "implement.h"
+
+/* TLS_OUT_OF_INDEXES not defined on WinCE */
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
int
pthread_key_create (pthread_key_t * key, void (*destructor) (void *))