summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpj <rpj>2000-12-29 07:08:44 +0000
committerrpj <rpj>2000-12-29 07:08:44 +0000
commit0c2cb3fb140fb0d12586587001cb1ca238cf8c25 (patch)
tree72caf359f0e3d2aea2c833c8061b65f971f91381
parentbab1896412f2d292ebd8d44bc9d6ddb58a8702b0 (diff)
./ChangeLog:
2000-12-29 Ross Johnson <rpj@special.ise.canberra.edu.au> * Makefile: Back-out "for" loops which don't work. * GNUmakefile: Remove the fake.a target; add the "realclean" target; don't remove built libs under the "clean" target. * config.h: Add a guard against multiple inclusion. * semaphore.h: Add some defines from config.h to make semaphore.h independent of config.h when building apps. * pthread.h (_errno): Back-out previous fix until we know how to fix it properly. * implement.h (lockCount): Add missing element to pthread_mutex_t_. * sync.c (pthread_join): Spelling fix in comment. * private.c (ptw32_threadStart): Reset original termination function (C++). (ptw32_threadStart): Cleanup detached threads early in case the library is statically linked. (ptw32_callUserDestroyRoutines): Remove [SEH] __try block from destructor call so that unhandled exceptions will be passed through to the system; call terminate() from [C++] try block for the same reason. * tsd.c (pthread_getspecific): Add comment. * mutex.c (pthread_mutex_init): Initialise new elements in pthread_mutex_t. (pthread_mutex_unlock): Invert "pthread_equal()" test. 2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au> * semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition. * config.h.in (HAVE_MODE_T): Added. (_UWIN): Start adding defines for the UWIN package. ./tests/ChangeLog: 2000-12-29 Ross Johnson <rpj@special.ise.canberra.edu.au> * GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is removed for "clean" target. * Makefile: Add mutex4 test. * exception3.c: Remove SEH code; automatically pass the test under SEH (which is an N/A environment). * mutex4.c: New test. * eyal1.c (do_work_unit): Add a dummy "if" to force the optimiser to retain code; reduce thread work loads. * condvar8.c (main): Add an additional "assert" for debugging; increase pthread_cond_signal timeout.
-rw-r--r--ChangeLog39
-rw-r--r--GNUmakefile13
-rw-r--r--Makefile20
-rw-r--r--config.h20
-rw-r--r--config.h.in20
-rw-r--r--implement.h1
-rw-r--r--mutex.c4
-rw-r--r--private.c57
-rw-r--r--pthread.h6
-rw-r--r--semaphore.h23
-rw-r--r--sync.c4
-rw-r--r--tests/ChangeLog17
-rw-r--r--tests/GNUmakefile5
-rw-r--r--tests/Makefile3
-rw-r--r--tests/condvar8.c8
-rw-r--r--tests/exception3.c72
-rw-r--r--tests/eyal1.c12
-rw-r--r--tests/mutex4.c34
-rw-r--r--tsd.c2
19 files changed, 228 insertions, 132 deletions
diff --git a/ChangeLog b/ChangeLog
index 28ff9d4..e8d72a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,44 @@
+2000-12-29 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * Makefile: Back-out "for" loops which don't work.
+
+ * GNUmakefile: Remove the fake.a target; add the "realclean"
+ target; don't remove built libs under the "clean" target.
+
+ * config.h: Add a guard against multiple inclusion.
+
+ * semaphore.h: Add some defines from config.h to make
+ semaphore.h independent of config.h when building apps.
+
+ * pthread.h (_errno): Back-out previous fix until we know how to
+ fix it properly.
+
+ * implement.h (lockCount): Add missing element to pthread_mutex_t_.
+
+ * sync.c (pthread_join): Spelling fix in comment.
+
+ * private.c (ptw32_threadStart): Reset original termination
+ function (C++).
+ (ptw32_threadStart): Cleanup detached threads early in case
+ the library is statically linked.
+ (ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
+ destructor call so that unhandled exceptions will be passed through
+ to the system; call terminate() from [C++] try block for the same
+ reason.
+
+ * tsd.c (pthread_getspecific): Add comment.
+
+ * mutex.c (pthread_mutex_init): Initialise new elements in
+ pthread_mutex_t.
+ (pthread_mutex_unlock): Invert "pthread_equal()" test.
+
2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
+ * semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
+
+ * config.h.in (HAVE_MODE_T): Added.
+ (_UWIN): Start adding defines for the UWIN package.
+
* private.c (ptw32_threadStart): Unhandled exceptions are
now passed through to the system to deal with. This is consistent
with normal Windows behaviour. C++ applications may use
diff --git a/GNUmakefile b/GNUmakefile
index 9ad6119..a7d13b3 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -52,12 +52,6 @@ LIBS = libpthreadw32.a
all: $(LIBS)
-fake.a:
- @ $(CP) pthreadVCE.dll $(DLL)
- dlltool --def pthread.def --output-lib $@ --dllname $(DLL)
- @-$(RM) $(LIBS)
- $(MV) fake.a $(LIBS)
-
$(LIBS): $(DLL)
dlltool --def pthread.def --output-lib $@ --dllname $(DLL)
@@ -78,10 +72,11 @@ $(DLL): $(OBJS)
clean:
-$(RM) *~
- -$(RM) $(LIBS)
-$(RM) *.o
-$(RM) *.exe
- -$(RM) $(DLL)
-$(RM) $(DLL:.dll=.base)
-$(RM) $(DLL:.dll=.exp)
- -$(RM) fake.a
+
+realclean:
+ -$(RM) $(LIBS)
+ -$(RM) $(DLL)
diff --git a/Makefile b/Makefile
index 1f63c31..ac8a718 100644
--- a/Makefile
+++ b/Makefile
@@ -53,21 +53,15 @@ VSE:
@ nmake /nologo EHFLAGS="$(VSEFLAGS)" pthreadVSE.dll
realclean: clean
- @ for %%ext in (dll lib) do \
- if exist *.%%ext del *.%%ext
-
-# del *.dll
-# del *.lib
+ if exist *.dll del *.dll
+ if exit *.lib del *.lib
clean:
- @ for %%ext in (obj ilk pdb exp o) do \
- if exist *.%%ext del *.%%ext
-
-# if exist *.obj del *.obj
-# if exist *.ilk del *.ilk
-# if exist *.pdb del *.pdb
-# if exist *.exp del *.exp
-# if exist *.o del *.o
+ if exist *.obj del *.obj
+ if exist *.ilk del *.ilk
+ if exist *.pdb del *.pdb
+ if exist *.exp del *.exp
+ if exist *.o del *.o
install: $(DLLS)
diff --git a/config.h b/config.h
index acea758..75e0338 100644
--- a/config.h
+++ b/config.h
@@ -1,5 +1,8 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
+#ifndef PTW32_CONFIG_H
+#define PTW32_CONFIG_H
+
/* Do we know about the C type sigset_t? */
#undef HAVE_SIGSET_T
@@ -27,6 +30,12 @@
/* Define if you need to convert string parameters to unicode. (eg. WinCE) */
#undef NEED_UNICODE_CONSTS
+/* Do we know about type mode_t? */
+#undef HAVE_MODE_T
+
+/* Define if you have the timespec struct */
+#undef HAVE_STRUCT_TIMESPEC
+
/*
* Target specific groups
*/
@@ -39,3 +48,14 @@
#define NEED_SEM
#define NEED_UNICODE_CONSTS
#endif
+
+#ifdef _UWIN
+#define HAVE_MODE_T
+#define HAVE_STRUCT_TIMESPEC
+#endif
+
+#ifdef __MINGW32__
+#define HAVE_MODE_T
+#endif
+
+#endif \ No newline at end of file
diff --git a/config.h.in b/config.h.in
index acea758..75e0338 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,5 +1,8 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
+#ifndef PTW32_CONFIG_H
+#define PTW32_CONFIG_H
+
/* Do we know about the C type sigset_t? */
#undef HAVE_SIGSET_T
@@ -27,6 +30,12 @@
/* Define if you need to convert string parameters to unicode. (eg. WinCE) */
#undef NEED_UNICODE_CONSTS
+/* Do we know about type mode_t? */
+#undef HAVE_MODE_T
+
+/* Define if you have the timespec struct */
+#undef HAVE_STRUCT_TIMESPEC
+
/*
* Target specific groups
*/
@@ -39,3 +48,14 @@
#define NEED_SEM
#define NEED_UNICODE_CONSTS
#endif
+
+#ifdef _UWIN
+#define HAVE_MODE_T
+#define HAVE_STRUCT_TIMESPEC
+#endif
+
+#ifdef __MINGW32__
+#define HAVE_MODE_T
+#endif
+
+#endif \ No newline at end of file
diff --git a/implement.h b/implement.h
index 9c74bb4..c6f535e 100644
--- a/implement.h
+++ b/implement.h
@@ -124,6 +124,7 @@ struct pthread_attr_t_ {
struct pthread_mutex_t_ {
HANDLE mutex;
CRITICAL_SECTION cs;
+ int lockCount;
pthread_t ownerThread;
};
diff --git a/mutex.c b/mutex.c
index d31b3b2..3e4722e 100644
--- a/mutex.c
+++ b/mutex.c
@@ -105,6 +105,8 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
}
mx->mutex = 0;
+ mx->lockCount = 0;
+ mx->ownerThread = NULL;
if (attr != NULL
&& *attr != NULL
@@ -586,7 +588,7 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
{
pthread_t self = pthread_self();
- if (pthread_equal(mx->ownerThread, self) == 0)
+ if (pthread_equal(mx->ownerThread, self))
{
int oldCount = mx->lockCount;
pthread_t oldOwner = mx->ownerThread;
diff --git a/private.c b/private.c
index 977eb67..ee3ab52 100644
--- a/private.c
+++ b/private.c
@@ -240,7 +240,7 @@ ptw32_threadStart (ThreadParms * threadParms)
void *(*start) (void *);
void *arg;
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__cplusplus)
DWORD ei[] = {0,0,0};
#endif
@@ -354,6 +354,7 @@ ptw32_threadStart (ThreadParms * threadParms)
*/
status = self->exitStatus = PTHREAD_CANCELED;
(void) pthread_mutex_destroy(&self->cancelLock);
+ (void) set_terminate(ptw32_oldTerminate);
ptw32_callUserDestroyRoutines(self);
throw;
@@ -362,6 +363,8 @@ ptw32_threadStart (ThreadParms * threadParms)
*/
}
+ (void) set_terminate(ptw32_oldTerminate);
+
#else /* __cplusplus */
/*
@@ -375,7 +378,32 @@ ptw32_threadStart (ThreadParms * threadParms)
#endif /* _MSC_VER */
(void) pthread_mutex_destroy(&self->cancelLock);
- ptw32_callUserDestroyRoutines(self);
+
+#if 1
+ if (self->detachState == PTHREAD_CREATE_DETACHED)
+ {
+ /*
+ * We need to cleanup the pthread now in case we have
+ * been statically linked, in which case the cleanup
+ * in dllMain won't get done. Joinable threads will
+ * be cleaned up by pthread_join().
+ *
+ * Note that implicitly created pthreads (those created
+ * for Win32 threads which have called pthreads routines)
+ * must be cleaned up explicitly by the application
+ * (by calling pthread_win32_thread_detach_np()) if
+ * this library has been statically linked. For the dll,
+ * dllMain will do the cleanup automatically.
+ */
+ (void) pthread_win32_thread_detach_np ();
+ }
+ else
+ {
+ ptw32_callUserDestroyRoutines (self);
+ }
+#else
+ ptw32_callUserDestroyRoutines (self);
+#endif
#if ! defined (__MINGW32__) || defined (__MSVCRT__)
_endthreadex ((unsigned) status);
@@ -611,21 +639,15 @@ ptw32_callUserDestroyRoutines (pthread_t thread)
#if defined(_MSC_VER) && !defined(__cplusplus)
- __try
- {
/*
* Run the caller's cleanup routine.
+ *
+ * If an exception occurs we let the system handle it
+ * as an unhandled exception. Since we are leaving the
+ * thread we should not get any internal pthreads
+ * exceptions.
*/
(*(k->destructor)) (value);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- /*
- * A system unexpected exception had occurred
- * running the user's destructor.
- * We get control back within this block.
- */
- }
#else /* _MSC_VER && !__cplusplus */
#ifdef __cplusplus
@@ -640,10 +662,15 @@ ptw32_callUserDestroyRoutines (pthread_t thread)
catch (...)
{
/*
- * A system unexpected exception had occurred
+ * A system unexpected exception has occurred
* running the user's destructor.
- * We get control back within this block.
+ * We get control back within this block in case
+ * the application has set up it's own terminate
+ * handler. Since we are leaving the thread we
+ * should not get any internal pthreads
+ * exceptions.
*/
+ terminate();
}
#else /* __cplusplus */
diff --git a/pthread.h b/pthread.h
index 21f4be9..cada83c 100644
--- a/pthread.h
+++ b/pthread.h
@@ -941,6 +941,11 @@ int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);
/*
* Thread-Safe C Runtime Library Mappings.
*/
+#if 1
+#if (! defined(NEED_ERRNO)) || (! defined( _REENTRANT ) && (! defined( _MT ) || ! defined( _MD )))
+int * _errno( void );
+#endif
+#else
#if (! defined(NEED_ERRNO)) || (! defined( _REENTRANT ) && (! defined( _MT ) || ! defined( _MD )))
#if defined(PTW32_BUILD)
__declspec( dllexport ) int * _errno( void );
@@ -948,6 +953,7 @@ __declspec( dllexport ) int * _errno( void );
int * _errno( void );
#endif
#endif
+#endif
/*
* WIN32 C runtime library had been made thread-safe
diff --git a/semaphore.h b/semaphore.h
index 8af8be8..bc66e35 100644
--- a/semaphore.h
+++ b/semaphore.h
@@ -28,7 +28,26 @@
#if !defined( SEMAPHORE_H )
#define SEMAPHORE_H
-#ifdef NEED_ERRNO
+/*
+ * This is a duplicate of what is in the autoconf config.h,
+ * which is only used when building the pthread-win32 libraries.
+ */
+
+#ifndef PTW32_CONFIG_H
+# if defined(WINCE)
+# define NEED_ERRNO
+# define NEED_SEM
+# endif
+# if defined(_UWIN) || defined(__MINGW32__)
+# define HAVE_MODE_T
+# endif
+#endif
+
+/*
+ *
+ */
+
+#ifdef NEED_SEM
#include "need_errno.h"
#else
#include <errno.h>
@@ -41,7 +60,7 @@ extern "C"
{
#endif /* __cplusplus */
-#if defined(_MSC_VER)
+#ifndef HAVE_MODE_T
typedef unsigned int mode_t;
#endif
diff --git a/sync.c b/sync.c
index 83f421c..4fb168c 100644
--- a/sync.c
+++ b/sync.c
@@ -131,10 +131,10 @@ pthread_join (pthread_t thread, void **value_ptr)
{
/*
* Pthread_join is a cancelation point.
- * If we are cancelled then our target thread must not be
+ * If we are canceled then our target thread must not be
* detached (destroyed). This is guarranteed because
* pthreadCancelableWait will not return if we
- * are cancelled.
+ * are canceled.
*/
result = pthreadCancelableWait(thread->threadH);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index db66602..92fca1b 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,20 @@
+2000-12-29 Ross Johnson <rpj@special.ise.canberra.edu.au>
+
+ * GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
+ removed for "clean" target.
+ * Makefile: Add mutex4 test.
+
+ * exception3.c: Remove SEH code; automatically pass the test
+ under SEH (which is an N/A environment).
+
+ * mutex4.c: New test.
+
+ * eyal1.c (do_work_unit): Add a dummy "if" to force the
+ optimiser to retain code; reduce thread work loads.
+
+ * condvar8.c (main): Add an additional "assert" for debugging;
+ increase pthread_cond_signal timeout.
+
2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
* eyal1.c: Increase thread work loads.
diff --git a/tests/GNUmakefile b/tests/GNUmakefile
index 7b4fd64..33de3ac 100644
--- a/tests/GNUmakefile
+++ b/tests/GNUmakefile
@@ -32,7 +32,7 @@ COPYFILES = $(HDR) $(LIB) $(DLL)
TESTS = loadfree \
mutex1 condvar1 condvar2 exit1 create1 equal1 \
exit2 exit3 \
- join0 join1 join2 mutex2 mutex3 \
+ join0 join1 join2 mutex2 mutex3 mutex4 \
count1 once1 tsd1 self1 self2 cancel1 cancel2 eyal1 \
condvar3 condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \
errno1 \
@@ -57,6 +57,7 @@ create1.pass: mutex2.pass
cancel1.pass: create1.pass
cancel2.pass: cancel1.pass
mutex3.pass: create1.pass
+mutex4.pass: mutex3.pass
equal1.pass: create1.pass
exit2.pass: create1.pass
exit3.pass: create1.pass
@@ -122,7 +123,7 @@ clean:
- $(RM) pthread.h
- $(RM) semaphore.h
- $(RM) sched.h
- - $(RM) *.a
+ - $(RM) libpthreadw32.a
- $(RM) *.e
- $(RM) *.obj
- $(RM) *.pdb
diff --git a/tests/Makefile b/tests/Makefile
index 208b438..281cd50 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -33,7 +33,7 @@ EHFLAGS =
# stop.
PASSES= loadfree.pass \
- mutex1.pass mutex2.pass mutex3.pass \
+ mutex1.pass mutex2.pass mutex3.pass mutex4.pass \
condvar1.pass condvar2.pass \
exit1.pass create1.pass equal1.pass \
exit2.pass exit3.pass \
@@ -112,6 +112,7 @@ create1.pass: mutex2.pass
cancel1.pass: create1.pass
cancel2.pass: cancel1.pass
mutex3.pass: create1.pass
+mutex4.pass: mutex3.pass
equal1.pass: create1.pass
exit2.pass: create1.pass
exit3.pass: create1.pass
diff --git a/tests/condvar8.c b/tests/condvar8.c
index 9e63b79..ff893c7 100644
--- a/tests/condvar8.c
+++ b/tests/condvar8.c
@@ -93,10 +93,6 @@ mythread(void * arg)
assert(pthread_mutex_lock(&cvthing.lock) == 0);
- /*
- * pthread_cond_timedwait is a cancelation point and we
- * going to cancel one deliberately.
- */
pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock);
while (! (cvthing.shared > 0))
@@ -135,7 +131,7 @@ main()
abstime.tv_sec = currSysTime.time;
abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
- abstime.tv_sec += 5;
+ abstime.tv_sec += 10;
assert((t[0] = pthread_self()) != NULL);
@@ -179,6 +175,8 @@ main()
* Give threads time to complete.
*/
Sleep(1000);
+
+ assert(awoken == (i - 1));
}
diff --git a/tests/exception3.c b/tests/exception3.c
index b820b4b..66f4173 100644
--- a/tests/exception3.c
+++ b/tests/exception3.c
@@ -39,17 +39,16 @@
* - Process returns non-zero exit status.
*/
+#include "test.h"
+
+#if defined(__cplusplus)
-#if defined(_MSC_VER) && defined(__cplusplus)
+#if defined(_MSC_VER)
#include <eh.h>
#else
#include <new.h>
#endif
-#if defined(_MSC_VER) || defined(__cplusplus)
-
-#include "test.h"
-
/*
* Create NUMTHREADS threads in addition to the Main thread.
*/
@@ -60,28 +59,12 @@ enum {
int caught = 0;
pthread_mutex_t caughtLock = PTHREAD_MUTEX_INITIALIZER;
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-LONG unhandledExceptionFilter (EXCEPTION_POINTERS *ep)
-{
- if (ep->ExceptionRecord->ExceptionCode == 0x1)
- {
- pthread_mutex_lock(&caughtLock);
- caught++;
- pthread_mutex_unlock(&caughtLock);
- }
-
- return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-#elif defined(__cplusplus)
-
void
terminateFunction ()
{
pthread_mutex_lock(&caughtLock);
caught++;
-#if 1
+#if 0
{
FILE * fp = fopen("pthread.log", "a");
fprintf(fp, "Caught = %d\n", caught);
@@ -92,28 +75,15 @@ terminateFunction ()
pthread_exit((void *) 0);
}
-#endif
-
void *
exceptionedThread(void * arg)
{
int dummy = 0x1;
- {
-#if defined(_MSC_VER) && !defined(__cplusplus)
+ (void) set_terminate(&terminateFunction);
+ throw dummy;
- RaiseException(dummy, 0, 0, NULL);
-
-#elif defined(__cplusplus)
-
- (void) set_terminate(&terminateFunction);
-
- throw dummy;
-
-#endif
- }
-
- return (void *) 100;
+ return (void *) 0;
}
int
@@ -125,25 +95,13 @@ main()
assert((mt = pthread_self()) != NULL);
- {
-#if defined(_MSC_VER) && !defined(__cplusplus)
- LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
- oldHandler = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) unhandledExceptionFilter);
-#endif
-
- for (i = 0; i < NUMTHREADS; i++)
- {
- assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
- }
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
- (void) SetUnhandledExceptionFilter(oldHandler);
-#endif
+ for (i = 0; i < NUMTHREADS; i++)
+ {
+ assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0);
+ }
- Sleep(30000);
- }
+ Sleep(10000);
- printf("Caught = %d\n", caught);
assert(caught == NUMTHREADS);
/*
@@ -152,7 +110,7 @@ main()
return 0;
}
-#else /* defined(_MSC_VER) || defined(__cplusplus) */
+#else /* defined(__cplusplus) */
int
main()
@@ -161,4 +119,4 @@ main()
return 0;
}
-#endif /* defined(_MSC_VER) || defined(__cplusplus) */
+#endif /* defined(__cplusplus) */
diff --git a/tests/eyal1.c b/tests/eyal1.c
index a9ba909..6954c3b 100644
--- a/tests/eyal1.c
+++ b/tests/eyal1.c
@@ -63,7 +63,7 @@ typedef struct thread_control TC;
static TC *tcs = NULL;
static int nthreads = 10;
-static int nwork = 1000;
+static int nwork = 100;
static int quiet = 0;
static int todo = -1;
@@ -86,7 +86,7 @@ die (int ret)
}
-static void
+static double
waste_time (int n)
{
int i;
@@ -98,6 +98,7 @@ waste_time (int n)
{
f = 2 * f * f / (f * f);
}
+ return f;
}
static int
@@ -105,6 +106,7 @@ do_work_unit (int who, int n)
{
int i;
static int nchars = 0;
+ double f = 0.0;
if (quiet)
i = 0;
@@ -131,7 +133,11 @@ do_work_unit (int who, int n)
}
n = rand () % 10000; /* ignore incoming 'n' */
- waste_time (n);
+ f = waste_time (n);
+
+ /* This prevents the statement above from being optimised out */
+ if (f > 0.0)
+ return(n);
return (n);
}
diff --git a/tests/mutex4.c b/tests/mutex4.c
index 5290f2a..7b989d0 100644
--- a/tests/mutex4.c
+++ b/tests/mutex4.c
@@ -10,35 +10,32 @@
*/
#include "test.h"
-
-pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t locker_done = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t unlocker_done = PTHREAD_MUTEX_INITIALIZER;
-static int washere = 0;
+static int wasHere = 0;
+
+static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
void * locker(void * arg)
{
- assert(pthread_mutex_lock(&locker_start) == 0);
+ wasHere++;
assert(pthread_mutex_lock(&mutex1) == 0);
- assert(pthread_mutex_unlock(&locker_start) == 0);
-
- /* Wait for unlocker to finish */
- assert(pthread_mutex_lock(&unlocker_end) == 0);
+ Sleep(1000);
assert(pthread_mutex_unlock(&mutex1) == 0);
+ wasHere++;
return 0;
}
void * unlocker(void * arg)
{
+ wasHere++;
+
/* Wait for locker to lock mutex1 */
- assert(pthread_mutex_lock(&unlocker_start) == 0);
+ Sleep(500);
assert(pthread_mutex_unlock(&mutex1) == EPERM);
- assert(pthread_mutex_unlock(&unlocker_start) == 0);
-
+ wasHere++;
return 0;
}
@@ -47,16 +44,11 @@ main()
{
pthread_t t;
- assert(pthread_mutex_lock(&locker_start) == 0);
- assert(pthread_mutex_lock(&unlocker_start) == 0);
-
assert(pthread_create(&t, NULL, locker, NULL) == 0);
- assert(pthread_mutex_unlock(&locker_start) == 0);
- Sleep(0);
-
assert(pthread_create(&t, NULL, unlocker, NULL) == 0);
- assert(pthread_mutex_unlock(&unlocker_start) == 0);
- Sleep(0);
+ Sleep(2000);
+
+ assert(wasHere == 4);
return 0;
}
diff --git a/tsd.c b/tsd.c
index cd80ff9..4e95210 100644
--- a/tsd.c
+++ b/tsd.c
@@ -317,7 +317,7 @@ pthread_getspecific (pthread_key_t key)
* the thread, NULL is returned.
*
* RESULTS
- * key value
+ * key value or NULL on failure
*
* ------------------------------------------------------
*/