diff options
Diffstat (limited to 'pthreads/tests')
151 files changed, 20743 insertions, 0 deletions
diff --git a/pthreads/tests/Bmakefile b/pthreads/tests/Bmakefile new file mode 100644 index 000000000..9a2c2b4bb --- /dev/null +++ b/pthreads/tests/Bmakefile @@ -0,0 +1,350 @@ +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +# 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 +# + +DLL_VER = 2 + +CP = copy +RM = erase +CAT = type +MKDIR = mkdir +TOUCH = echo Passed > +ECHO = @echo + +QAPC = ..\QueueUserAPCEx\User\quserex.dll + +CPHDR = pthread.h semaphore.h sched.h + +OPTIM = -O2 + +XXLIBS = cw32mti.lib ws2_32.lib + +# C++ Exceptions +BCEFLAGS = -P -DPtW32NoCatchWarn -D__CLEANUP_CXX +BCELIB = pthreadBCE$(DLL_VER).lib +BCEDLL = pthreadBCE$(DLL_VER).dll +# C cleanup code +BCFLAGS = -D__CLEANUP_C +BCLIB = pthreadBC$(DLL_VER).lib +BCDLL = pthreadBC$(DLL_VER).dll +# C++ Exceptions in application - using VC version of pthreads dll +BCXFLAGS = -D__CLEANUP_C + +# Defaults +CPLIB = $(BCLIB) +CPDLL = $(BCDLL) + +CFLAGS= -q $(OPTIM) /D_WIN32_WINNT=0x400 -w -tWC -tWM -4 -w-aus -w-asc -w-par +LFLAGS= +INCLUDES=-I. +BUILD_DIR=.. + +COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC) + +EHFLAGS = + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES= loadfree.pass \ + errno1.pass \ + self1.pass mutex5.pass \ + mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass \ + semaphore1.pass semaphore2.pass semaphore3.pass \ + mutex2.pass mutex3.pass \ + mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass \ + condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass \ + exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass \ + kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.pass join2.pass join3.pass \ + mutex4.pass mutex6.pass mutex6n.pass mutex6e.pass mutex6r.pass \ + mutex6s.pass mutex6es.pass mutex6rs.pass \ + mutex7.pass mutex7n.pass mutex7e.pass mutex7r.pass \ + mutex8.pass mutex8n.pass mutex8e.pass mutex8r.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ + tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ + condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ + condvar4.pass condvar5.pass condvar6.pass \ + condvar7.pass condvar8.pass condvar9.pass \ + rwlock1.pass rwlock2.pass rwlock3.pass rwlock4.pass \ + rwlock5.pass rwlock6.pass rwlock7.pass rwlock8.pass \ + rwlock2_t.pass rwlock3_t.pass rwlock4_t.pass rwlock5_t.pass rwlock6_t.pass rwlock6_t2.pass \ + context1.pass \ + cancel3.pass cancel4.pass cancel5.pass cancel6a.pass cancel6d.pass \ + cancel7.pass cancel8.pass \ + cleanup0.pass cleanup1.pass cleanup2.pass cleanup3.pass \ + priority1.pass priority2.pass inherit1.pass \ + spin1.pass spin2.pass spin3.pass spin4.pass \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass create3.pass stress1.pass + +BENCHRESULTS = \ + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +help: + @ $(ECHO) Run one of the following command lines: + @ $(ECHO) make clean BC (to test using BC dll with VC (no EH) applications) + @ $(ECHO) make clean BCX (to test using BC dll with VC++ (EH) applications) + @ $(ECHO) make clean BCE (to test using the BCE dll with VC++ EH applications) + @ $(ECHO) make clean BC-bench (to benchtest using BC dll with C bench app) + @ $(ECHO) make clean BCX-bench (to benchtest using BC dll with C++ bench app) + @ $(ECHO) make clean BCE-bench (to benchtest using BCE dll with C++ bench app) + +all: + @ make clean BC + @ make clean BCX + @ make clean BCE + @ make clean BC-bench + +# This allows an individual test application to be made using the default lib. +# e.g. make clean test cancel3.exe +test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) sizes.pass $(PASSES) + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(BENCHRESULTS) + @ $(ECHO) ALL BENCH TESTS DONE. + +sizes.pass: sizes.exe + @ $(ECHO) ... Running $(TEST) test: $*.exe + @ .\$*.exe > SIZES.$(TEST) + @ $(CAT) SIZES.$(TEST) + @ $(ECHO) ...... Passed + @ $(TOUCH) $*.pass + +BCE: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" tests + +BC: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" tests + +BCX: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" tests + +BCE-bench: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCELIB)" CPDLL="$(BCEDLL)" EHFLAGS="$(BCEFLAGS)" XXLIBS="benchlib.o" benchtests + +BC-bench: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCFLAGS)" XXLIBS="benchlib.o" benchtests + +BCX-bench: + @ make -f Bmakefile TEST="$@" CPLIB="$(BCLIB)" CPDLL="$(BCDLL)" EHFLAGS="$(BCXFLAGS)" XXLIBS="benchlib.o" benchtests + +.exe.pass: + @ $(ECHO) ... Running $(TEST) test: $< + @ .\$< + @ $(ECHO) ...... Passed + @ $(TOUCH) $@ + +.exe.bench: + @ $(ECHO) ... Running $(TEST) benchtest: $< + @ .\$< + @ $(ECHO) ...... Done + @ $(TOUCH) $@ + +.c.exe: + @ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS) + @ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< -e$@ $(LFLAGS) $(CPLIB) $(XXLIBS) + +.c.o: + @ $(ECHO) $(CC) $(EHFLAGS) -c $(CFLAGS) $(INCLUDES) $< -o$@ + @ $(CC) $(EHFLAGS) $(CFLAGS) -c $(INCLUDES) $< -o$@ + + +.c.i: + @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): + @ $(ECHO) Copying $@ + @ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: $(CPDLL) + @ $(CP) $(CPDLL) pthread.dll + @ $(CP) $(CPLIB) pthread.lib + +clean: + - $(RM) *.dll + - $(RM) *.lib + - $(RM) pthread.h + - $(RM) semaphore.h + - $(RM) sched.h + - $(RM) *.e + - $(RM) *.i + - $(RM) *.obj + - $(RM) *.tds + - $(RM) *.pdb + - $(RM) *.o + - $(RM) *.asm + - $(RM) *.exe + - $(RM) *.pass + - $(RM) *.bench + - $(RM) *.log + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: +barrier1.pass: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cancel9.pass: cancel8.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +semaphore5.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass diff --git a/pthreads/tests/ChangeLog b/pthreads/tests/ChangeLog new file mode 100644 index 000000000..6b2c74250 --- /dev/null +++ b/pthreads/tests/ChangeLog @@ -0,0 +1,894 @@ +2005-06-12 Ross Johnson <rpj@callisto.canberra.edu.au> + + * stress1.c (millisecondsFromNow): Remove limit 0 <= millisecs < 1000; + now works for -INT_MAX <= millisecs <= INT_MAX; not needed for + stress1.c but should be general anyway. + +2005-05-18 Ross Johnson <rpj@callisto.canberra.edu.au> + + * reuse2.c (main): Must use a read with memory barrier semantics + when polling 'done' to force the cache into coherence on MP systems. + +2005-05-15 Ross Johnson <rpj@callisto.canberra.edu.au> + + * detach1.c: New test. + * join1.c: Reduce sleep times. + * join0.c: Remove MSVCRT conditional compile - join should always + return the thread exit code. + * join1.c: Likewise. + * join2.c: Likewise. + * join3.c: Likewise. + +2005-04-18 Ross Johnson <rpj@callisto.canberra.edu.au> + + * condvar3.c: Remove locks from around signalling calls - should not + be required for normal operation and only serve to mask deficiencies; + ensure that CV destruction is not premature after removing guards. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * condvar3_3.c: Likewise. + * condvar4.c: Likewise. + * condvar5.c: Likewise. + * condvar6.c: Likewise. + * condvar7.c: Likewise. + * condvar8.c: Likewise. + * condvar9.c: Likewise. + +2005-04-11 Ross Johnson <rpj@callisto.canberra.edu.au> + + * once4.c: New test; tries to test priority adjustments + in pthread_once(); set priority class to realtime so that + any failures can be seen. + +2005-04-06 Ross Johnson <rpj@callisto.canberra.edu.au> + + * cleanup0.c: Fix unguarded global variable accesses. + * cleanup1.c: Likewise. + * cleanup2.c: Likewise. + * cleanup3.c: Likewise. + * once2.c: Likewise. + * once3.c: Likewise. + +2005-04-01 Ross Johnson <rpj@callisto.canberra.edu.au> + + * GNUmakefile: Add target to test linking static link library. + * Makefile: Likewise. + * self1.c: Run process attach/detach routines when static linked. + +2005-03-16 Ross Johnson <rpj@callisto.canberra.edu.au> + + * mutex5.c: Prevent optimiser from removing asserts. + +2005-03-12 Ross Johnson <rpj@callisto.canberra.edu.au> + + * once3.c: New test. + +2005-03-08 Ross Johnson <rpj@callisto.canberra.edu.au> + + * once2.c: New test. + +2004-11-19 Ross Johnson <rpj@callisto.canberra.edu.au> + + * Bmakefile: New makefile for Borland. + * Makefile (DLL_VER): Added. + * GNUmakefile (DLL_VER): Added. + * Wmakefile (DLL_VER): Added. + +2004-10-29 Ross Johnson <rpj@callisto.canberra.edu.au> + + * semaphore4.c: New test. + * semaphore4t.c: New test. + * Debug.dsp (et al): Created MSVC Workspace project to aid debugging. + * All: Many tests have been modified to work with the new pthread + ID type; some other corrections were made after some library + functions were semantically strengthened. For example, + pthread_cond_destroy() no longer destroys a busy CV, which + required minor redesigns of some tests, including some where + the mutex associated with the CV was not locked during + signaling and broadcasting. + +2004-10-23 Ross Johnson <rpj@callisto.canberra.edu.au> + + * condvar3.c: Fixed mutex operations that were incorrectly + placed in relation to their condition variable operations. + The error became evident after sem_destroy() was rewritten + and conditions for destroing the semaphore were tightened. + As a result, pthread_cond_destroy() was not able to + destroy the cv queueing sempahore. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * condvar4.c: Likewise. + * condvar5.c: Likewise. + * condvar6.c: Likewise. + * condvar7.c: Likewise. + * condvar8.c: Likewise. + * condvar9.c: Likewise. + +2004-10-19 Ross Johnson <rpj@callisto.canberra.edu.au> + + * semaphore3.c: New test. + +2004-10-14 Ross Johnson <rpj@callisto.canberra.edu.au> + + * rwlock7.c (main): Tidy up statistics reporting; randomise + update accesses. + * rwlock8.c: New test. + +2004-09-08 Alexandre Girao <alexgirao@gmail.com> + + * cancel7.c (main): Win98 wants a valid (non-NULL) location + for the last arg of _beginthreadex(). + * cancel8.c (main): Likewise. + * exit4.c (main): Likewise. + * exit5.c (main): Likewise. + +2004-08-26 Ross Johnson <rpj@callisto.canberra.edu.au> + + * create3.c: New test. + +2004-06-21 Ross Johnson <rpj@callisto.canberra.edu.au> + + * mutex2r.c: New test. + * mutex2e.c: New test. + * mutex3r.c: New test. + * mutex3e.c: New test. + * mutex6s.c: New test. + * mutex6rs.c: New test. + * mutex6es.c: New test. + +2004-05-21 Ross Johnson <rpj@callisto.canberra.edu.au> + + * join3.c: New test. + +2004-05-16 Ross Johnson <rpj@callisto.canberra.edu.au> + + * condvar2.c (WIN32_WINNT): Define to avoid redefinition warning + from inclusion of implement.h. + * convar2_1.c: Likewise. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * context1.c: Likewise. + * sizes.c: Likewise. + * Makefile: Don't define _WIN32_WINNT on compiler command line. + * GNUmakefile: Likewise. + * priority1.c (main): Add column to output for actual win32 + priority. + +2004-05-16 Ross Johnson <rpj@callisto.canberra.edu.au> + + * cancel9.c: New test. + * cancel3.c: Remove inappropriate conditional compilation; + GNU C version of test suite no longer quietly skips this test. + * cancel5.c: Likewise. + * GNUmakefile: Can now build individual test app using default + C version of library using 'make clean testname.c'. + * Makefile: Likewise for VC using 'nmake clean test testname.c'. + +2003-10-14 Ross Johnson <rpj@callisto.canberra.edu.au> + + * Wmakefile: New makefile for Watcom testing. + +2003-09-18 Ross Johnson <rpj@callisto.canberra.edu.au> + + * benchtest.h: Move old mutex code into benchlib.c. + * benchlib.c: New statically linked module to ensure that + bench apps don't inline the code and therefore have an unfair + advantage over the pthreads lib routines. Made little or no + difference. + * benchtest1.c: Minor change to avoid compiler warnings. + * benchtest5.c: Likewise. + * benchtest2.c: Fix misinformation in output report. + * README.BENCH: Add comments on results. + +2003-09-14 Ross Johnson <rpj@callisto.canberra.edu.au> + + * priority1.c: Reworked to comply with modified priority + management and provide additional output. + * priority2.c: Likewise. + * inherit1.c: Likewise. + +2003-09-03 Ross Johnson <rpj@callisto.canberra.edu.au> + + * exit4.c: New test. + * exit5.c: New test. + * cancel7.c: New test. + * cancel8.c: New test. + +2003-08-13 Ross Johnson <rpj@ise.canberra.edu.au> + + * reuse1.c: New test. + * reuse1.c: New test. + * valid1.c: New test. + * valid2.c: New test. + * kill1.c: New test. + * create2.c: Now included in test regime. + +2003-07-19 Ross Johnson <rpj@ise.canberra.edu.au> + + * eyal1.c (waste_time): Make threads do more work to ensure that + all threads get to do some work. + * semaphore1.c: Make it clear that certain errors are expected. + * exception2.c (non_MSVC code sections): Change to include + C++ standard include file, i.e. change <new.h> to <exception>. + * exception3.c (non_MSVC code sections): Likewise; qualify std:: + namespace entities where necessary. + * GNUmakefile: modified to work in the MsysDTK (newer MinGW) + environment; define CC as gcc or g++ as appropriate because + using gcc -x c++ doesn't link with required c++ libs by default, + but g++ does. + +2002-12-11 Ross Johnson <ross@special.ise.canberra.edu.au> + + * mutex7e.c: Assert EBUSY return instead of EDEADLK. + +2002-06-03 Ross Johnson <rpj@digit.ise.canberra.edu.au> + + * semaphore2.c: New test. + +2002-03-02 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * Makefile (CFLAGS): Changed /MT to /MD to link with + the correct library MSVCRT.LIB. Otherwise errno doesn't + work. + +2002-02-28 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * exception3.c: Correct recent change. + + * semaphore1.c: New test. + + * Makefile: Add rule to generate pre-processor output. + +2002-02-28 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * exception3.c (terminateFunction): For MSVC++, call + exit() rather than pthread_exit(). Add comments to explain + why. + * Notes from the MSVC++ manual: + * 1) A term_func() should call exit(), otherwise + * abort() will be called on return to the caller. + * abort() raises SIGABRT. The default signal handler + * for all signals terminates the calling program with + * exit code 3. + * 2) A term_func() must not throw an exception. Therefore + * term_func() should not call pthread_exit() if an + * an exception-using version of pthreads-win32 library + * is being used (i.e. either pthreadVCE or pthreadVSE). + + +2002-02-23 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * rwlock2_t.c: New test. + * rwlock3_t.c: New test. + * rwlock4_t.c: New test. + * rwlock5_t.c: New test. + * rwlock6_t.c: New test. + * rwlock6_t2.c: New test. + * rwlock6.c (main): Swap thread and result variables + to correspond to actual thread functions. + * rwlock1.c: Change test description comment to correspond + to the actual test. + + * condvar1_2.c: Loop over the test many times in the hope + of detecting any intermittent deadlocks. This is to + test a fixed problem in pthread_cond_destroy.c. + + * spin4.c: Remove unused variable. + +2002-02-17 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * condvar1_1.c: New test. + * condvar1_2.c: New test. + +2002-02-07 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * delay1.c: New test. + * delay2.c: New test. + * exit4.c: New test. + +2002-02-02 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * mutex8: New test. + * mutex8n: New test. + * mutex8e: New test. + * mutex8r: New test. + * cancel6a: New test. + * cancel6d: New test. + * cleanup0.c: Add pragmas for inline optimisation control. + * cleanup1.c: Add pragmas for inline optimisation control. + * cleanup2.c: Add pragmas for inline optimisation control. + * cleanup3.c: Add pragmas for inline optimisation control. + * condvar7.c: Add pragmas for inline optimisation control. + * condvar8.c: Add pragmas for inline optimisation control. + * condvar9.c: Add pragmas for inline optimisation control. + +2002-01-30 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cleanup1.c (): Must be declared __cdecl when compiled + as C++ AND testing the standard C library version. + +2002-01-16 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * spin4.c (main): Fix renamed function call. + +2002-01-14 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * exception3.c (main): Shorten wait time. + +2002-01-09 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * mutex7.c: New test. + * mutex7n.c: New test. + * mutex7e.c: New test. + * mutex7r.c: New test. + * mutex6.c: Modified to avoid leaving the locked mutex + around on exit. + +2001-10-25 Ross Johnson <rpj@setup1.ise.canberra.edu.au> + + * condvar2.c: Remove reference to cv->nWaitersUnblocked. + * condvar2_1.c: Likewise; lower NUMTHREADS from 60 to 30. + * condvar3_1.c: Likewise. + * condvar3_2.c: Likewise. + * count1.c: lower NUMTHREADS from 60 to 30. + * inherit1.c: Determine valid priority values and then + assert values returned by POSIX routines are the same. + * priority1.c: Likewise. + * priority2.c: Likewise. + +2001-07-12 Ross Johnson <rpj@setup1.ise.canberra.edu.au> + + * barrier5.c: Assert that precisely one thread receives + PTHREAD_BARRIER_SERIAL_THREAD at each barrier. + +2001-07-09 Ross Johnson <rpj@setup1.ise.canberra.edu.au> + + * barrier3.c: Fixed. + * barrier4.c: Fixed. + * barrier5.c: New; proves that all threads in the group + reaching the barrier wait and then resume together. Repeats the test + using groups of 1 to 16 threads. Each group of threads must negotiate + a large number of barriers (10000). + * spin4.c: Fixed. + * test.h (error_string): Modified the success (0) value. + +2001-07-07 Ross Johnson <rpj@setup1.ise.canberra.edu.au> + + * spin3.c: Changed test and fixed. + * spin4.c: Fixed. + * barrier3.c: Fixed. + * barrier4.c: Fixed. + +2001-07-05 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * spin1.c: New; testing spinlocks. + * spin2.c: New; testing spinlocks. + * spin3.c: New; testing spinlocks. + * spin4.c: New; testing spinlocks. + * barrier1.c: New; testing barriers. + * barrier2.c: New; testing barriers. + * barrier3.c: New; testing barriers. + * barrier4.c: New; testing barriers. + * GNUmakefile: Add new tests. + * Makefile: Add new tests. + +2001-07-01 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * benchtest3.c: New; timing mutexes. + * benchtest4.c: New; time mutexes. + * condvar3_1.c: Fixed bug - Alexander Terekhov + * condvar3_3.c: New test. + +2001-06-25 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * priority1.c: New test. + * priority2.c: New test. + * inherit1.c: New test. + * benchtest1.c: New; timing mutexes. + * benchtest2.c: New; timing mutexes. + * mutex4.c: Modified to test all mutex types. + +2001-06-8 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * mutex5.c: Insert inert change to quell compiler warnings. + * condvar3_2.c: Remove unused variable. + +2001-06-3 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * condvar2_1.c: New test. + * condvar3_1.c: New test. + * condvar3_2.c: New test. + +2001-05-30 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * mutex1n.c: New test. + * mutex1e.c: New test. + * mutex1r.c: New test. + * mutex4.c: Now locks and unlocks a mutex. + * mutex5.c: New test. + * mutex6.c: New test. + * mutex6n.c: New test. + * mutex6e.c: New test. + * mutex6r.c: New test. + * Makefile: Added new tests; reorganised. + * GNUmakefile: Likewise. + * rwlock6.c: Fix to properly prove read-while-write locking + and single writer locking. + +2001-05-29 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * Makefile: Reorganisation. + * GNUmakefile: Likewise. + - Thomas Pfaff <tpfaff@gmx.net> + + * exception1.c: Add stdio.h include to define fprintf and stderr + in non-exception C version of main(). + * exception2.c: Likewise. + * exception3.c: Likewise. + + * Makefile (rwlock7): Add new test. + * GNUmakefile (rwlock7): Add new test. + * rwlock7.c: New test. + * rwlock6.c: Changed to test that writer has priority. + + * eyal1.c (main): Unlock each mutex_start lock before destroying + it. + +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. + * exception2.c: New test. + * exception3.c: New test. + * Makefile: Add new tests exception2.c and exception3.c. + * GNUmakefile: Likewise. + +2000-12-11 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cleanup3.c: Remove unused variable. + * cleanup2.c: Likewise. + * exception1.c: Throw an exception rather than use + a deliberate zero divide so that catch(...) will + handle it under Mingw32. Mingw32 now builds the + library correctly to pass all tests - see Thomas + Pfaff's detailed instructions re needed changes + to Mingw32 in the Pthreads-Win32 FAQ. + +2000-09-08 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cancel5.c: New; tests calling pthread_cancel() + from the main thread without first creating a + POSIX thread struct for the non-POSIX main thread + - this forces pthread_cancel() to create one via + pthread_self(). + * Makefile (cancel5): Add new test. + * GNUmakefile (cancel5): Likewise. + +2000-08-17 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * create2.c: New; Test that pthread_t contains + the W32 HANDLE before it calls the thread routine + proper. + +2000-08-13 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * condvar3.c: Minor change to eliminate compiler + warning. + + * condvar4.c: ditto. + + * condvar5.c: ditto. + + * condvar6.c: ditto. + + * condvar7.c: ditto. + + * condvar8.c: ditto. + + * condvar9.c: ditto. + + * exit1.c: Function needed return statement. + + * cleanup1.c: Remove unnecessary printf arg. + + * cleanup2.c: Fix cast. + + * rwlock6.c: Fix casts. + + * exception1.c (PtW32CatchAll): Had the wrong name; + fix casts. + + * cancel3.c: Remove unused waitLock variable. + + * GNUmakefile: Change library/dll naming; add new tests; + general minor changes. + + * Makefile: Change library/dll naming; add targets for + testing each of the two VC++ EH scheme versions; + default target now issues help message; compile warnings + now interpreted as errors to stop the make; add new + tests; restructure to remove prerequisites needed + otherwise. + + * README: Updated. + + +2000-08-10 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * eyal1.c (main): Change implicit cast to explicit + cast when passing "print_server" function pointer; + G++ no longer allows implicit func parameter casts. + + * cleanup1.c: Remove unused "waitLock". + (main): Fix implicit parameter cast. + + * cancel2.c (main): Fix implicit parameter cast. + + * cancel4.c (main): Fix implicit parameter cast. + + * cancel3.c (main): Fix implicit parameter cast. + + * GNUmakefile: Renamed from Makefile; Add missing + cancel1 and cancel2 test targets. + + * Makefile: Converted for use with MS nmake. + +2000-08-06 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * ccl.bat: Add /nologo to remove extraneous output. + + * exception1.c (exceptionedThread): Init 'dummy'; + put expression into if condition to prevent optimising away; + remove unused variable. + + * cancel4.c (mythread): Cast return value to avoid warnings. + + * cancel2.c (mythread): Missing #endif. + + * condvar9.c (mythread): Cast return value to avoid warnings. + + * condvar8.c (mythread): Cast return value to avoid warnings. + + * condvar7.c (mythread): Cast return value to avoid warnings. + + * cleanup3.c (mythread): Cast return value to avoid warnings. + + * cleanup2.c (mythread): Cast return value to avoid warnings. + + * cleanup1.c (mythread): Cast return value to avoid warnings. + + * condvar5.c (mythread): Cast return value to avoid warnings. + + * condvar3.c (mythread): Cast return value to avoid warnings. + + * condvar6.c (mythread): Cast return value to avoid warnings. + + * condvar4.c (mythread): Cast return value to avoid warnings. + +2000-08-05 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cancel2.c: Use PtW32CatchAll macro if defined. + + * exception1.c: Use PtW32CatchAll macro if defined. + +2000-08-02 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * tsd1.c: Fix typecasts of &result [g++ is now very fussy]. + + * test.h (assert): Return 0's explicitly to allay + g++ errors. + + * join2.c: Add explicit typecasts. + + * join1.c: Add explicit typecasts. + + * join0.c: Add explicit typecasts. + + * eyal1.c: Add explicit typecasts. + + * count1.c (main): Add type cast to remove g++ parse warning + [gcc-2.95.2 seems to have tightened up on this]. + + * Makefile (GLANG): Use c++ explicitly. + Remove MSVC sections (was commented out). + Add target to generate cpp output. + +2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * runtest.bat: modified to work under W98. + + * runall.bat: Add new tests; modified to work under W98. + It was ok under NT. + + * Makefile: Add new tests. + + * exception1.c: New; Test passing exceptions back to the + application and retaining library internal exceptions. + + * join0.c: New; Test a single join. + +2000-01-06 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cleanup1.c: New; Test cleanup handler executes (when thread is + canceled). + + * cleanup2.c: New; Test cleanup handler executes (when thread is + not canceled). + + * cleanup3.c: New; Test cleanup handler does not execute + (when thread is not canceled). + +2000-01-04 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * cancel4.c: New; Test cancelation does not occur in deferred + cancelation threads with no cancelation points. + + * cancel3.c: New; Test asynchronous cancelation. + + * context1.c: New; Test context switching method for async + cancelation. + +1999-11-23 Ross Johnson <rpj@special.ise.canberra.edu.au> + + * test.h: Add header includes; include local header versions rather + than system versions; rearrange the assert macro defines. + +1999-11-07 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * loadfree.c: New. Test loading and freeing the library (DLL). + +1999-10-30 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * cancel1.c: New. Test pthread_setcancelstate and + pthread_setcanceltype functions. + * eyal1.c (waste_time): Change calculation to avoid FP exception + on Aplhas + - Rich Peters <rpeters@micro-magic.com> + +Oct 14 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * condvar7.c: New. Test broadcast after waiting thread is canceled. + * condvar8.c: New. Test multiple broadcasts. + * condvar9.c: New. Test multiple broadcasts with thread + cancelation. + +Sep 16 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * rwlock6.c: New test. + +Sep 15 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * rwlock1.c: New test. + * rwlock2.c: New test. + * rwlock3.c: New test. + * rwlock4.c: New test. + * rwlock5.c: New test. + +Aug 22 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * runall.bat (join2): Add test. + +Aug 19 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * join2.c: New test. + +Wed Aug 12 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * Makefile (LIBS): Add -L. + +Mon May 31 10:25:01 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * Makefile (GLANG): Add GCC language option. + +Sat May 29 23:29:04 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * runall.bat (condvar5): Add new test. + + * runall.bat (condvar6): Add new test. + + * Makefile (condvar5) : Add new test. + + * Makefile (condvar6) : Add new test. + + * condvar5.c: New test for pthread_cond_broadcast(). + + * condvar6.c: New test for pthread_cond_broadcast(). + +Sun Apr 4 12:04:28 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * tsd1.c (mythread): Change Sleep(0) to sched_yield(). + (sched.h): Include. + + * condvar3.c (mythread): Remove redundant Sleep(). + + * runtest.bat: Re-organised to make more informative. + +Fri Mar 19 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * *.bat: redirect unwanted output to nul: + + * runall.bat: new. + + * cancel1.c: new. Not part of suite yet. + +Mon Mar 15 00:17:55 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * mutex1.c: only test mutex init and destroy; add assertions. + + * count1.c: raise number of spawned threads to 60 (appears to + be the limit under Win98). + +Sun Mar 14 21:31:02 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * test.h (assert): add assertion trace option. + Use: + "#define ASSERT_TRACE 1" to turn it on, + "#define ASSERT_TRACE 0" to turn it off (default). + + * condvar3.c (main): add more assertions. + + * condvar4.c (main): add more assertions. + + * condvar1.c (main): add more assertions. + +Fri Mar 12 08:34:15 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * condvar4.c (cvthing): switch the order of the INITIALIZERs. + + * eyal1.c (main): Fix trylock loop; was not waiting for thread to lock + the "started" mutex. + +Wed Mar 10 10:41:52 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * tryentercs.c: Apply typo patch from bje. + + * tryentercs2.c: Ditto. + +Sun Mar 7 10:41:52 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * Makefile (condvar3, condvar4): Add tests. + + * condvar4.c (General): Reduce to simple test case; prerequisite + is condvar3.c; add description. + + * condvar3.c (General): Reduce to simple test case; prerequisite + is condvar2.c; add description. + + * condvar2.c (General): Reduce to simple test case; prerequisite + is condvar1.c; add description. + + * condvar1.c (General): Reduce to simple test case; add + description. + + * Template.c (Comments): Add generic test detail. + +1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au> + + * Template.c: Revamp. + + * condvar1.c: Add. + + * condvar2.c: Add. + + * Makefile: Add condvar1 condvar2 tests. + + * exit1.c, exit2.c, exit3.c: Cosmetic changes. + +1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au> + + * Makefile: Some refinement. + + * *.c: More exhaustive checking through assertions; clean up; + add some more tests. + + * Makefile: Now actually runs the tests. + + * tests.h: Define our own assert macro. The Mingw32 + version pops up a dialog but we want to run non-interactively. + + * equal1.c: use assert a little more directly so that it + prints the actual call statement. + + * exit1.c: Modify to return 0 on success, 1 on failure. + +1999-02-22 Ross Johnson <rpj@ise.canberra.edu.au> + + * self2.c: Bring up to date. + + * self3.c: Ditto. + +1999-02-21 Ben Elliston <bje@cygnus.com> + + * README: Update. + + * Makefile: New file. Run all tests automatically. Primitive tests + are run first; more complex tests are run last. + + * count1.c: New test. Validate the thread count. + + * exit2.c: Perform a simpler test. + + * exit3.c: New test. Replaces exit2.c, since exit2.c needs to + perform simpler checking first. + + * create1.c: Update to use the new testsuite exiting convention. + + * equal1.c: Likewise. + + * mutex1.c: Likewise. + + * mutex2.c: Likewise. + + * once1.c: Likewise. + + * self2.c: Likewise. + + * self3.c: Likewise. + + * tsd1.c: Likewise. + +1999-02-20 Ross Johnson <rpj@ise.canberra.edu.au> + + * mutex2.c: Test static mutex initialisation. + + * test.h: New. Declares a table mapping error numbers to + error names. + +1999-01-17 Ross Johnson <rpj@ise.canberra.edu.au> + + * runtest: New script to build and run a test in the tests directory. + +Wed Dec 30 11:22:44 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * tsd1.c: Re-written. See comments at start of file. + * Template.c: New. Contains skeleton code and comment template + intended to fully document the test. + +Fri Oct 16 17:59:49 1998 Ross Johnson <rpj@swan.canberra.edu.au> + + * tsd1.c (destroy_key): Add function. Change diagnostics. + +Thu Oct 15 17:42:37 1998 Ross Johnson <rpj@swan.canberra.edu.au> + + * tsd1.c (mythread): Fix some casts and add some message + output. Fix inverted conditional. + +Mon Oct 12 02:12:29 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * tsd1.c: New. Test TSD using 1 key and 2 threads. + +1998-09-13 Ben Elliston <bje@cygnus.com> + + * eyal1.c: New file; contributed by Eyal Lebedinsky + <eyal@eyal.emu.id.au>. + +1998-09-12 Ben Elliston <bje@cygnus.com> + + * exit2.c (func): Return a value. + (main): Call the right thread entry function. + +1998-07-22 Ben Elliston <bje@cygnus.com> + + * exit2.c (main): Fix size of pthread_t array. + +1998-07-10 Ben Elliston <bje@cygnus.com> + + * exit2.c: New file; test pthread_exit() harder. + + * exit1.c: New file; test pthread_exit(). diff --git a/pthreads/tests/Debug.dsp b/pthreads/tests/Debug.dsp new file mode 100644 index 000000000..191b97862 --- /dev/null +++ b/pthreads/tests/Debug.dsp @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="Debug" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Debug - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Debug.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Debug.mak" CFG="Debug - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Debug - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Debug - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Debug - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0xc09 /d "NDEBUG" +# ADD RSC /l 0xc09 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Debug - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0xc09 /d "_DEBUG" +# ADD RSC /l 0xc09 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".." + +!ENDIF + +# Begin Target + +# Name "Debug - Win32 Release" +# Name "Debug - Win32 Debug" +# Begin Source File + +SOURCE=.\Debug.txt +# End Source File +# Begin Source File + +SOURCE=.\semaphore1.c +# End Source File +# End Target +# End Project diff --git a/pthreads/tests/Debug.dsw b/pthreads/tests/Debug.dsw new file mode 100644 index 000000000..5fd6af3e5 --- /dev/null +++ b/pthreads/tests/Debug.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Debug"=.\Debug.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/pthreads/tests/Debug.txt b/pthreads/tests/Debug.txt new file mode 100644 index 000000000..5323874f4 --- /dev/null +++ b/pthreads/tests/Debug.txt @@ -0,0 +1,6 @@ +This project is used to debug individual test case programs. + +To build and debug a test case: +- add the .c file to this project; +- remove any .c files from other test cases from this project. +- build and debug as usual.
\ No newline at end of file diff --git a/pthreads/tests/GNUmakefile b/pthreads/tests/GNUmakefile new file mode 100644 index 000000000..1762b6c7c --- /dev/null +++ b/pthreads/tests/GNUmakefile @@ -0,0 +1,375 @@ +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +# 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 +# + +DLL_VER = 2 + +CP = cp -f +MV = mv -f +RM = rm -f +CAT = cat +#CP = copy +#MV = rename +#RM = erase +#CAT = type +MKDIR = mkdir +TOUCH = echo Passed > +ECHO = @echo +MAKE = make + +# +# Mingw32 +# +XXCFLAGS = +XXLIBS = -lws2_32 +#CFLAGS = -O3 -UNDEBUG -Wall $(XXCFLAGS) +CFLAGS = -g -UNDEBUG -Wall $(XXCFLAGS) +BUILD_DIR = .. +INCLUDES = -I. + + +TEST = GC + +# Default lib version +GCX = $(TEST)$(DLL_VER) + +# Files we need to run the tests +# - paths are relative to pthreads build dir. +HDR = pthread.h semaphore.h sched.h +LIB = libpthread$(GCX).a +DLL = pthread$(GCX).dll +QAPC = ../QueueUserAPCEx/User/quserex.dll + +COPYFILES = $(HDR) $(LIB) $(DLL) $(QAPC) + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +TESTS = sizes loadfree \ + self1 mutex5 mutex1 mutex1e mutex1n mutex1r \ + semaphore1 semaphore2 semaphore3 \ + condvar1 condvar1_1 condvar1_2 condvar2 condvar2_1 exit1 \ + create1 create2 reuse1 reuse2 equal1 \ + kill1 valid1 valid2 \ + exit2 exit3 exit4 exit5 \ + join0 join1 detach1 join2 join3 \ + mutex2 mutex2r mutex2e mutex3 mutex3r mutex3e \ + mutex4 mutex6 mutex6n mutex6e mutex6r \ + mutex6s mutex6es mutex6rs \ + mutex7 mutex7n mutex7e mutex7r mutex8 mutex8n mutex8e mutex8r \ + count1 \ + once1 once2 once3 once4 self2 \ + cancel1 cancel2 \ + semaphore4 semaphore4t semaphore5 \ + barrier1 barrier2 barrier3 barrier4 barrier5 \ + tsd1 tsd2 delay1 delay2 eyal1 \ + condvar3 condvar3_1 condvar3_2 condvar3_3 \ + condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ + errno1 \ + rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 rwlock8 \ + rwlock2_t rwlock3_t rwlock4_t rwlock5_t rwlock6_t rwlock6_t2 \ + context1 cancel3 cancel4 cancel5 cancel6a cancel6d \ + cancel7 cancel8 \ + cleanup0 cleanup1 cleanup2 cleanup3 \ + priority1 priority2 inherit1 \ + spin1 spin2 spin3 spin4 \ + exception1 exception2 exception3 \ + cancel9 create3 stress1 + +STRESSTESTS = \ + stress1 + +BENCHTESTS = \ + benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 + +STATICTESTS = \ + self1 + +PASSES = $(TESTS:%=%.pass) +BENCHRESULTS = $(BENCHTESTS:%=%.bench) +STRESSRESULTS = $(STRESSTESTS:%=%.pass) +STATICRESULTS = $(STATICTESTS:%=%.pass) + +help: + @ $(ECHO) "Run one of the following command lines:" + @ $(ECHO) "make clean GC (to test using GC dll with C (no EH) applications)" + @ $(ECHO) "make clean GCX (to test using GC dll with C++ (EH) applications)" + @ $(ECHO) "make clean GCE (to test using GCE dll with C++ (EH) applications)" + @ $(ECHO) "make clean GC-bench (to benchtest using GNU C dll with C cleanup code)" + @ $(ECHO) "make clean GCE-bench (to benchtest using GNU C dll with C++ exception handling)" + @ $(ECHO) "make clean GC-stress (to stresstest using GNU C dll with C cleanup code)" + @ $(ECHO) "make clean GCE-stress (to stresstest using GNU C dll with C++ exception handling)" + @ $(ECHO) "make clean GC-static (to test using GC static lib with C (no EH) applications)" + +all: + @ $(MAKE) clean GC + @ $(MAKE) clean GCX + @ $(MAKE) clean GCE + +GC: + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-pass + +GCE: + $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-pass + +GCX: + $(MAKE) TEST=GC CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_C" all-pass + +GC-bench: + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" XXLIBS="benchlib.o" all-bench + +GCE-bench: + $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench + +GC-debug: + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" DLL_VER="$(DLL_VER)d" all-pass + +GC-static: + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" DLL="" all-static + +GC-stress: + $(ECHO) Stress tests can take a long time since they are trying to + $(ECHO) expose weaknesses that may be intermittant or statistically rare. + $(ECHO) A pass does not prove correctness, but may give greater confidence. + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" all-stress + +GCE-stress: + $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" all-stress + +all-pass: $(PASSES) + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-bench: $(BENCHRESULTS) + @ $(ECHO) BENCH TESTS COMPLETED. + +all-stress: $(STRESSRESULTS) + @ $(ECHO) STRESS TESTS COMPLETED. + +all-static: $(STATICRESULTS) + @ $(ECHO) ALL STATIC TESTS PASSED! Congratulations! + @ $(ECHO) Build and test the DLL to run all tests. + @ $(ECHO) This test only confirms that the static lib links correctly. + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: + +barrier1.pass: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel2_1.pass: cancel2.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cancel9.pass: cancel8.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: cancel2.pass +delay2.pass: delay1.pass +detach1.pass: join0.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: exit4.pass kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +semaphore5.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass + +sizes.pass: sizes.exe + @ $(ECHO) Running $* + $< > SIZES.$(TEST) + @ $(CAT) SIZES.$(TEST) + @ $(ECHO) Passed + @ $(TOUCH) $@ + +%.pass: %.exe + @ $(ECHO) Running $* + $* + @ $(ECHO) Passed + @ $(TOUCH) $@ + +%.bench: $(LIB) $(DLL) $(HDR) $(QAPC) $(XXLIBS) %.exe + @ $(ECHO) Running $* + $* + @ $(ECHO) Done + @ $(TOUCH) $@ + +%.exe: %.c $(LIB) $(DLL) $(HDR) $(QAPC) + @ $(ECHO) Compiling $@ + @ $(ECHO) $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) + @ $(CC) $(CFLAGS) -o $@ $< $(INCLUDES) -L. -lpthread$(GCX) -lsupc++ $(XXLIBS) + +%.pre: %.c $(HDR) + @ $(CC) -E $(CFLAGS) -o $@ $< $(INCLUDES) + +%.s: %.c $(HDR) + @ $(CC) -S $(CFLAGS) -o $@ $< $(INCLUDES) + +$(COPYFILES): + @ $(ECHO) Copying $@ + @ $(CP) $(BUILD_DIR)/$@ . + +benchlib.o: benchlib.c + @ $(ECHO) Compiling $@ + @ $(ECHO) $(CC) -c $(CFLAGS) $< $(INCLUDES) + @ $(CC) -c $(CFLAGS) $< $(INCLUDES) + +pthread.dll: $(DLL) + @ $(CP) $(DLL) $@ + +clean: + - $(RM) *.dll + - $(RM) *.lib + - $(RM) pthread.h + - $(RM) semaphore.h + - $(RM) sched.h + - $(RM) *.a + - $(RM) *.e + - $(RM) *.i + - $(RM) *.o + - $(RM) *.obj + - $(RM) *.pdb + - $(RM) *.exe + - $(RM) *.pass + - $(RM) *.bench + - $(RM) *.static + - $(RM) *.log diff --git a/pthreads/tests/Makefile b/pthreads/tests/Makefile new file mode 100644 index 000000000..69dc39c07 --- /dev/null +++ b/pthreads/tests/Makefile @@ -0,0 +1,404 @@ +# Makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +# 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 +# + +DLL_VER = 2 + +CP = copy +RM = erase +CAT = type +MKDIR = mkdir +TOUCH = echo Passed > +ECHO = @echo + +QAPC = ..\QueueUserAPCEx\User\quserex.dll + +CPHDR = pthread.h semaphore.h sched.h + +OPTIM = /O2 /Ob0 + +XXLIBS = ws2_32.lib + +# C++ Exceptions +VCEFLAGS = /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX +VCELIB = pthreadVCE$(DLL_VER).lib +VCEDLL = pthreadVCE$(DLL_VER).dll +# Structured Exceptions +VSEFLAGS = /D__CLEANUP_SEH +VSELIB = pthreadVSE$(DLL_VER).lib +VSEDLL = pthreadVSE$(DLL_VER).dll +# C cleanup code +VCFLAGS = /D__CLEANUP_C +VCLIB = pthreadVC$(DLL_VER).lib +VCDLL = pthreadVC$(DLL_VER).dll +# C++ Exceptions in application - using VC version of pthreads dll +VCXFLAGS = /GX /TP /D__CLEANUP_C + +# Defaults +CPLIB = $(VCLIB) +CPDLL = $(VCDLL) + +CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi +LFLAGS= /INCREMENTAL:NO +INCLUDES=-I. +BUILD_DIR=.. + +COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) $(QAPC) + +TEST = +EHFLAGS = + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES= sizes.pass loadfree.pass \ + self1.pass mutex5.pass \ + mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass \ + semaphore1.pass semaphore2.pass semaphore3.pass \ + mutex2.pass mutex3.pass \ + mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass \ + condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass \ + exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass \ + kill1.pass valid1.pass valid2.pass \ + exit2.pass exit3.pass exit4.pass exit5.pass \ + join0.pass join1.pass detach1.pass join2.pass join3.pass \ + mutex4.pass mutex6.pass mutex6n.pass mutex6e.pass mutex6r.pass \ + mutex6s.pass mutex6es.pass mutex6rs.pass \ + mutex7.pass mutex7n.pass mutex7e.pass mutex7r.pass \ + mutex8.pass mutex8n.pass mutex8e.pass mutex8r.pass \ + count1.pass \ + once1.pass once2.pass once3.pass once4.pass \ + self2.pass \ + cancel1.pass cancel2.pass \ + semaphore4.pass semaphore4t.pass semaphore5.pass \ + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ + tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ + condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ + condvar4.pass condvar5.pass condvar6.pass \ + condvar7.pass condvar8.pass condvar9.pass \ + errno1.pass \ + rwlock1.pass rwlock2.pass rwlock3.pass rwlock4.pass \ + rwlock5.pass rwlock6.pass rwlock7.pass rwlock8.pass \ + rwlock2_t.pass rwlock3_t.pass rwlock4_t.pass rwlock5_t.pass rwlock6_t.pass rwlock6_t2.pass \ + context1.pass \ + cancel3.pass cancel4.pass cancel5.pass cancel6a.pass cancel6d.pass \ + cancel7.pass cancel8.pass \ + cleanup0.pass cleanup1.pass cleanup2.pass cleanup3.pass \ + priority1.pass priority2.pass inherit1.pass \ + spin1.pass spin2.pass spin3.pass spin4.pass \ + exception1.pass exception2.pass exception3.pass \ + cancel9.pass create3.pass stress1.pass + +BENCHRESULTS = \ + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +STRESSRESULTS = \ + stress1.stress + +STATICRESULTS = \ + self1.pass + +help: + @ $(ECHO) Run one of the following command lines: + @ $(ECHO) nmake clean VC (to test using VC dll with VC (no EH) apps) + @ $(ECHO) nmake clean VC-bench (to benchtest using VC dll with C bench apps) + @ $(ECHO) nmake clean VC-stress (to stresstest using VC dll with C stress apps) + @ $(ECHO) nmake clean VC-static (to test using VC static lib with VC (no EH) apps) + @ $(ECHO) nmake clean VCX (to test using VC dll with VC++ (EH) applications) + @ $(ECHO) nmake clean VCX-bench (to benchtest using VC dll with C++ bench apps) + @ $(ECHO) nmake clean VCX-stress (to stresstest using VC dll with C++ stress apps) + @ $(ECHO) nmake clean VCE (to test using the VCE dll with VC++ EH applications) + @ $(ECHO) nmake clean VCE-bench (to benchtest using VCE dll with C++ bench apps) + @ $(ECHO) nmake clean VCE-stress (to stresstest using VCE dll with C++ stress apps) + @ $(ECHO) nmake clean VSE (to test using VSE dll with VC (SEH) apps) + @ $(ECHO) nmake clean VSE-bench (to benchtest using VSE dll with SEH bench apps) + @ $(ECHO) nmake clean VSE-stress (to stresstest using VSE dll with SEH stress apps) + +all: + @ nmake clean VC + @ nmake clean VCX + @ nmake clean VCE + @ nmake clean VSE + @ nmake clean VC-bench + @ nmake clean VC-stress + +# This allows an individual test application to be made using the default lib. +# e.g. nmake clean test cancel3.exe +test: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(QAPC) $(PASSES) + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) + @ $(ECHO) ALL BENCH TESTS DONE. + +stresstests: $(CPLIB) $(CPDLL) $(CPHDR) $(STRESSRESULTS) + @ $(ECHO) ALL STRESS TESTS DONE. + +statictests: $(CPLIB) $(CPDLL) $(CPHDR) $(STATICRESULTS) + @ $(ECHO) ALL STATIC TESTS DONE. + @ $(ECHO) Build and test the DLL to run all tests. + @ $(ECHO) The static test only confirms that the .lib links correctly. + +sizes.pass: sizes.exe + @ $(ECHO) ... Running $(TEST)$(DLL_VER) test: $*.exe + @ .\$*.exe > SIZES.$(TEST) + @ $(CAT) SIZES.$(TEST) + @ $(ECHO) ...... Passed + @ $(TOUCH) $*.pass + +$(PASSES): $*.exe + @ $(ECHO) ... Running $(TEST) test: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Passed + @ $(TOUCH) $*.pass + +$(BENCHRESULTS): $*.exe + @ $(ECHO) ... Running $(TEST) benchtest: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Done + @ $(TOUCH) $*.bench + +$(STRESSRESULTS): $*.exe + @ $(ECHO) ... Running $(TEST) stresstest: $*.exe + @ .\$*.exe + @ $(ECHO) ...... Done + @ $(TOUCH) $*.pass + +VC: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests + +VCE: + @ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" tests + +VSE: + @ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests + +VCX: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" tests + +VC-bench: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" XXLIBS="benchlib.o" benchtests + +VCE-bench: + @ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" XXLIBS="benchlib.o" benchtests + +VSE-bench: + @ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" XXLIBS="benchlib.o" benchtests + +VCX-bench: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" XXLIBS="benchlib.o" benchtests + +VC-stress: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" stresstests + +VCE-stress: + @ nmake TEST="$@" CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" stresstests + +VSE-stress: + @ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" stresstests + +VCX-stress: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" stresstests + +VC-static: + @ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="" EHFLAGS="$(VCFLAGS) /DPTW32_STATIC_LIB" statictests + +.c.exe: + @ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS) + @ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB) $(XXLIBS) + +.c.o: + @ $(ECHO) $(CC) $(EHFLAGS) /c $(CFLAGS) $(INCLUDES) $< /Fo$@ + @ $(CC) $(EHFLAGS) $(CFLAGS) /c $(INCLUDES) $< /Fo$@ + +.c.i: + @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): + @ $(ECHO) Copying $@ + @ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: $(CPDLL) + @ $(CP) $(CPDLL) pthread.dll + @ $(CP) $(CPLIB) pthread.lib + +clean: + - $(RM) *.dll + - $(RM) *.lib + - $(RM) pthread.h + - $(RM) semaphore.h + - $(RM) sched.h + - $(RM) *.e + - $(RM) *.i + - $(RM) *.obj + - $(RM) *.pdb + - $(RM) *.o + - $(RM) *.asm + - $(RM) *.exe + - $(RM) *.pass + - $(RM) *.bench + - $(RM) *.log + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: + +barrier1.pass: semaphore4.pass +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cancel9.pass: cancel8.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock8.pass: rwlock7.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +semaphore5.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: condvar9.pass barrier5.pass +tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass diff --git a/pthreads/tests/README b/pthreads/tests/README new file mode 100644 index 000000000..a1b5646b9 --- /dev/null +++ b/pthreads/tests/README @@ -0,0 +1,44 @@ +Running test cases in this directory +------------------------------------ + +These make scripts expect to be able to copy the dll, library +and header files from this directory's parent directory, +which should be the pthreads-win32 source directory. + +MS VC nmake +------------- + +Run the target corresponding to the DLL version being tested: + +nmake clean VC + +or: + +nmake clean VS + + +GNU GCC make +------------ + +Run "make clean" and then "make". See the "Known bugs" section +in ..\README. + + +Writing Test Cases +------------------ + +Tests written in this test suite should behave in the following manner: + + * If a test fails, leave main() with a result of 1. + + * If a test succeeds, leave main() with a result of 0. + + * No diagnostic output should appear when the test is succeeding. + Diagnostic output may be emitted if something in the test + fails, to help determine the cause of the test failure. + +Notes: +------ + +Many test cases use knowledge of implementation internals which are supposed +to be opaque to portable applications. diff --git a/pthreads/tests/README.BENCHTESTS b/pthreads/tests/README.BENCHTESTS new file mode 100644 index 000000000..448570c1f --- /dev/null +++ b/pthreads/tests/README.BENCHTESTS @@ -0,0 +1,74 @@ + +------------ +Benchmarking +------------ +There is a set a benchmarking programs in the +"tests" directory. These should be runnable using the +following command-lines corresponding to each of the possible +library builds: + +MSVC: +nmake clean VC-bench +nmake clean VCE-bench +nmake clean VSE-bench + +Mingw32: +make clean GC-bench +make clean GCE-bench + +UWIN: +The benchtests are run as part of the testsuite. + + +Mutex benchtests +---------------- + +benchtest1 - Lock plus unlock on an unlocked mutex. +benchtest2 - Lock plus unlock on a locked mutex. +benchtest3 - Trylock on a locked mutex. +benchtest4 - Trylock plus unlock on an unlocked mutex. + + +Each test times up to three alternate synchronisation +implementations as a reference, and then times each of +the four mutex types provided by the library. Each is +described below: + +Simple Critical Section +- uses a simple Win32 critical section. There is no +additional overhead for this case as there is in the +remaining cases. + +POSIX mutex implemented using a Critical Section +- The old implementation which uses runtime adaptation +depending on the Windows variant being run on. When +the pthreads DLL was run on WinNT or higher then +POSIX mutexes would use Win32 Critical Sections. + +POSIX mutex implemented using a Win32 Mutex +- The old implementation which uses runtime adaptation +depending on the Windows variant being run on. When +the pthreads DLL was run on Win9x then POSIX mutexes +would use Win32 Mutexes (because TryEnterCriticalSection +is not implemented on Win9x). + +PTHREAD_MUTEX_DEFAULT +PTHREAD_MUTEX_NORMAL +PTHREAD_MUTEX_ERRORCHECK +PTHREAD_MUTEX_RECURSIVE +- The current implementation supports these mutex types. +The underlying basis of POSIX mutexes is now the same +irrespective of the Windows variant, and should therefore +have consistent performance. + + +Semaphore benchtests +-------------------- + +benchtest5 - Timing for various uncontended cases. + + +In all benchtests, the operation is repeated a large +number of times and an average is calculated. Loop +overhead is measured and subtracted from all test times. + diff --git a/pthreads/tests/SIZES.GC b/pthreads/tests/SIZES.GC new file mode 100644 index 000000000..ae09a84e6 --- /dev/null +++ b/pthreads/tests/SIZES.GC @@ -0,0 +1,20 @@ +Sizes of pthreads-win32 structs +------------------------------- + pthread_t_ 124 + pthread_attr_t_ 28 + sem_t_ 4 + pthread_mutex_t_ 44 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 24 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 8 + ptw32_cleanup_t 12 + sched_param 4 +------------------------------- + diff --git a/pthreads/tests/SIZES.GCE b/pthreads/tests/SIZES.GCE new file mode 100644 index 000000000..f36d0d2b1 --- /dev/null +++ b/pthreads/tests/SIZES.GCE @@ -0,0 +1,20 @@ +Sizes of pthreads-win32 structs +------------------------------- + pthread_t_ 60 + pthread_attr_t_ 28 + sem_t_ 4 + pthread_mutex_t_ 44 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 24 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 8 + ptw32_cleanup_t 12 + sched_param 4 +------------------------------- + diff --git a/pthreads/tests/SIZES.VC b/pthreads/tests/SIZES.VC new file mode 100644 index 000000000..ae09a84e6 --- /dev/null +++ b/pthreads/tests/SIZES.VC @@ -0,0 +1,20 @@ +Sizes of pthreads-win32 structs +------------------------------- + pthread_t_ 124 + pthread_attr_t_ 28 + sem_t_ 4 + pthread_mutex_t_ 44 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 24 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 8 + ptw32_cleanup_t 12 + sched_param 4 +------------------------------- + diff --git a/pthreads/tests/SIZES.VCE b/pthreads/tests/SIZES.VCE new file mode 100644 index 000000000..edc642719 --- /dev/null +++ b/pthreads/tests/SIZES.VCE @@ -0,0 +1,19 @@ +Sizes of pthreads-win32 structs +------------------------------- + pthread_t_ 68 + pthread_attr_t_ 28 + sem_t_ 4 + pthread_mutex_t_ 44 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 24 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 8 + ptw32_cleanup_t 12 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/SIZES.VSE b/pthreads/tests/SIZES.VSE new file mode 100644 index 000000000..edc642719 --- /dev/null +++ b/pthreads/tests/SIZES.VSE @@ -0,0 +1,19 @@ +Sizes of pthreads-win32 structs +------------------------------- + pthread_t_ 68 + pthread_attr_t_ 28 + sem_t_ 4 + pthread_mutex_t_ 44 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 24 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 8 + ptw32_cleanup_t 12 + sched_param 4 +------------------------------- diff --git a/pthreads/tests/Wmakefile b/pthreads/tests/Wmakefile new file mode 100644 index 000000000..83cd34bb2 --- /dev/null +++ b/pthreads/tests/Wmakefile @@ -0,0 +1,346 @@ +# Watcom makefile for the pthreads test suite. +# If all of the .pass files can be created, the test suite has passed. +# +# -------------------------------------------------------------------------- +# +# 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 +# + + +DLL_VER = 2 + +.EXTENSIONS: + +.EXTENSIONS: .pass .exe .obj .i .c + +CP = copy +RM = erase +CAT = type +MKDIR = mkdir +TOUCH = echo Passed > +ECHO = @echo + +CPHDR = pthread.h semaphore.h sched.h + +OPTIM = -od + +XXLIBS = + +# C++ Exceptions +WCEFLAGS = -xs -dPtW32NoCatchWarn -d__CLEANUP_CXX +WCELIB = pthreadWCE$(DLL_VER).lib +WCEDLL = pthreadWCE$(DLL_VER).dll +# C cleanup code +WCFLAGS = -d__CLEANUP_C +WCLIB = pthreadWC$(DLL_VER).lib +WCDLL = pthreadWC$(DLL_VER).dll +# C++ Exceptions in application - using WC version of pthreads dll +WCXFLAGS = -xs -d__CLEANUP_C + +CFLAGS= -w4 -e25 -d_WIN32_WINNT=0x400 -d_REENTRANT -zq -bm $(OPTIM) -5r -bt=nt -mf -d2 + +LFLAGS= +INCLUDES= -i=. +BUILD_DIR=.. + +COPYFILES = $(CPHDR) $(CPLIB) $(CPDLL) + +TEST = +EHFLAGS = + +# If a test case returns a non-zero exit code to the shell, make will +# stop. + +PASSES = sizes.pass loadfree.pass & + self1.pass mutex5.pass & + mutex1.pass mutex1n.pass mutex1e.pass mutex1r.pass & + semaphore1.pass semaphore2.pass semaphore3.pass & + mutex2.pass mutex3.pass & + mutex2r.pass mutex2e.pass mutex3r.pass mutex3e.pass & + condvar1.pass condvar1_1.pass condvar1_2.pass condvar2.pass condvar2_1.pass & + exit1.pass create1.pass create2.pass reuse1.pass reuse2.pass equal1.pass & + kill1.pass valid1.pass valid2.pass & + exit2.pass exit3.pass exit4 exit5 & + join0.pass join1.pass detach1.pass join2.pass join3.pass & + mutex4.pass mutex6.pass mutex6n.pass mutex6e.pass mutex6r.pass & + mutex6s.pass mutex6es.pass mutex6rs.pass & + mutex7.pass mutex7n.pass mutex7e.pass mutex7r.pass & + mutex8.pass mutex8n.pass mutex8e.pass mutex8r.pass & + count1.pass & + once1.pass once2.pass once3.pass once4.pass tsd1.pass & + self2.pass & + cancel1.pass cancel2.pass & + semaphore4.pass semaphore4t.pass semaphore5.pass & + delay1.pass delay2.pass eyal1.pass & + condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass & + condvar4.pass condvar5.pass condvar6.pass & + condvar7.pass condvar8.pass condvar9.pass & + errno1.pass & + rwlock1.pass rwlock2.pass rwlock3.pass rwlock4.pass rwlock5.pass & + rwlock6.pass rwlock7.pass rwlock8.pass & + rwlock2_t.pass rwlock3_t.pass rwlock4_t.pass rwlock5_t.pass rwlock6_t.pass rwlock6_t2.pass & + context1.pass & + cancel3.pass cancel4.pass cancel5.pass cancel6a.pass cancel6d.pass & + cancel7 cancel8 & + cleanup0.pass cleanup1.pass cleanup2.pass cleanup3.pass & + priority1.pass priority2.pass inherit1.pass & + spin1.pass spin2.pass spin3.pass spin4.pass & + barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass & + exception1.pass exception2.pass exception3.pass & + cancel9.pass create3.pass stress1.pass + +BENCHRESULTS = & + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench + +help: .SYMBOLIC + @ $(ECHO) Run one of the following command lines: + @ $(ECHO) wmake /f Wmakefile clean WC (to test using WC dll with wcc386 (no EH) applications) + @ $(ECHO) wmake /f Wmakefile clean WCX (to test using WC dll with wpp386 (EH) applications) + @ $(ECHO) wmake /f Wmakefile clean WCE (to test using the WCE dll with wpp386 EH applications) + @ $(ECHO) wmake /f Wmakefile clean WC-bench (to benchtest using WC dll with C bench app) + @ $(ECHO) wmake /f Wmakefile clean WCX-bench (to benchtest using WC dll with C++ bench app) + @ $(ECHO) wmake /f Wmakefile clean WCE-bench (to benchtest using WCE dll with C++ bench app) + +all: .SYMBOLIC + @ wmake /f Wmakefile clean WC + @ wmake /f Wmakefile clean WCX + @ wmake /f Wmakefile clean WCE + @ wmake /f Wmakefile clean WSE + @ wmake /f Wmakefile clean WC-bench + +tests: $(CPLIB) $(CPDLL) $(CPHDR) $(PASSES) .SYMBOLIC + @ $(ECHO) ALL TESTS PASSED! Congratulations! + +benchtests: $(CPLIB) $(CPDLL) $(CPHDR) $(XXLIBS) $(BENCHRESULTS) .SYMBOLIC + @ $(ECHO) ALL BENCH TESTS DONE. + +$(BENCHRESULTS): ($[*).exe + @ $(ECHO) ... Running $(TEST) benchtest: ($[*).exe + @ .\($[*).exe + @ $(ECHO) ...... Done + @ $(TOUCH) ($[*).bench + +WCE: .SYMBOLIC + @ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" tests + +WC: .SYMBOLIC + @ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" tests + +WCX: .SYMBOLIC + @ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" tests + +WCE-bench: .SYMBOLIC + @ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCELIB)" CPDLL="$(WCEDLL)" EHFLAGS="$(WCEFLAGS)" XXLIBS="benchlib.o" benchtests + +WC-bench: .SYMBOLIC + @ wmake /f Wmakefile CC=wcc386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCFLAGS)" XXLIBS="benchlib.o" benchtests + +WCX-bench: .SYMBOLIC + @ wmake /f Wmakefile CC=wpp386 TEST="$@" CPLIB="$(WCLIB)" CPDLL="$(WCDLL)" EHFLAGS="$(WCXFLAGS)" XXLIBS="benchlib.o" benchtests + +sizes.pass: sizes.exe + @ $(ECHO) ... Running $(TEST) test: $^* + @ $[@ > SIZES.$(TEST) + @ $(CAT) SIZES.$(TEST) + @ $(ECHO) ...... Passed + @ $(TOUCH) $^@ + +.exe.pass: + @ $(ECHO) ... Running $(TEST) test: $^* + @ $[@ + @ $(ECHO) ...... Passed + @ $(TOUCH) $^@ + +.obj.exe: + @ $(ECHO) wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet + @ wlink NAME $^@ FILE $[@ LIBRARY $(CPLIB) OPTION quiet + +.c.obj: + @ $(ECHO) $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES) + @ $(CC) $^* $(EHFLAGS) $(CFLAGS) $(INCLUDES) + +.c.i: + @ $(CC) /P $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< + +$(COPYFILES): .SYMBOLIC + @ $(ECHO) Copying $@ + @ $(CP) $(BUILD_DIR)\$@ . + +pthread.dll: + @ $(CP) $(CPDLL) $*.dll + @ $(CP) $(CPLIB) $*.lib + +clean: .SYMBOLIC + @ if exist *.dll $(RM) *.dll + @ if exist *.lib $(RM) *.lib + @ if exist *.err $(RM) *.err + @ if exist pthread.h $(RM) pthread.h + @ if exist semaphore.h $(RM) semaphore.h + @ if exist sched.h $(RM) sched.h + @ if exist *.e $(RM) *.e + @ if exist *.i $(RM) *.i + @ if exist *.obj $(RM) *.obj + @ if exist *.pdb $(RM) *.pdb + @ if exist *.o $(RM) *.o + @ if exist *.asm $(RM) *.asm + @ if exist *.exe $(RM) *.exe + @ if exist *.pass $(RM) *.pass + @ if exist *.bench $(RM) *.bench + @ if exist *.log $(RM) *.log + @ $(ECHO) Clean completed. + +benchtest1.bench: +benchtest2.bench: +benchtest3.bench: +benchtest4.bench: +benchtest5.bench: +barrier1.pass: +barrier2.pass: barrier1.pass +barrier3.pass: barrier2.pass +barrier4.pass: barrier3.pass +barrier5.pass: barrier4.pass +cancel1.pass: create1.pass +cancel2.pass: cancel1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cancel6a.pass: cancel3.pass +cancel6d.pass: cancel3.pass +cancel7.pass: kill1.pass +cancel8.pass: cancel7.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar1_1.pass: condvar1.pass +condvar1_2.pass: join2.pass +condvar2.pass: condvar1.pass +condvar2_1.pass: condvar2.pass join2.pass +condvar3.pass: create1.pass condvar2.pass +condvar3_1.pass: condvar3.pass join2.pass +condvar3_2.pass: condvar3_1.pass +condvar3_3.pass: condvar3_2.pass +condvar4.pass: create1.pass +condvar5.pass: condvar4.pass +condvar6.pass: condvar5.pass +condvar7.pass: condvar6.pass cleanup1.pass +condvar8.pass: condvar7.pass +condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +create2.pass: create1.pass +create3.pass: +delay1.pass: +delay2.pass: delay1.pass +detach1.pass: join0.pass +equal1.pass: create1.pass +errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +exit4.pass: +exit5.pass: kill1.pass +eyal1.pass: tsd1.pass +inherit1.pass: join1.pass priority1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +join3.pass: join2.pass +kill1.pass: +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex2r.pass: mutex2.pass +mutex2e.pass: mutex2.pass +mutex3.pass: create1.pass +mutex3r.pass: mutex3.pass +mutex3e.pass: mutex3.pass +mutex4.pass: mutex3.pass +mutex5.pass: +mutex6.pass: mutex4.pass +mutex6n.pass: mutex4.pass +mutex6e.pass: mutex4.pass +mutex6r.pass: mutex4.pass +mutex6s.pass: mutex6.pass +mutex6rs.pass: mutex6r.pass +mutex6es.pass: mutex6e.pass +mutex7.pass: mutex6.pass +mutex7n.pass: mutex6n.pass +mutex7e.pass: mutex6e.pass +mutex7r.pass: mutex6r.pass +mutex8.pass: mutex7.pass +mutex8n.pass: mutex7n.pass +mutex8e.pass: mutex7e.pass +mutex8r.pass: mutex7r.pass +once1.pass: create1.pass +once2.pass: once1.pass +once3.pass: once2.pass +once4.pass: once3.pass +priority1.pass: join1.pass +priority2.pass: priority1.pass barrier3.pass +reuse1.pass: create2.pass +reuse2.pass: reuse1.pass +rwlock1.pass: condvar6.pass +rwlock2.pass: rwlock1.pass +rwlock3.pass: rwlock2.pass +rwlock4.pass: rwlock3.pass +rwlock5.pass: rwlock4.pass +rwlock6.pass: rwlock5.pass +rwlock7.pass: rwlock6.pass +rwlock2_t.pass: rwlock2.pass +rwlock3_t.pass: rwlock2_t.pass +rwlock4_t.pass: rwlock3_t.pass +rwlock5_t.pass: rwlock4_t.pass +rwlock6_t.pass: rwlock5_t.pass +rwlock6_t2.pass: rwlock6_t.pass +self1.pass: +self2.pass: create1.pass +semaphore1.pass: +semaphore2.pass: +semaphore3.pass: semaphore2.pass +semaphore4.pass: semaphore3.pass cancel1.pass +semaphore4t.pass: semaphore4.pass +semaphore5.pass: semaphore4.pass +sizes.pass: +spin1.pass: +spin2.pass: spin1.pass +spin3.pass: spin2.pass +spin4.pass: spin3.pass +stress1.pass: +tsd1.pass: join1.pass +valid1.pass: join1.pass +valid2.pass: valid1.pass +cancel9.pass: cancel8.pass diff --git a/pthreads/tests/barrier1.c b/pthreads/tests/barrier1.c new file mode 100644 index 000000000..76f78df66 --- /dev/null +++ b/pthreads/tests/barrier1.c @@ -0,0 +1,58 @@ +/* + * barrier1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create a barrier object and then destroy it. + * + */ + +#include "test.h" + +pthread_barrier_t barrier = NULL; + +int +main() +{ + assert(barrier == NULL); + + assert(pthread_barrier_init(&barrier, NULL, 1) == 0); + + assert(barrier != NULL); + + assert(pthread_barrier_destroy(&barrier) == 0); + + assert(barrier == NULL); + + return 0; +} diff --git a/pthreads/tests/barrier2.c b/pthreads/tests/barrier2.c new file mode 100644 index 000000000..28aa238c5 --- /dev/null +++ b/pthreads/tests/barrier2.c @@ -0,0 +1,55 @@ +/* + * barrier2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +pthread_barrier_t barrier = NULL; + +int +main() +{ + assert(pthread_barrier_init(&barrier, NULL, 1) == 0); + + assert(pthread_barrier_wait(&barrier) == PTHREAD_BARRIER_SERIAL_THREAD); + + assert(pthread_barrier_destroy(&barrier) == 0); + + return 0; +} diff --git a/pthreads/tests/barrier3.c b/pthreads/tests/barrier3.c new file mode 100644 index 000000000..3e4009068 --- /dev/null +++ b/pthreads/tests/barrier3.c @@ -0,0 +1,71 @@ +/* + * barrier3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object with barrier attribute, wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +pthread_barrier_t barrier = NULL; +static int result = 1; + +void * func(void * arg) +{ + return (void *) pthread_barrier_wait(&barrier); +} + +int +main() +{ + pthread_t t; + pthread_barrierattr_t ba; + + assert(pthread_barrierattr_init(&ba) == 0); + assert(pthread_barrierattr_setpshared(&ba, PTHREAD_PROCESS_PRIVATE) == 0); + assert(pthread_barrier_init(&barrier, &ba, 1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + + assert(result == PTHREAD_BARRIER_SERIAL_THREAD); + + assert(pthread_barrier_destroy(&barrier) == 0); + assert(pthread_barrierattr_destroy(&ba) == 0); + + return 0; +} diff --git a/pthreads/tests/barrier4.c b/pthreads/tests/barrier4.c new file mode 100644 index 000000000..042992dfd --- /dev/null +++ b/pthreads/tests/barrier4.c @@ -0,0 +1,110 @@ +/* + * barrier4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, multiple wait on it, + * and then destroy it. + * + */ + +#include "test.h" + +enum { + NUMTHREADS = 16 +}; + +pthread_barrier_t barrier = NULL; +pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; +static int serialThreadCount = 0; +static int otherThreadCount = 0; + +void * +func(void * arg) +{ + int result = pthread_barrier_wait(&barrier); + + assert(pthread_mutex_lock(&mx) == 0); + + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + serialThreadCount++; + } + else if (0 == result) + { + otherThreadCount++; + } + else + { + printf("Barrier wait failed: error = %s\n", error_string[result]); + fflush(stdout); + return NULL; + } + assert(pthread_mutex_unlock(&mx) == 0); + + return NULL; +} + +int +main() +{ + int i, j; + pthread_t t[NUMTHREADS + 1]; + + for (j = 1; j <= NUMTHREADS; j++) + { + printf("Barrier height = %d\n", j); + + serialThreadCount = 0; + + assert(pthread_barrier_init(&barrier, NULL, j) == 0); + + for (i = 1; i <= j; i++) + { + assert(pthread_create(&t[i], NULL, func, NULL) == 0); + } + + for (i = 1; i <= j; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + assert(serialThreadCount == 1); + + assert(pthread_barrier_destroy(&barrier) == 0); + } + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} diff --git a/pthreads/tests/barrier5.c b/pthreads/tests/barrier5.c new file mode 100644 index 000000000..5b598c9d9 --- /dev/null +++ b/pthreads/tests/barrier5.c @@ -0,0 +1,128 @@ +/* + * barrier5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a single barrier object, set up a sequence of + * barrier points to prove lockstepness, and then destroy it. + * + */ + +#include "test.h" + +enum { + NUMTHREADS = 16, + BARRIERS = 10000 +}; + +pthread_barrier_t barrier = NULL; +pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; + +int barrierReleases[BARRIERS + 1]; + +void * +func(void * barrierHeight) +{ + int i; + int result; + int serialThreads = 0; + + for (i = 1; i < BARRIERS; i++) + { + result = pthread_barrier_wait(&barrier); + + assert(pthread_mutex_lock(&mx) == 0); + barrierReleases[i]++; + assert(pthread_mutex_unlock(&mx) == 0); + /* + * Confirm the correct number of releases from the previous + * barrier. We can't do the current barrier yet because there may + * still be threads waking up. + */ + if (result == PTHREAD_BARRIER_SERIAL_THREAD) + { + serialThreads++; + assert(barrierReleases[i - 1] == (int) barrierHeight); + barrierReleases[i + 1] = 0; + } + else if (result != 0) + { + printf("Barrier failed: result = %s\n", error_string[result]); + fflush(stdout); + return NULL; + } + } + + return (void *) serialThreads; +} + +int +main() +{ + int i, j; + int result; + int serialThreadsTotal; + pthread_t t[NUMTHREADS + 1]; + + for (j = 1; j <= NUMTHREADS; j++) + { + printf("Barrier height = %d\n", j); + + barrierReleases[0] = j; + barrierReleases[1] = 0; + + assert(pthread_barrier_init(&barrier, NULL, j) == 0); + + for (i = 1; i <= j; i++) + { + assert(pthread_create(&t[i], NULL, func, (void *) j) == 0); + } + + serialThreadsTotal = 0; + for (i = 1; i <= j; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + serialThreadsTotal += result; + } + + assert(serialThreadsTotal == BARRIERS - 1); + assert(barrierReleases[BARRIERS - 1] == j); + assert(barrierReleases[BARRIERS] == 0); + + assert(pthread_barrier_destroy(&barrier) == 0); + } + + assert(pthread_mutex_destroy(&mx) == 0); + + return 0; +} diff --git a/pthreads/tests/benchlib.c b/pthreads/tests/benchlib.c new file mode 100644 index 000000000..bf60ae515 --- /dev/null +++ b/pthreads/tests/benchlib.c @@ -0,0 +1,363 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * 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 "../config.h" + +#include "pthread.h" +#include "sched.h" +#include "semaphore.h" +#include <windows.h> +#include <stdio.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +int old_mutex_use = OLD_WIN32CS; + +BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL; +HINSTANCE ptw32_h_kernel32; + +void +dummy_call(int * a) +{ +} + +void +interlocked_inc_with_conditionals(int * a) +{ + if (a != NULL) + if (InterlockedIncrement((long *) a) == -1) + { + *a = 0; + } +} + +void +interlocked_dec_with_conditionals(int * a) +{ + if (a != NULL) + if (InterlockedDecrement((long *) a) == -1) + { + *a = 0; + } +} + +int +old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr) +{ + int result = 0; + old_mutex_t mx; + + if (mutex == NULL) + { + return EINVAL; + } + + mx = (old_mutex_t) calloc(1, sizeof(*mx)); + + if (mx == NULL) + { + result = ENOMEM; + goto FAIL0; + } + + mx->mutex = 0; + + if (attr != NULL + && *attr != NULL + && (*attr)->pshared == PTHREAD_PROCESS_SHARED + ) + { + result = ENOSYS; + } + else + { + CRITICAL_SECTION cs; + + /* + * Load KERNEL32 and try to get address of TryEnterCriticalSection + */ + ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); + ptw32_try_enter_critical_section = (BOOL (WINAPI *)(LPCRITICAL_SECTION)) + +#if defined(NEED_UNICODE_CONSTS) + GetProcAddress(ptw32_h_kernel32, + (const TCHAR *)TEXT("TryEnterCriticalSection")); +#else + GetProcAddress(ptw32_h_kernel32, + (LPCSTR) "TryEnterCriticalSection"); +#endif + + if (ptw32_try_enter_critical_section != NULL) + { + InitializeCriticalSection(&cs); + if ((*ptw32_try_enter_critical_section)(&cs)) + { + LeaveCriticalSection(&cs); + } + else + { + /* + * Not really supported (Win98?). + */ + ptw32_try_enter_critical_section = NULL; + } + DeleteCriticalSection(&cs); + } + + if (ptw32_try_enter_critical_section == NULL) + { + (void) FreeLibrary(ptw32_h_kernel32); + ptw32_h_kernel32 = 0; + } + + if (old_mutex_use == OLD_WIN32CS) + { + InitializeCriticalSection(&mx->cs); + } + else if (old_mutex_use == OLD_WIN32MUTEX) + { + mx->mutex = CreateMutex (NULL, + FALSE, + NULL); + + if (mx->mutex == 0) + { + result = EAGAIN; + } + } + else + { + result = EINVAL; + } + } + + if (result != 0 && mx != NULL) + { + free(mx); + mx = NULL; + } + +FAIL0: + *mutex = mx; + + return(result); +} + + +int +old_mutex_lock(old_mutex_t *mutex) +{ + int result = 0; + old_mutex_t mx; + + if (mutex == NULL || *mutex == NULL) + { + return EINVAL; + } + + if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT) + { + /* + * Don't use initialisers when benchtesting. + */ + result = EINVAL; + } + + mx = *mutex; + + if (result == 0) + { + if (mx->mutex == 0) + { + EnterCriticalSection(&mx->cs); + } + else + { + result = (WaitForSingleObject(mx->mutex, INFINITE) + == WAIT_OBJECT_0) + ? 0 + : EINVAL; + } + } + + return(result); +} + +int +old_mutex_unlock(old_mutex_t *mutex) +{ + int result = 0; + old_mutex_t mx; + + if (mutex == NULL || *mutex == NULL) + { + return EINVAL; + } + + mx = *mutex; + + if (mx != (old_mutex_t) PTW32_OBJECT_AUTO_INIT) + { + if (mx->mutex == 0) + { + LeaveCriticalSection(&mx->cs); + } + else + { + result = (ReleaseMutex (mx->mutex) ? 0 : EINVAL); + } + } + else + { + result = EINVAL; + } + + return(result); +} + + +int +old_mutex_trylock(old_mutex_t *mutex) +{ + int result = 0; + old_mutex_t mx; + + if (mutex == NULL || *mutex == NULL) + { + return EINVAL; + } + + if (*mutex == (old_mutex_t) PTW32_OBJECT_AUTO_INIT) + { + /* + * Don't use initialisers when benchtesting. + */ + result = EINVAL; + } + + mx = *mutex; + + if (result == 0) + { + if (mx->mutex == 0) + { + if (ptw32_try_enter_critical_section == NULL) + { + result = 0; + } + else if ((*ptw32_try_enter_critical_section)(&mx->cs) != TRUE) + { + result = EBUSY; + } + } + else + { + DWORD status; + + status = WaitForSingleObject (mx->mutex, 0); + + if (status != WAIT_OBJECT_0) + { + result = ((status == WAIT_TIMEOUT) + ? EBUSY + : EINVAL); + } + } + } + + return(result); +} + + +int +old_mutex_destroy(old_mutex_t *mutex) +{ + int result = 0; + old_mutex_t mx; + + if (mutex == NULL + || *mutex == NULL) + { + return EINVAL; + } + + if (*mutex != (old_mutex_t) PTW32_OBJECT_AUTO_INIT) + { + mx = *mutex; + + if ((result = old_mutex_trylock(&mx)) == 0) + { + *mutex = NULL; + + (void) old_mutex_unlock(&mx); + + if (mx->mutex == 0) + { + DeleteCriticalSection(&mx->cs); + } + else + { + result = (CloseHandle (mx->mutex) ? 0 : EINVAL); + } + + if (result == 0) + { + mx->mutex = 0; + free(mx); + } + else + { + *mutex = mx; + } + } + } + else + { + result = EINVAL; + } + + if (ptw32_try_enter_critical_section != NULL) + { + (void) FreeLibrary(ptw32_h_kernel32); + ptw32_h_kernel32 = 0; + } + + return(result); +} + +/****************************************************************************************/ diff --git a/pthreads/tests/benchtest.h b/pthreads/tests/benchtest.h new file mode 100644 index 000000000..809057810 --- /dev/null +++ b/pthreads/tests/benchtest.h @@ -0,0 +1,70 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * 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 "../config.h" + +enum { + OLD_WIN32CS, + OLD_WIN32MUTEX +}; + +extern int old_mutex_use; + +struct old_mutex_t_ { + HANDLE mutex; + CRITICAL_SECTION cs; +}; + +typedef struct old_mutex_t_ * old_mutex_t; + +struct old_mutexattr_t_ { + int pshared; +}; + +typedef struct old_mutexattr_t_ * old_mutexattr_t; + +extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION); +extern HINSTANCE ptw32_h_kernel32; + +#define PTW32_OBJECT_AUTO_INIT ((void *) -1) + +void dummy_call(int * a); +void interlocked_inc_with_conditionals(int *a); +void interlocked_dec_with_conditionals(int *a); +int old_mutex_init(old_mutex_t *mutex, const old_mutexattr_t *attr); +int old_mutex_lock(old_mutex_t *mutex); +int old_mutex_unlock(old_mutex_t *mutex); +int old_mutex_trylock(old_mutex_t *mutex); +int old_mutex_destroy(old_mutex_t *mutex); +/****************************************************************************************/ diff --git a/pthreads/tests/benchtest1.c b/pthreads/tests/benchtest1.c new file mode 100644 index 000000000..116dad05e --- /dev/null +++ b/pthreads/tests/benchtest1.c @@ -0,0 +1,249 @@ +/* + * benchtest1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over lock/unlock for each mutex type. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 10000000L + +pthread_mutex_t mx; +pthread_mutexattr_t ma; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; +int one = 1; +int zero = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + assert(pthread_mutexattr_settype(&ma, mType) == 0); +#endif + assert(pthread_mutex_init(&mx, &ma) == 0); + + TESTSTART + assert(pthread_mutex_lock(&mx) == zero); + assert(pthread_mutex_unlock(&mx) == zero); + TESTSTOP + + assert(pthread_mutex_destroy(&mx) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + int i = 0; + CRITICAL_SECTION cs; + old_mutex_t ox; + pthread_mutexattr_init(&ma); + + printf( "=============================================================================\n"); + printf( "\nLock plus unlock on an unlocked mutex.\n%ld iterations\n\n", + ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "-----------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == one); + assert(1 == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + TESTSTART + assert((dummy_call(&i), 1) == one); + assert((dummy_call(&i), 1) == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Dummy call x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + TESTSTART + assert((interlocked_inc_with_conditionals(&i), 1) == one); + assert((interlocked_dec_with_conditionals(&i), 1) == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Dummy call -> Interlocked with cond x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + TESTSTART + assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one); + assert((InterlockedDecrement((LPLONG)&i), 1) == (LONG)one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "InterlockedOp x 2", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + InitializeCriticalSection(&cs); + + TESTSTART + assert((EnterCriticalSection(&cs), 1) == one); + assert((LeaveCriticalSection(&cs), 1) == one); + TESTSTOP + + DeleteCriticalSection(&cs); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Simple Critical Section", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + old_mutex_use = OLD_WIN32CS; + assert(old_mutex_init(&ox, NULL) == 0); + + TESTSTART + assert(old_mutex_lock(&ox) == zero); + assert(old_mutex_unlock(&ox) == zero); + TESTSTOP + + assert(old_mutex_destroy(&ox) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Critical Section (WNT)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + + old_mutex_use = OLD_WIN32MUTEX; + assert(old_mutex_init(&ox, NULL) == 0); + + TESTSTART + assert(old_mutex_lock(&ox) == zero); + assert(old_mutex_unlock(&ox) == zero); + TESTSTOP + + assert(old_mutex_destroy(&ox) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Win32 Mutex (W9x)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + one = i; /* Dummy assignment to avoid 'variable unused' warning */ + return 0; +} diff --git a/pthreads/tests/benchtest2.c b/pthreads/tests/benchtest2.c new file mode 100644 index 000000000..d92bb3c1a --- /dev/null +++ b/pthreads/tests/benchtest2.c @@ -0,0 +1,311 @@ +/* + * benchtest1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Two threads iterate over lock/unlock for each mutex type. + * The two threads are forced into lock-step using two mutexes, + * forcing the threads to block on each lock operation. The + * time measured is therefore the worst case senario. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 100000L + +pthread_mutex_t gate1, gate2; +old_mutex_t ox1, ox2; +CRITICAL_SECTION cs1, cs2; +pthread_mutexattr_t ma; +long durationMilliSecs; +long overHeadMilliSecs = 0; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +pthread_t worker; +int running = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void * +overheadThread(void * arg) +{ + do + { + sched_yield(); + } + while (running); + + return NULL; +} + + +void * +oldThread(void * arg) +{ + do + { + (void) old_mutex_lock(&ox1); + (void) old_mutex_lock(&ox2); + (void) old_mutex_unlock(&ox1); + sched_yield(); + (void) old_mutex_unlock(&ox2); + } + while (running); + + return NULL; +} + +void * +workerThread(void * arg) +{ + do + { + (void) pthread_mutex_lock(&gate1); + (void) pthread_mutex_lock(&gate2); + (void) pthread_mutex_unlock(&gate1); + sched_yield(); + (void) pthread_mutex_unlock(&gate2); + } + while (running); + + return NULL; +} + +void * +CSThread(void * arg) +{ + do + { + EnterCriticalSection(&cs1); + EnterCriticalSection(&cs2); + LeaveCriticalSection(&cs1); + sched_yield(); + LeaveCriticalSection(&cs2); + } + while (running); + + return NULL; +} + +void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + assert(pthread_mutexattr_settype(&ma, mType) == 0); +#endif + assert(pthread_mutex_init(&gate1, &ma) == 0); + assert(pthread_mutex_init(&gate2, &ma) == 0); + assert(pthread_mutex_lock(&gate1) == 0); + assert(pthread_mutex_lock(&gate2) == 0); + running = 1; + assert(pthread_create(&worker, NULL, workerThread, NULL) == 0); + TESTSTART + (void) pthread_mutex_unlock(&gate1); + sched_yield(); + (void) pthread_mutex_unlock(&gate2); + (void) pthread_mutex_lock(&gate1); + (void) pthread_mutex_lock(&gate2); + TESTSTOP + running = 0; + assert(pthread_mutex_unlock(&gate2) == 0); + assert(pthread_mutex_unlock(&gate1) == 0); + assert(pthread_join(worker, NULL) == 0); + assert(pthread_mutex_destroy(&gate2) == 0); + assert(pthread_mutex_destroy(&gate1) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS / 4 /* Four locks/unlocks per iteration */); +} + + +int +main (int argc, char *argv[]) +{ + assert(pthread_mutexattr_init(&ma) == 0); + + printf( "=============================================================================\n"); + printf( "\nLock plus unlock on a locked mutex.\n"); + printf("%ld iterations, four locks/unlocks per iteration.\n\n", ITERATIONS); + + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "-----------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + running = 1; + assert(pthread_create(&worker, NULL, overheadThread, NULL) == 0); + TESTSTART + sched_yield(); + sched_yield(); + TESTSTOP + running = 0; + assert(pthread_join(worker, NULL) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + InitializeCriticalSection(&cs1); + InitializeCriticalSection(&cs2); + EnterCriticalSection(&cs1); + EnterCriticalSection(&cs2); + running = 1; + assert(pthread_create(&worker, NULL, CSThread, NULL) == 0); + TESTSTART + LeaveCriticalSection(&cs1); + sched_yield(); + LeaveCriticalSection(&cs2); + EnterCriticalSection(&cs1); + EnterCriticalSection(&cs2); + TESTSTOP + running = 0; + LeaveCriticalSection(&cs2); + LeaveCriticalSection(&cs1); + assert(pthread_join(worker, NULL) == 0); + DeleteCriticalSection(&cs2); + DeleteCriticalSection(&cs1); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Simple Critical Section", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS / 4 ); + + + old_mutex_use = OLD_WIN32CS; + assert(old_mutex_init(&ox1, NULL) == 0); + assert(old_mutex_init(&ox2, NULL) == 0); + assert(old_mutex_lock(&ox1) == 0); + assert(old_mutex_lock(&ox2) == 0); + running = 1; + assert(pthread_create(&worker, NULL, oldThread, NULL) == 0); + TESTSTART + (void) old_mutex_unlock(&ox1); + sched_yield(); + (void) old_mutex_unlock(&ox2); + (void) old_mutex_lock(&ox1); + (void) old_mutex_lock(&ox2); + TESTSTOP + running = 0; + assert(old_mutex_unlock(&ox1) == 0); + assert(old_mutex_unlock(&ox2) == 0); + assert(pthread_join(worker, NULL) == 0); + assert(old_mutex_destroy(&ox2) == 0); + assert(old_mutex_destroy(&ox1) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Critical Section (WNT)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS / 4); + + + old_mutex_use = OLD_WIN32MUTEX; + assert(old_mutex_init(&ox1, NULL) == 0); + assert(old_mutex_init(&ox2, NULL) == 0); + assert(old_mutex_lock(&ox1) == 0); + assert(old_mutex_lock(&ox2) == 0); + running = 1; + assert(pthread_create(&worker, NULL, oldThread, NULL) == 0); + TESTSTART + (void) old_mutex_unlock(&ox1); + sched_yield(); + (void) old_mutex_unlock(&ox2); + (void) old_mutex_lock(&ox1); + (void) old_mutex_lock(&ox2); + TESTSTOP + running = 0; + assert(old_mutex_unlock(&ox1) == 0); + assert(old_mutex_unlock(&ox2) == 0); + assert(pthread_join(worker, NULL) == 0); + assert(old_mutex_destroy(&ox2) == 0); + assert(old_mutex_destroy(&ox1) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Win32 Mutex (W9x)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS / 4); + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Blocking locks", 0); +#endif + + printf( "=============================================================================\n"); + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/pthreads/tests/benchtest3.c b/pthreads/tests/benchtest3.c new file mode 100644 index 000000000..023460dfb --- /dev/null +++ b/pthreads/tests/benchtest3.c @@ -0,0 +1,201 @@ +/* + * benchtest3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over a trylock on a locked mutex for each mutex type. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 10000000L + +pthread_mutex_t mx; +old_mutex_t ox; +pthread_mutexattr_t ma; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void * +trylockThread (void * arg) +{ + TESTSTART + (void) pthread_mutex_trylock(&mx); + TESTSTOP + + return NULL; +} + + +void * +oldTrylockThread (void * arg) +{ + TESTSTART + (void) old_mutex_trylock(&ox); + TESTSTOP + + return NULL; +} + + +void +runTest (char * testNameString, int mType) +{ + pthread_t t; + +#ifdef PTW32_MUTEX_TYPES + (void) pthread_mutexattr_settype(&ma, mType); +#endif + assert(pthread_mutex_init(&mx, &ma) == 0); + assert(pthread_mutex_lock(&mx) == 0); + assert(pthread_create(&t, NULL, trylockThread, 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mx) == 0); + assert(pthread_mutex_destroy(&mx) == 0); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + pthread_t t; + + assert(pthread_mutexattr_init(&ma) == 0); + + printf( "=============================================================================\n"); + printf( "\nTrylock on a locked mutex.\n"); + printf( "%ld iterations.\n\n", ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "-----------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + old_mutex_use = OLD_WIN32CS; + assert(old_mutex_init(&ox, NULL) == 0); + assert(old_mutex_lock(&ox) == 0); + assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(old_mutex_unlock(&ox) == 0); + assert(old_mutex_destroy(&ox) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Critical Section (WNT)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + old_mutex_use = OLD_WIN32MUTEX; + assert(old_mutex_init(&ox, NULL) == 0); + assert(old_mutex_lock(&ox) == 0); + assert(pthread_create(&t, NULL, oldTrylockThread, 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(old_mutex_unlock(&ox) == 0); + assert(old_mutex_destroy(&ox) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Win32 Mutex (W9x)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/pthreads/tests/benchtest4.c b/pthreads/tests/benchtest4.c new file mode 100644 index 000000000..772d10047 --- /dev/null +++ b/pthreads/tests/benchtest4.c @@ -0,0 +1,182 @@ +/* + * benchtest4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Mutex + * Single thread iteration over trylock/unlock for each mutex type. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define PTW32_MUTEX_TYPES +#define ITERATIONS 10000000L + +pthread_mutex_t mx; +old_mutex_t ox; +pthread_mutexattr_t ma; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void +oldRunTest (char * testNameString, int mType) +{ +} + + +void +runTest (char * testNameString, int mType) +{ +#ifdef PTW32_MUTEX_TYPES + pthread_mutexattr_settype(&ma, mType); +#endif + pthread_mutex_init(&mx, &ma); + + TESTSTART + (void) pthread_mutex_trylock(&mx); + (void) pthread_mutex_unlock(&mx); + TESTSTOP + + pthread_mutex_destroy(&mx); + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + pthread_mutexattr_init(&ma); + + printf( "=============================================================================\n"); + printf( "Trylock plus unlock on an unlocked mutex.\n"); + printf( "%ld iterations.\n\n", ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "-----------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + old_mutex_use = OLD_WIN32CS; + assert(old_mutex_init(&ox, NULL) == 0); + TESTSTART + (void) old_mutex_trylock(&ox); + (void) old_mutex_unlock(&ox); + TESTSTOP + assert(old_mutex_destroy(&ox) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Critical Section (WNT)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + old_mutex_use = OLD_WIN32MUTEX; + assert(old_mutex_init(&ox, NULL) == 0); + TESTSTART + (void) old_mutex_trylock(&ox); + (void) old_mutex_unlock(&ox); + TESTSTOP + assert(old_mutex_destroy(&ox) == 0); + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + printf( "%-45s %15ld %15.3f\n", + "Old PT Mutex using a Win32 Mutex (W9x)", + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); + + printf( ".............................................................................\n"); + + /* + * Now we can start the actual tests + */ +#ifdef PTW32_MUTEX_TYPES + runTest("PTHREAD_MUTEX_DEFAULT (W9x,WNT)", PTHREAD_MUTEX_DEFAULT); + + runTest("PTHREAD_MUTEX_NORMAL (W9x,WNT)", PTHREAD_MUTEX_NORMAL); + + runTest("PTHREAD_MUTEX_ERRORCHECK (W9x,WNT)", PTHREAD_MUTEX_ERRORCHECK); + + runTest("PTHREAD_MUTEX_RECURSIVE (W9x,WNT)", PTHREAD_MUTEX_RECURSIVE); +#else + runTest("Non-blocking lock", 0); +#endif + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + pthread_mutexattr_destroy(&ma); + + return 0; +} diff --git a/pthreads/tests/benchtest5.c b/pthreads/tests/benchtest5.c new file mode 100644 index 000000000..7700fdeaa --- /dev/null +++ b/pthreads/tests/benchtest5.c @@ -0,0 +1,159 @@ +/* + * benchtest5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Measure time taken to complete an elementary operation. + * + * - Semaphore + * Single thread iteration over post/wait for a semaphore. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "benchtest.h" + +#define ITERATIONS 1000000L + +sem_t sema; +HANDLE w32sema; + +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; +long durationMilliSecs; +long overHeadMilliSecs = 0; +int one = 1; +int zero = 0; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +/* + * Dummy use of j, otherwise the loop may be removed by the optimiser + * when doing the overhead timing with an empty loop. + */ +#define TESTSTART \ + { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + +#define TESTSTOP \ + }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + + +void +reportTest (char * testNameString) +{ + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + + printf( "%-45s %15ld %15.3f\n", + testNameString, + durationMilliSecs, + (float) durationMilliSecs * 1E3 / ITERATIONS); +} + + +int +main (int argc, char *argv[]) +{ + printf( "=============================================================================\n"); + printf( "\nOperations on a semaphore.\n%ld iterations\n\n", + ITERATIONS); + printf( "%-45s %15s %15s\n", + "Test", + "Total(msec)", + "average(usec)"); + printf( "-----------------------------------------------------------------------------\n"); + + /* + * Time the loop overhead so we can subtract it from the actual test times. + */ + + TESTSTART + assert(1 == one); + TESTSTOP + + durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; + overHeadMilliSecs = durationMilliSecs; + + + /* + * Now we can start the actual tests + */ + assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0); + TESTSTART + assert(ReleaseSemaphore(w32sema, 1, NULL) != zero); + TESTSTOP + assert(CloseHandle(w32sema) != 0); + + reportTest("W32 Post with no waiters"); + + + assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0); + TESTSTART + assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0); + TESTSTOP + assert(CloseHandle(w32sema) != 0); + + reportTest("W32 Wait without blocking"); + + + assert(sem_init(&sema, 0, 0) == 0); + TESTSTART + assert(sem_post(&sema) == zero); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("POSIX Post with no waiters"); + + + assert(sem_init(&sema, 0, ITERATIONS) == 0); + TESTSTART + assert(sem_wait(&sema) == zero); + TESTSTOP + assert(sem_destroy(&sema) == 0); + + reportTest("POSIX Wait without blocking"); + + + printf( "=============================================================================\n"); + + /* + * End of tests. + */ + + return 0; +} diff --git a/pthreads/tests/cancel1.c b/pthreads/tests/cancel1.c new file mode 100644 index 000000000..be9b102a5 --- /dev/null +++ b/pthreads/tests/cancel1.c @@ -0,0 +1,179 @@ +/* + * File: cancel1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test setting cancel state and cancel type. + * - + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - pthread_setcancelstate function + * - pthread_setcanceltype function + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - pthread_create, pthread_self work. + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 2 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* ... */ + { + int oldstate; + int oldtype; + + assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0); + assert(oldstate == PTHREAD_CANCEL_ENABLE); /* Check default */ + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + assert(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) == 0); + assert(pthread_setcancelstate(oldstate, &oldstate) == 0); + assert(oldstate == PTHREAD_CANCEL_DISABLE); /* Check setting */ + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype) == 0); + assert(oldtype == PTHREAD_CANCEL_DEFERRED); /* Check default */ + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + assert(pthread_setcanceltype(oldtype, &oldtype) == 0); + assert(oldtype == PTHREAD_CANCEL_ASYNCHRONOUS); /* Check setting */ + } + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print ouput on failure. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + /* ... */ + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel2.c b/pthreads/tests/cancel2.c new file mode 100644 index 000000000..6ef2043e2 --- /dev/null +++ b/pthreads/tests/cancel2.c @@ -0,0 +1,251 @@ +/* + * File: cancel2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test SEH or C++ cancel exception handling within + * application exception blocks. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER; + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + switch (bag->threadnum % 2) + { + case 0: + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + result = 0; + break; + case 1: + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + result = 1; + break; + } + +#if defined(_MSC_VER) && !defined(__cplusplus) + __try +#else + try +#endif + { + /* Wait for go from main */ + assert(pthread_mutex_lock(&waitLock) == 0); + assert(pthread_mutex_unlock(&waitLock) == 0); + sched_yield(); + + for (;;) + { + pthread_testcancel(); + } + } +#if defined(_MSC_VER) && !defined(__cplusplus) + __except(EXCEPTION_EXECUTE_HANDLER) +#else +#if defined(PtW32CatchAll) + PtW32CatchAll +#else + catch(...) +#endif +#endif + { + /* + * Should not get into here. + */ + result += 100; + } + + /* + * Should not get to here either. + */ + result += 1000; + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + assert(pthread_mutex_lock(&waitLock) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + assert(pthread_mutex_unlock(&waitLock) == 0); + + Sleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + fail = (result != (int) PTHREAD_CANCELED); + if (fail) + { + fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n", + i, + threadbag[i].started, + result, + ((result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED"); + } + failed |= fail; + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/cancel3.c b/pthreads/tests/cancel3.c new file mode 100644 index 000000000..1560ccfd2 --- /dev/null +++ b/pthreads/tests/cancel3.c @@ -0,0 +1,201 @@ +/* + * File: cancel3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test asynchronous cancelation (alertable or non-alertable). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - Async cancel if thread is not blocked (i.e. voluntarily resumes if blocked). + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join. + * - quserex.dll and alertdrv.sys are not available. + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ +{ + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread (void *arg) +{ + int result = ((int) PTHREAD_CANCELED + 1); + bag_t *bag = (bag_t *) arg; + + assert (bag == &threadbag[bag->threadnum]); + assert (bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + Sleep (100); + + return (void *) result; +} + +int +main () +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert ((t[0] = pthread_self ()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) + == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep (500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert (pthread_cancel (t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep (NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf (stderr, "Thread %d: started %d\n", i, + threadbag[i].started); + } + } + + assert (!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert (pthread_join (t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf (stderr, "Thread %d: started %d: count %d\n", + i, threadbag[i].started, threadbag[i].count); + } + failed = (failed || fail); + } + + assert (!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel4.c b/pthreads/tests/cancel4.c new file mode 100644 index 000000000..6d6d3dc7b --- /dev/null +++ b/pthreads/tests/cancel4.c @@ -0,0 +1,203 @@ +/* + * File: cancel4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cancelation does not occur in deferred + * cancelation threads with no cancelation points. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - pthread_create + * pthread_self + * pthread_cancel + * pthread_join + * pthread_setcancelstate + * pthread_setcanceltype + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + + /* + * We wait up to 2 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 20; bag->count++) + Sleep(100); + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED indicates that async + * cancelation occurred. + */ + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result == (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel5.c b/pthreads/tests/cancel5.c new file mode 100644 index 000000000..dd6cb8bae --- /dev/null +++ b/pthreads/tests/cancel5.c @@ -0,0 +1,199 @@ +/* + * File: cancel5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_cancel from the main thread + * without calling pthread_self() in main. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum +{ + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ +{ + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread (void *arg) +{ + int result = ((int) PTHREAD_CANCELED + 1); + bag_t *bag = (bag_t *) arg; + + assert (bag == &threadbag[bag->threadnum]); + assert (bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert (pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + Sleep (100); + + return (void *) result; +} + +int +main () +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert (pthread_create (&t[i], NULL, mythread, (void *) &threadbag[i]) + == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep (500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert (pthread_cancel (t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep (NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf (stderr, "Thread %d: started %d\n", i, + threadbag[i].started); + } + } + + assert (!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert (pthread_join (t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf (stderr, "Thread %d: started %d: count %d\n", + i, threadbag[i].started, threadbag[i].count); + } + failed = (failed || fail); + } + + assert (!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel6a.c b/pthreads/tests/cancel6a.c new file mode 100644 index 000000000..644cd4a53 --- /dev/null +++ b/pthreads/tests/cancel6a.c @@ -0,0 +1,191 @@ +/* + * File: cancel6a.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test double cancelation - asynchronous. + * Second attempt should fail (ESRCH). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + Sleep(100); + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + assert(pthread_cancel(t[i]) == ESRCH); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* + * The thread does not contain any cancelation points, so + * a return value of PTHREAD_CANCELED confirms that async + * cancelation succeeded. + */ + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel6d.c b/pthreads/tests/cancel6d.c new file mode 100644 index 000000000..d0ad7ac2c --- /dev/null +++ b/pthreads/tests/cancel6d.c @@ -0,0 +1,190 @@ +/* + * File: cancel6d.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test double cancelation - deferred. + * Second attempt should succeed (unless the canceled thread has started + * cancelation already - not tested here). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +void * +mythread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0); + + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + { + Sleep(100); + pthread_testcancel(); + } + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cancel7.c b/pthreads/tests/cancel7.c new file mode 100644 index 000000000..9fb2e6166 --- /dev/null +++ b/pthreads/tests/cancel7.c @@ -0,0 +1,216 @@ +/* + * File: cancel7.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test canceling a Win32 thread having created an + * implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - Validate return value and that POSIX handle is created and destroyed. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#ifndef _UWIN +#include <process.h> +#endif + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + pthread_t self; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +unsigned __stdcall +#else +void +#endif +Win32thread(void * arg) +{ + int i; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + assert((bag->self = pthread_self()).p != NULL); + assert(pthread_kill(bag->self, 0) == 0); + + for (i = 0; i < 100; i++) + { + Sleep(100); + pthread_testcancel(); + } + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + HANDLE h[NUMTHREADS + 1]; + unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */ + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr); +#else + h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]); +#endif + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + /* + * Cancel all threads. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_kill(threadbag[i].self, 0) == 0); + assert(pthread_cancel(threadbag[i].self) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE); +#else + /* + * Can't get a result code. + */ + result = (int) PTHREAD_CANCELED; +#endif + + assert(threadbag[i].self.p != NULL); + assert(pthread_kill(threadbag[i].self, 0) == ESRCH); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/pthreads/tests/cancel8.c b/pthreads/tests/cancel8.c new file mode 100644 index 000000000..69eafe98e --- /dev/null +++ b/pthreads/tests/cancel8.c @@ -0,0 +1,217 @@ +/* + * File: cancel8.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cancelling a blocked Win32 thread having created an + * implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - Validate return value and that POSIX handle is created and destroyed. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#ifndef _UWIN +#include <process.h> +#endif + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + pthread_t self; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +pthread_cond_t CV = PTHREAD_COND_INITIALIZER; +pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +unsigned __stdcall +#else +void +#endif +Win32thread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + assert((bag->self = pthread_self()).p != NULL); + assert(pthread_kill(bag->self, 0) == 0); + + assert(pthread_mutex_lock(&CVLock) == 0); + pthread_cleanup_push(pthread_mutex_unlock, &CVLock); + pthread_cond_wait(&CV, &CVLock); + pthread_cleanup_pop(1); + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + HANDLE h[NUMTHREADS + 1]; + unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */ + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr); +#else + h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]); +#endif + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + /* + * Cancel all threads. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_kill(threadbag[i].self, 0) == 0); + assert(pthread_cancel(threadbag[i].self) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE); +#else + /* + * Can't get a result code. + */ + result = (int) PTHREAD_CANCELED; +#endif + + assert(threadbag[i].self.p != NULL); + assert(pthread_kill(threadbag[i].self, 0) == ESRCH); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/pthreads/tests/cancel9.c b/pthreads/tests/cancel9.c new file mode 100644 index 000000000..b0091614a --- /dev/null +++ b/pthreads/tests/cancel9.c @@ -0,0 +1,202 @@ +/* + * File: cancel9.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test true asynchronous cancelation with Alert driver. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - Cancel threads, including those blocked on system recources + * such as network I/O. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <windows.h> + + +void * +test_udp (void *arg) +{ + struct sockaddr_in serverAddress; + struct sockaddr_in clientAddress; + SOCKET UDPSocket; + int addr_len; + int nbyte, bytes; + char buffer[4096]; + WORD wsaVersion = MAKEWORD (2, 2); + WSADATA wsaData; + + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + if (WSAStartup (wsaVersion, &wsaData) != 0) + { + return NULL; + } + + UDPSocket = socket (AF_INET, SOCK_DGRAM, 0); + if ((int)UDPSocket == -1) + { + printf ("Server: socket ERROR \n"); + exit (-1); + } + + serverAddress.sin_family = AF_INET; + serverAddress.sin_addr.s_addr = INADDR_ANY; + serverAddress.sin_port = htons (9003); + + if (bind + (UDPSocket, (struct sockaddr *) &serverAddress, + sizeof (struct sockaddr_in))) + { + printf ("Server: ERROR can't bind UDPSocket"); + exit (-1); + } + + addr_len = sizeof (struct sockaddr); + + nbyte = 512; + + bytes = + recvfrom (UDPSocket, (char *) buffer, nbyte, 0, + (struct sockaddr *) &clientAddress, &addr_len); + + closesocket (UDPSocket); + WSACleanup (); + + return NULL; +} + + +void * +test_sleep (void *arg) +{ + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + Sleep (1000); + return NULL; + +} + +void * +test_wait (void *arg) +{ + HANDLE hEvent; + DWORD dwEvent; + + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + + dwEvent = WaitForSingleObject (hEvent, 1000); /* WAIT_IO_COMPLETION */ + + return NULL; +} + + +int +main () +{ + pthread_t t; + void *result; + + if (pthread_win32_test_features_np (PTW32_ALERTABLE_ASYNC_CANCEL)) + { + printf ("Cancel sleeping thread.\n"); + assert (pthread_create (&t, NULL, test_sleep, NULL) == 0); + /* Sleep for a while; then cancel */ + Sleep (100); + assert (pthread_cancel (t) == 0); + assert (pthread_join (t, &result) == 0); + assert (result == PTHREAD_CANCELED && "test_sleep" != NULL); + + printf ("Cancel waiting thread.\n"); + assert (pthread_create (&t, NULL, test_wait, NULL) == 0); + /* Sleep for a while; then cancel. */ + Sleep (100); + assert (pthread_cancel (t) == 0); + assert (pthread_join (t, &result) == 0); + assert (result == PTHREAD_CANCELED && "test_wait"); + + printf ("Cancel blocked thread (blocked on network I/O).\n"); + assert (pthread_create (&t, NULL, test_udp, NULL) == 0); + /* Sleep for a while; then cancel. */ + Sleep (100); + assert (pthread_cancel (t) == 0); + assert (pthread_join (t, &result) == 0); + assert (result == PTHREAD_CANCELED && "test_udp" != NULL); + } + else + { + printf ("Alertable async cancel not available.\n"); + } + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/cleanup0.c b/pthreads/tests/cleanup0.c new file mode 100644 index 000000000..77626eb66 --- /dev/null +++ b/pthreads/tests/cleanup0.c @@ -0,0 +1,229 @@ +/* + * File: cleanup1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t pop_count = {0, {0}}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + EnterCriticalSection(&sI->cs); + sI->i++; + LeaveCriticalSection(&sI->cs); +} + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + Sleep(100); + + pthread_cleanup_pop(1); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + InitializeCriticalSection(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result == (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: result %d\n", + i, + threadbag[i].started, + result); + fflush(stderr); + } + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + DeleteCriticalSection(&pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/cleanup1.c b/pthreads/tests/cleanup1.c new file mode 100644 index 000000000..385aed959 --- /dev/null +++ b/pthreads/tests/cleanup1.c @@ -0,0 +1,242 @@ +/* + * File: cleanup1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t pop_count = {0, {0}}; + +static void +#ifdef __CLEANUP_C +__cdecl +#endif +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + EnterCriticalSection(&sI->cs); + sI->i++; + LeaveCriticalSection(&sI->cs); +} + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Set to known state and type */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + /* + * We don't have true async cancelation - it relies on the thread + * at least re-entering the run state at some point. + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (bag->count = 0; bag->count < 100; bag->count++) + Sleep(100); + + pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + InitializeCriticalSection(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_cancel(t[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != (int) PTHREAD_CANCELED); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: result %d\n", + i, + threadbag[i].started, + result); + } + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + DeleteCriticalSection(&pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/cleanup2.c b/pthreads/tests/cleanup2.c new file mode 100644 index 000000000..4c639181b --- /dev/null +++ b/pthreads/tests/cleanup2.c @@ -0,0 +1,217 @@ +/* + * File: cleanup2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler executes (when thread is not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t pop_count = {0, {0}}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + EnterCriticalSection(&sI->cs); + sI->i++; + LeaveCriticalSection(&sI->cs); +} + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + sched_yield(); + + pthread_cleanup_pop(1); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + InitializeCriticalSection(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != 0); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: result: %d\n", + i, + threadbag[i].started, + result); + } + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == NUMTHREADS); + + DeleteCriticalSection(&pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/cleanup3.c b/pthreads/tests/cleanup3.c new file mode 100644 index 000000000..b595ab43c --- /dev/null +++ b/pthreads/tests/cleanup3.c @@ -0,0 +1,222 @@ +/* + * File: cleanup3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test cleanup handler does not execute (when thread is + * not canceled). + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 10 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t pop_count = {0, {0}}; + +static void +increment_pop_count(void * arg) +{ + sharedInt_t * sI = (sharedInt_t *) arg; + + EnterCriticalSection(&sI->cs); + sI->i++; + LeaveCriticalSection(&sI->cs); +} + +void * +mythread(void * arg) +{ + int result = 0; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(increment_pop_count, (void *) &pop_count); + + sched_yield(); + + EnterCriticalSection(&pop_count.cs); + pop_count.i--; + LeaveCriticalSection(&pop_count.cs); + + pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + InitializeCriticalSection(&pop_count.cs); + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + assert(pthread_join(t[i], (void **) &result) == 0); + + fail = (result != 0); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: result: %d\n", + i, + threadbag[i].started, + result); + } + failed = (failed || fail); + } + + assert(!failed); + + assert(pop_count.i == -(NUMTHREADS)); + + DeleteCriticalSection(&pop_count.cs); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +int +main() +{ + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/condvar1.c b/pthreads/tests/condvar1.c new file mode 100644 index 000000000..380ab1aff --- /dev/null +++ b/pthreads/tests/condvar1.c @@ -0,0 +1,97 @@ +/* + * File: condvar1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test initialisation and destruction of a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_init returns 0, and + * - pthread_cond_destroy returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_init returns non-zero, or + * - pthread_cond_destroy returns non-zero. + * - Process returns non-zero exit status. + */ + +#include "test.h" + +static pthread_cond_t cv = NULL; + +int +main() +{ + assert(cv == NULL); + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(cv != NULL); + + assert(pthread_cond_destroy(&cv) == 0); + + assert(cv == NULL); + + return 0; +} diff --git a/pthreads/tests/condvar1_1.c b/pthreads/tests/condvar1_1.c new file mode 100644 index 000000000..a05e113b9 --- /dev/null +++ b/pthreads/tests/condvar1_1.c @@ -0,0 +1,115 @@ +/* + * File: condvar1_1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test CV linked list management. + * + * Test Method (Validation or Falsification): + * - Validation: + * Initiate and destroy several CVs in random order. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - All initialised CVs destroyed without segfault. + * - Successfully broadcasts all remaining CVs after + * each CV is removed. + * + * Fail Criteria: + */ + +#include <stdlib.h> +#include "test.h" + +enum { + NUM_CV = 100 +}; + +static pthread_cond_t cv[NUM_CV]; + +int +main() +{ + int i, j; + + for (i = 0; i < NUM_CV; i++) + { + /* Traverse the list before every init of a CV. */ + assert(pthread_timechange_handler_np(NULL) == (void *) 0); + assert(pthread_cond_init(&cv[i], NULL) == 0); + } + + j = NUM_CV; + (void) srand((unsigned)time(NULL)); + + do + { + i = (NUM_CV - 1) * rand() / RAND_MAX; + if (cv[i] != NULL) + { + j--; + assert(pthread_cond_destroy(&cv[i]) == 0); + /* Traverse the list every time we remove a CV. */ + assert(pthread_timechange_handler_np(NULL) == (void *) 0); + } + } + while (j > 0); + + return 0; +} diff --git a/pthreads/tests/condvar1_2.c b/pthreads/tests/condvar1_2.c new file mode 100644 index 000000000..503e821b6 --- /dev/null +++ b/pthreads/tests/condvar1_2.c @@ -0,0 +1,124 @@ +/* + * File: condvar1_2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test CV linked list management and serialisation. + * + * Test Method (Validation or Falsification): + * - Validation: + * Initiate and destroy several CVs in random order. + * Asynchronously traverse the CV list and broadcast. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Creates and then imediately destroys a CV. Does not + * test the CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - All initialised CVs destroyed without segfault. + * - Successfully broadcasts all remaining CVs after + * each CV is removed. + * + * Fail Criteria: + */ + +#include <stdlib.h> +#include "test.h" + +enum { + NUM_CV = 5, + NUM_LOOPS = 5 +}; + +static pthread_cond_t cv[NUM_CV]; + +int +main() +{ + int i, j, k; + int result = -1; + pthread_t t; + + for (k = 0; k < NUM_LOOPS; k++) + { + for (i = 0; i < NUM_CV; i++) + { + assert(pthread_cond_init(&cv[i], NULL) == 0); + } + + j = NUM_CV; + (void) srand((unsigned)time(NULL)); + + /* Traverse the list asynchronously. */ + assert(pthread_create(&t, NULL, pthread_timechange_handler_np, NULL) == 0); + + do + { + i = (NUM_CV - 1) * rand() / RAND_MAX; + if (cv[i] != NULL) + { + j--; + assert(pthread_cond_destroy(&cv[i]) == 0); + } + } + while (j > 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert (result == 0); + } + + return 0; +} diff --git a/pthreads/tests/condvar2.c b/pthreads/tests/condvar2.c new file mode 100644 index 000000000..33f1d3f1d --- /dev/null +++ b/pthreads/tests/condvar2.c @@ -0,0 +1,125 @@ +/* + * File: condvar2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timed wait on a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because the CV is never signaled, we expect the wait to time out. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +pthread_cond_t cv; +pthread_mutex_t mutex; + +#include "../implement.h" + +int +main() +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mutex) == 0); + + { + int result = pthread_cond_destroy(&cv); + if (result != 0) + { + fprintf(stderr, "Result = %s\n", error_string[result]); + fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); + fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); + fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); + fflush(stderr); + } + assert(result == 0); + } + + return 0; +} diff --git a/pthreads/tests/condvar2_1.c b/pthreads/tests/condvar2_1.c new file mode 100644 index 000000000..92dddfd9a --- /dev/null +++ b/pthreads/tests/condvar2_1.c @@ -0,0 +1,153 @@ +/* + * File: condvar2_1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with no signal/broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because the CV is never signaled, we expect the waits to time out. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static struct timespec abstime = { 0, 0 }; + +enum { + NUMTHREADS = 30 +}; + +void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return arg; +} + +#include "../implement.h" + +int +main() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_mutex_lock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + assert(pthread_mutex_unlock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + assert(result == i); + } + + { + int result = pthread_cond_destroy(&cv); + if (result != 0) + { + fprintf(stderr, "Result = %s\n", error_string[result]); + fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); + fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); + fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); + fflush(stderr); + } + assert(result == 0); + } + + return 0; +} diff --git a/pthreads/tests/condvar3.c b/pthreads/tests/condvar3.c new file mode 100644 index 000000000..e3a23f54f --- /dev/null +++ b/pthreads/tests/condvar3.c @@ -0,0 +1,148 @@ +/* + * File: condvar3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test basic function of a CV + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - The primary thread takes the lock before creating any threads. + * The secondary thread blocks on the lock allowing the primary + * thread to enter the cv wait state which releases the lock. + * The secondary thread then takes the lock and signals the waiting + * primary thread. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static int shared = 0; + +enum { + NUMTHREADS = 2 /* Including the primary thread. */ +}; + +void * +mythread(void * arg) +{ + int result = 0; + + assert(pthread_mutex_lock(&mutex) == 0); + shared++; + assert(pthread_mutex_unlock(&mutex) == 0); + + if ((result = pthread_cond_signal(&cv)) != 0) + { + printf("Error = %s\n", error_string[result]); + } + assert(result == 0); + + + return (void *) 0; +} + +int +main() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert((t[0] = pthread_self()).p != NULL); + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + abstime.tv_sec += 5; + + while (! (shared > 0)) + assert(pthread_cond_timedwait(&cv, &mutex, &abstime) == 0); + + assert(shared > 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_cond_destroy(&cv) == 0); + + return 0; +} diff --git a/pthreads/tests/condvar3_1.c b/pthreads/tests/condvar3_1.c new file mode 100644 index 000000000..25a50e4bb --- /dev/null +++ b/pthreads/tests/condvar3_1.c @@ -0,0 +1,201 @@ +/* + * File: condvar3_1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with some signaled. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + * Some are signaled, the rest time out. Pthread_cond_destroy() will fail + * unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_cond_t cv1; +static pthread_mutex_t mutex; +static pthread_mutex_t mutex1; +static struct timespec abstime = { 0, 0 }; +static int timedout = 0; +static int signaled = 0; +static int awoken = 0; +static int waiting = 0; + +enum { + NUMTHREADS = 30 +}; + +void * +mythread(void * arg) +{ + int result; + + assert(pthread_mutex_lock(&mutex1) == 0); + ++waiting; + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(pthread_cond_signal(&cv1) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + result = pthread_cond_timedwait(&cv, &mutex, &abstime); + if (result == ETIMEDOUT) + { + timedout++; + } + else + { + awoken++; + } + assert(pthread_mutex_unlock(&mutex) == 0); + + return arg; +} + +#include "../implement.h" + +int +main() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + assert(pthread_cond_init(&cv1, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + assert(pthread_mutex_init(&mutex1, NULL) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_mutex_lock(&mutex1) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + do { + assert(pthread_cond_wait(&cv1,&mutex1) == 0); + } while ( NUMTHREADS > waiting ); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + for (i = NUMTHREADS/3; i <= 2*NUMTHREADS/3; i++) + { +// assert(pthread_mutex_lock(&mutex) == 0); + assert(pthread_cond_signal(&cv) == 0); +// assert(pthread_mutex_unlock(&mutex) == 0); + + signaled++; + } + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + assert(result == i); + } + + fprintf(stderr, "awk = %d\n", awoken); + fprintf(stderr, "sig = %d\n", signaled); + fprintf(stderr, "tot = %d\n", timedout); + + assert(signaled == awoken); + assert(timedout == NUMTHREADS - signaled); + + assert(pthread_cond_destroy(&cv1) == 0); + + { + int result = pthread_cond_destroy(&cv); + if (result != 0) + { + fprintf(stderr, "Result = %s\n", error_string[result]); + fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); + fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); + fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); + fflush(stderr); + } + assert(result == 0); + } + + assert(pthread_mutex_destroy(&mutex1) == 0); + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/pthreads/tests/condvar3_2.c b/pthreads/tests/condvar3_2.c new file mode 100644 index 000000000..5ddcf5748 --- /dev/null +++ b/pthreads/tests/condvar3_2.c @@ -0,0 +1,193 @@ +/* + * File: condvar3_2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeout of multiple waits on a CV with remainder broadcast awoken. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Because some CVs are never signaled, we expect their waits to time out. + * Some time out, the rest are broadcast signaled. Pthread_cond_destroy() will fail + * unless all are accounted for, either signaled or timedout. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include <sys/timeb.h> + +static pthread_cond_t cv; +static pthread_mutex_t mutex; +static struct timespec abstime = { 0, 0 }; +static struct timespec abstime2 = { 0, 0 }; +static int timedout = 0; +static int awoken = 0; + +enum { + NUMTHREADS = 30 +}; + +void * +mythread(void * arg) +{ + int result; + + assert(pthread_mutex_lock(&mutex) == 0); + + abstime2.tv_sec = abstime.tv_sec; + + if ((int) arg % 3 == 0) + { + abstime2.tv_sec += 2; + } + + result = pthread_cond_timedwait(&cv, &mutex, &abstime2); + assert(pthread_mutex_unlock(&mutex) == 0); + if (result == ETIMEDOUT) + { + InterlockedIncrement((LPLONG)&timedout); + } + else + { + InterlockedIncrement((LPLONG)&awoken); + } + + + return arg; +} + +#include "../implement.h" + +int +main() +{ + int i; + pthread_t t[NUMTHREADS + 1]; + int result = 0; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cv, NULL) == 0); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; + abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + assert(pthread_mutex_lock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_create(&t[i], NULL, mythread, (void *) i) == 0); + } + + assert(pthread_mutex_unlock(&mutex) == 0); + + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], (void **) &result) == 0); + assert(result == i); + /* + * Approximately 2/3rds of the threads are expected to time out. + * Signal the remainder after some threads have woken up and exited + * and while some are still waking up after timeout. + * Also tests that redundant broadcasts don't return errors. + */ + +// assert(pthread_mutex_lock(&mutex) == 0); + + if (InterlockedExchangeAdd((LPLONG)&awoken, 0L) > NUMTHREADS/3) + { + assert(pthread_cond_broadcast(&cv) == 0); + } + +// assert(pthread_mutex_unlock(&mutex) == 0); + + } + + assert(awoken == NUMTHREADS - timedout); + + { + int result = pthread_cond_destroy(&cv); + if (result != 0) + { + fprintf(stderr, "Result = %s\n", error_string[result]); + fprintf(stderr, "\tWaitersBlocked = %ld\n", cv->nWaitersBlocked); + fprintf(stderr, "\tWaitersGone = %ld\n", cv->nWaitersGone); + fprintf(stderr, "\tWaitersToUnblock = %ld\n", cv->nWaitersToUnblock); + fflush(stderr); + } + assert(result == 0); + } + + assert(pthread_mutex_destroy(&mutex) == 0); + + return 0; +} diff --git a/pthreads/tests/condvar3_3.c b/pthreads/tests/condvar3_3.c new file mode 100644 index 000000000..fe6763249 --- /dev/null +++ b/pthreads/tests/condvar3_3.c @@ -0,0 +1,132 @@ +/* + * File: condvar3_3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test timeouts and lost signals on a CV. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait does not return ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +/* Timur Aydin (taydin@snet.net) */ + +#include "test.h" + +#include <sys/timeb.h> + +pthread_cond_t cnd; +pthread_mutex_t mtx; + +int main() +{ + int rc; + + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert(pthread_cond_init(&cnd, 0) == 0); + assert(pthread_mutex_init(&mtx, 0) == 0); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + abstime.tv_sec += 1; + + /* Here pthread_cond_timedwait should time out after one second. */ + + assert(pthread_mutex_lock(&mtx) == 0); + + assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mtx) == 0); + + /* Here, the condition variable is signaled, but there are no + threads waiting on it. The signal should be lost and + the next pthread_cond_timedwait should time out too. */ + +// assert(pthread_mutex_lock(&mtx) == 0); + + assert((rc = pthread_cond_signal(&cnd)) == 0); + +// assert(pthread_mutex_unlock(&mtx) == 0); + + assert(pthread_mutex_lock(&mtx) == 0); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + abstime.tv_sec += 1; + + assert((rc = pthread_cond_timedwait(&cnd, &mtx, &abstime)) == ETIMEDOUT); + + assert(pthread_mutex_unlock(&mtx) == 0); + + return 0; +} diff --git a/pthreads/tests/condvar4.c b/pthreads/tests/condvar4.c new file mode 100644 index 000000000..3babeeac5 --- /dev/null +++ b/pthreads/tests/condvar4.c @@ -0,0 +1,169 @@ +/* + * File: condvar4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test PTHREAD_COND_INITIALIZER. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test basic CV function but starting with a static initialised + * CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +enum { + NUMTHREADS = 2 +}; + +void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_signal(&cvthing.notbusy) == 0); + + return (void *) 0; +} + +int +main() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); + + assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + assert(cvthing.shared > 0); + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + return 0; +} diff --git a/pthreads/tests/condvar5.c b/pthreads/tests/condvar5.c new file mode 100644 index 000000000..4d51f396a --- /dev/null +++ b/pthreads/tests/condvar5.c @@ -0,0 +1,168 @@ +/* + * File: condvar5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with one waiting CV. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - pthread_cond_timedwait returns 0. + * - Process returns zero exit status. + * + * Fail Criteria: + * - pthread_cond_timedwait returns ETIMEDOUT. + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +enum { + NUMTHREADS = 2 +}; + +void * +mythread(void * arg) +{ + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + return (void *) 0; +} + +int +main() +{ + pthread_t t[NUMTHREADS]; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); + + /* get current system time */ + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == ETIMEDOUT); + + assert(cvthing.notbusy != PTHREAD_COND_INITIALIZER); + + assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + assert(cvthing.shared > 0); + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + return 0; +} diff --git a/pthreads/tests/condvar6.c b/pthreads/tests/condvar6.c new file mode 100644 index 000000000..e63132c5d --- /dev/null +++ b/pthreads/tests/condvar6.c @@ -0,0 +1,242 @@ +/* + * File: condvar6.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&start_flag) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + Sleep(1000); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Give threads time to complete. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS); + + /* + * Success. + */ + return 0; +} + + diff --git a/pthreads/tests/condvar7.c b/pthreads/tests/condvar7.c new file mode 100644 index 000000000..6d89f2ea9 --- /dev/null +++ b/pthreads/tests/condvar7.c @@ -0,0 +1,257 @@ +/* + * File: condvar7.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test pthread_cond_broadcast with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Test broadcast with NUMTHREADS (=5) waiting CVs, one is canceled while waiting. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + cvthing.shared = 0; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&start_flag) == 0); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 10; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + Sleep(1000); + + /* + * Cancel one of the threads. + */ + assert(pthread_cancel(t[1]) == 0); + assert(pthread_join(t[1], NULL) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + /* + * Signal all remaining waiting threads. + */ + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Wait for all threads to complete. + */ + for (i = 2; i <= NUMTHREADS; i++) + assert(pthread_join(t[i], NULL) == 0); + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == (NUMTHREADS - 1)); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/condvar8.c b/pthreads/tests/condvar8.c new file mode 100644 index 000000000..e384a1c9c --- /dev/null +++ b/pthreads/tests/condvar8.c @@ -0,0 +1,258 @@ +/* + * File: condvar8.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Make NUMTHREADS threads wait on CV, broadcast signal them, and then repeat. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 5 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + assert(cvthing.shared > 0); + + awoken++; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int +main() +{ + int failed = 0; + int i; + int first, last; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 10; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (first = 1, last = NUMTHREADS / 2; + first < NUMTHREADS; + first = last + 1, last = NUMTHREADS) + { + assert(pthread_mutex_lock(&start_flag) == 0); + + for (i = first; i <= last; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + cvthing.shared = 0; + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + Sleep(100); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Give threads time to complete. + */ + for (i = first; i <= last; i++) + { + assert(pthread_join(t[i], NULL) == 0); + } + + assert(awoken == (i - 1)); + } + + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert(pthread_cond_destroy(&cvthing.notbusy) == 0); + + assert(cvthing.notbusy == NULL); + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/condvar9.c b/pthreads/tests/condvar9.c new file mode 100644 index 000000000..c75127108 --- /dev/null +++ b/pthreads/tests/condvar9.c @@ -0,0 +1,267 @@ +/* + * File: condvar9.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test multiple pthread_cond_broadcasts with thread cancelation. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - Make NUMTHREADS threads wait on CV, cancel one, broadcast signal them, + * and then repeat. + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#include <sys/timeb.h> + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 9 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + int finished; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +typedef struct cvthing_t_ cvthing_t; + +struct cvthing_t_ { + pthread_cond_t notbusy; + pthread_mutex_t lock; + int shared; +}; + +static cvthing_t cvthing = { + PTHREAD_COND_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + 0 +}; + +static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER; + +static struct timespec abstime = { 0, 0 }; + +static int awoken; + +static void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* Wait for the start gun */ + assert(pthread_mutex_lock(&start_flag) == 0); + assert(pthread_mutex_unlock(&start_flag) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + + /* + * pthread_cond_timedwait is a cancelation point and we're + * going to cancel some threads deliberately. + */ +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(pthread_mutex_unlock, (void *) &cvthing.lock); + + while (! (cvthing.shared > 0)) + assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0); + + pthread_cleanup_pop(0); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + assert(cvthing.shared > 0); + + awoken++; + bag->finished = 1; + + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + return (void *) 0; +} + +int +main() +{ + int failed = 0; + int i; + int first, last; + int canceledThreads = 0; + pthread_t t[NUMTHREADS + 1]; + + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + assert((t[0] = pthread_self()).p != NULL); + + assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER); + + assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 5; + + assert((t[0] = pthread_self()).p != NULL); + + awoken = 0; + + for (first = 1, last = NUMTHREADS / 2; + first < NUMTHREADS; + first = last + 1, last = NUMTHREADS) + { + int ct; + + assert(pthread_mutex_lock(&start_flag) == 0); + + for (i = first; i <= last; i++) + { + threadbag[i].started = threadbag[i].finished = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + cvthing.shared = 0; + + assert(pthread_mutex_unlock(&start_flag) == 0); + + /* + * Give threads time to start. + */ + Sleep(1000); + + ct = (first + last) / 2; + assert(pthread_cancel(t[ct]) == 0); + canceledThreads++; + assert(pthread_join(t[ct], NULL) == 0); + + assert(pthread_mutex_lock(&cvthing.lock) == 0); + cvthing.shared++; + assert(pthread_mutex_unlock(&cvthing.lock) == 0); + + assert(pthread_cond_broadcast(&cvthing.notbusy) == 0); + + /* + * Standard check that all threads started - and wait for them to finish. + */ + for (i = first; i <= last; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + else + { + assert(pthread_join(t[i], NULL) == 0 || threadbag[i].finished == 0); +// fprintf(stderr, "Thread %d: finished %d\n", i, threadbag[i].finished); + } + } + } + + /* + * Cleanup the CV. + */ + + assert(pthread_mutex_destroy(&cvthing.lock) == 0); + + assert(cvthing.lock == NULL); + + assert_e(pthread_cond_destroy(&cvthing.notbusy), ==, 0); + + assert(cvthing.notbusy == NULL); + + assert(!failed); + + /* + * Check any results here. + */ + + assert(awoken == NUMTHREADS - canceledThreads); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/context1.c b/pthreads/tests/context1.c new file mode 100644 index 000000000..090df9c9d --- /dev/null +++ b/pthreads/tests/context1.c @@ -0,0 +1,144 @@ +/* + * File: context1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test context switching method. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - pthread_create + * pthread_exit + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include "../implement.h" + +static int washere = 0; + +static void * func(void * arg) +{ + washere = 1; + + Sleep(1000); + + return 0; +} + +static void +anotherEnding () +{ + /* + * Switched context + */ + washere++; + + pthread_exit(0); +} + +int +main() +{ + pthread_t t; + HANDLE hThread; + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + hThread = ((ptw32_thread_t *)t.p)->threadH; + + Sleep(500); + + SuspendThread(hThread); + + if (WaitForSingleObject(hThread, 0) == WAIT_TIMEOUT) + { + /* + * Ok, thread did not exit before we got to it. + */ + CONTEXT context; + + context.ContextFlags = CONTEXT_CONTROL; + + GetThreadContext(hThread, &context); + /* + *_x86 only!!! + */ + context.Eip = (DWORD) anotherEnding; + SetThreadContext(hThread, &context); + ResumeThread(hThread); + } + else + { + printf("Exited early\n"); + fflush(stdout); + } + + Sleep(1000); + + assert(washere == 2); + + return 0; +} + diff --git a/pthreads/tests/count1.c b/pthreads/tests/count1.c new file mode 100644 index 000000000..c2386b0e9 --- /dev/null +++ b/pthreads/tests/count1.c @@ -0,0 +1,90 @@ +/* + * count1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Description: + * Test some basic assertions about the number of threads at runtime. + */ + +#include "test.h" + +#define NUMTHREADS (30) + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_t threads[NUMTHREADS]; +static unsigned numThreads = 0; + +void * +myfunc(void *arg) +{ + pthread_mutex_lock(&lock); + numThreads++; + pthread_mutex_unlock(&lock); + + Sleep(1000); + return 0; +} +int +main() +{ + int i; + int maxThreads = sizeof(threads) / sizeof(pthread_t); + + /* + * Spawn NUMTHREADS threads. Each thread should increment the + * numThreads variable, sleep for one second. + */ + for (i = 0; i < maxThreads; i++) + { + assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0); + } + + /* + * Wait for all the threads to exit. + */ + for (i = 0; i < maxThreads; i++) + { + assert(pthread_join(threads[i], NULL) == 0); + } + + /* + * Check the number of threads created. + */ + assert((int) numThreads == maxThreads); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/create1.c b/pthreads/tests/create1.c new file mode 100644 index 000000000..8c630cb93 --- /dev/null +++ b/pthreads/tests/create1.c @@ -0,0 +1,66 @@ +/* + * create1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Description: + * Create a thread and check that it ran. + * + * Depends on API functions: None. + */ + +#include "test.h" + +static int washere = 0; + +void * func(void * arg) +{ + washere = 1; + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + /* A dirty hack, but we cannot rely on pthread_join in this + primitive test. */ + Sleep(2000); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/create2.c b/pthreads/tests/create2.c new file mode 100644 index 000000000..2ffb64e08 --- /dev/null +++ b/pthreads/tests/create2.c @@ -0,0 +1,108 @@ +/* + * File: create2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that threads have a Win32 handle when started. + * + * Test Method (Validation or Falsification): + * - Statistical, not absolute (depends on sample size). + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + NUMTHREADS = 10000 +}; + +static int washere = 0; + +void * func(void * arg) +{ + washere = 1; + return (void *) 0; +} + +int +main() +{ + pthread_t t; + pthread_attr_t attr; + void * result = NULL; + int i; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + for (i = 0; i < NUMTHREADS; i++) + { + washere = 0; + assert(pthread_create(&t, &attr, func, NULL) == 0); + pthread_join(t, &result); + assert(washere == 1); + } + + return 0; +} diff --git a/pthreads/tests/create3.c b/pthreads/tests/create3.c new file mode 100644 index 000000000..98bd5200e --- /dev/null +++ b/pthreads/tests/create3.c @@ -0,0 +1,122 @@ +/* + * File: create3.c + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2003 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing NULL as thread id arg to pthread_create. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + + +void * +threadFunc(void * arg) +{ + return (void *) 0; +} + +int +main(int argc, char * argv[]) +{ + int i; + pthread_t mt; + + if (argc <= 1) + { + int result; + + printf("You should see an application memory write error message\n"); + fflush(stdout); + result = system("create3.exe die"); + exit(0); + } + + assert((mt = pthread_self()).p != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(NULL, NULL, threadFunc, NULL) == 0); + } + + /* + * Success. + */ + return 0; +} + diff --git a/pthreads/tests/delay1.c b/pthreads/tests/delay1.c new file mode 100644 index 000000000..83becd890 --- /dev/null +++ b/pthreads/tests/delay1.c @@ -0,0 +1,51 @@ +/* + * delay1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_delay_np + */ + +#include "test.h" + +int +main(int argc, char * argv[]) +{ + struct timespec interval = {1L, 500000000L}; + + assert(pthread_delay_np(&interval) == 0); + + return 0; +} + diff --git a/pthreads/tests/delay2.c b/pthreads/tests/delay2.c new file mode 100644 index 000000000..8ecaf0b94 --- /dev/null +++ b/pthreads/tests/delay2.c @@ -0,0 +1,82 @@ +/* + * delay1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_delay_np + */ + +#include "test.h" + +pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER; + +void * +func(void * arg) +{ + struct timespec interval = {5, 500000000L}; + + assert(pthread_mutex_lock(&mx) == 0); + +#ifdef _MSC_VER +#pragma inline_depth(0) +#endif + pthread_cleanup_push(pthread_mutex_unlock, &mx); + assert(pthread_delay_np(&interval) == 0); + pthread_cleanup_pop(1); +#ifdef _MSC_VER +#pragma inline_depth() +#endif + + return (void *) 1; +} + +int +main(int argc, char * argv[]) +{ + pthread_t t; + int result = 0; + + assert(pthread_mutex_lock(&mx) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_cancel(t) == 0); + + assert(pthread_mutex_unlock(&mx) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == (int) PTHREAD_CANCELED); + + return 0; +} + diff --git a/pthreads/tests/detach1.c b/pthreads/tests/detach1.c new file mode 100644 index 000000000..165c8c1d1 --- /dev/null +++ b/pthreads/tests/detach1.c @@ -0,0 +1,93 @@ +/* + * Test for pthread_detach(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_detach(), pthread_exit(). + */ + +#include "test.h" + + +enum { + NUMTHREADS = 100 +}; + +void * +func(void * arg) +{ + int i = (int) arg; + + Sleep(i * 10); + + pthread_exit(arg); + + /* Never reached. */ + exit(1); +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[NUMTHREADS]; + int i; + + /* Create a few threads and then exit. */ + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + /* Some threads will finish before they are detached, some after. */ + Sleep(NUMTHREADS/2 * 10 + 50); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_detach(id[i]) == 0); + } + + Sleep(NUMTHREADS * 10 + 100); + + /* + * Check that all threads are now invalid. + * This relies on unique thread IDs - e.g. works with + * pthreads-w32 or Solaris, but may not work for Linux, BSD etc. + */ + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_kill(id[i], 0) == ESRCH); + } + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/equal1.c b/pthreads/tests/equal1.c new file mode 100644 index 000000000..8932bb2aa --- /dev/null +++ b/pthreads/tests/equal1.c @@ -0,0 +1,66 @@ +/* + * Test for pthread_equal. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on functions: pthread_create(). + */ + +#include "test.h" + +void * func(void * arg) +{ + Sleep(2000); + return 0; +} + +int +main() +{ + pthread_t t1, t2; + + assert(pthread_create(&t1, NULL, func, (void *) 1) == 0); + + assert(pthread_create(&t2, NULL, func, (void *) 2) == 0); + + assert(pthread_equal(t1, t2) == 0); + + assert(pthread_equal(t1,t1) != 0); + + /* This is a hack. We don't want to rely on pthread_join + yet if we can help it. */ + Sleep(4000); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/errno1.c b/pthreads/tests/errno1.c new file mode 100644 index 000000000..70ce92802 --- /dev/null +++ b/pthreads/tests/errno1.c @@ -0,0 +1,177 @@ +/* + * File: errno1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test thread-safety of errno + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 3 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +pthread_mutex_t stop_here = PTHREAD_MUTEX_INITIALIZER; + +void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + errno = bag->threadnum; + + Sleep(1000); + + pthread_mutex_lock(&stop_here); + + assert(errno == bag->threadnum); + + pthread_mutex_unlock(&stop_here); + + Sleep(1000); + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t t[NUMTHREADS + 1]; + + pthread_mutex_lock(&stop_here); + errno = 0; + + assert((t[0] = pthread_self()).p != NULL); + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; + assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(2000); + pthread_mutex_unlock(&stop_here); + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 1000); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + failed = !threadbag[i].started; + + if (failed) + { + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print ouput on failure. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + /* ... */ + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} diff --git a/pthreads/tests/exception1.c b/pthreads/tests/exception1.c new file mode 100644 index 000000000..3f9f59578 --- /dev/null +++ b/pthreads/tests/exception1.c @@ -0,0 +1,263 @@ +/* + * File: exception1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing of exceptions back to the application. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#if defined(_MSC_VER) || defined(__cplusplus) + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +void * +exceptionedThread(void * arg) +{ + int dummy = 0; + int result = ((int)PTHREAD_CANCELED + 1); + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + + Sleep(100); + +#if defined(_MSC_VER) && !defined(__cplusplus) + __try + { + int zero = (int) arg; /* Passed in from arg to avoid compiler error */ + int one = 1; + /* + * The deliberate exception condition (zero divide) is + * in an "if" to avoid being optimised out. + */ + if (dummy == one/zero) + Sleep(0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* Should get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#elif defined(__cplusplus) + try + { + /* + * I had a zero divide exception here but it + * wasn't being caught by the catch(...) + * below under Mingw32. That could be a problem. + */ + throw dummy; + } +#if defined(PtW32CatchAll) + PtW32CatchAll +#else + catch (...) +#endif + { + /* Should get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#endif + + return (void *) result; +} + +void * +canceledThread(void * arg) +{ + int result = ((int)PTHREAD_CANCELED + 1); + int count; + + /* Set to async cancelable */ + + assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0); + + assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0); + +#if defined(_MSC_VER) && !defined(__cplusplus) + __try + { + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (count = 0; count < 100; count++) + Sleep(100); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + /* Should NOT get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#elif defined(__cplusplus) + try + { + /* + * We wait up to 10 seconds, waking every 0.1 seconds, + * for a cancelation to be applied to us. + */ + for (count = 0; count < 100; count++) + Sleep(100); + } +#if defined(PtW32CatchAll) + PtW32CatchAll +#else + catch (...) +#endif + { + /* Should NOT get into here. */ + result = ((int)PTHREAD_CANCELED + 2); + } +#endif + + return (void *) result; +} + +int +main() +{ + int failed = 0; + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + pthread_t ct[NUMTHREADS]; + + assert((mt = pthread_self()).p != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, (void *) 0) == 0); + assert(pthread_create(&ct[i], NULL, canceledThread, NULL) == 0); + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(1000); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_cancel(ct[i]) == 0); + } + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 1000); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 0; i < NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + + /* Canceled thread */ + assert(pthread_join(ct[i], (void **) &result) == 0); + assert(!(fail = (result != (int) PTHREAD_CANCELED))); + + failed = (failed || fail); + + /* Exceptioned thread */ + assert(pthread_join(et[i], (void **) &result) == 0); + assert(!(fail = (result != ((int) PTHREAD_CANCELED + 2)))); + + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +#include <stdio.h> + +int +main() +{ + fprintf(stderr, "Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/exception2.c b/pthreads/tests/exception2.c new file mode 100644 index 000000000..5c1856810 --- /dev/null +++ b/pthreads/tests/exception2.c @@ -0,0 +1,158 @@ +/* + * File: exception2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test passing of exceptions out of thread scope. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + + +#if defined(_MSC_VER) || defined(__cplusplus) + +#if defined(_MSC_VER) && defined(__cplusplus) +#include <eh.h> +#elif defined(__cplusplus) +#include <exception> +#endif + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#include "test.h" + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + + +void * +exceptionedThread(void * arg) +{ + int dummy = 0x1; + +#if defined(_MSC_VER) && !defined(__cplusplus) + + RaiseException(dummy, 0, 0, NULL); + +#elif defined(__cplusplus) + + throw dummy; + +#endif + + return (void *) 100; +} + +int +main(int argc, char argv[]) +{ + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + + if (argc <= 1) + { + int result; + + printf("You should see an \"abnormal termination\" message\n"); + fflush(stdout); + result = system("exception2.exe die"); + exit(0); + } + + assert((mt = pthread_self()).p != NULL); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); + } + + Sleep(1000); + + /* + * Success. + */ + return 0; +} + +#else /* defined(_MSC_VER) || defined(__cplusplus) */ + +#include <stdio.h> + +int +main() +{ + fprintf(stderr, "Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(_MSC_VER) || defined(__cplusplus) */ diff --git a/pthreads/tests/exception3.c b/pthreads/tests/exception3.c new file mode 100644 index 000000000..9a70a405a --- /dev/null +++ b/pthreads/tests/exception3.c @@ -0,0 +1,196 @@ +/* + * File: exception3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test running of user supplied terminate() function. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#if defined(__cplusplus) + +#if defined(_MSC_VER) +# include <eh.h> +#else +# if defined(__GNUC__) && __GNUC__ < 3 +# include <new.h> +# else +# include <new> + using std::set_terminate; +# endif +#endif + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 1 +}; + +int caught = 0; +pthread_mutex_t caughtLock; + +void +terminateFunction () +{ + assert(pthread_mutex_lock(&caughtLock) == 0); + caught++; +#if 1 + { + FILE * fp = fopen("pthread.log", "a"); + fprintf(fp, "Caught = %d\n", caught); + fclose(fp); + } +#endif + assert(pthread_mutex_unlock(&caughtLock) == 0); + +#if defined(__MINGW32__) + /* + * Seems to work. That is, threads exit and the process + * continues. Note: need to check correct POSIX behaviour. + * My guess is: this is because of the + * eh incompatibility between g++ and MSVC++. That is, + * an exception thrown in g++ code doesn't propogate + * through or to MSVC++ code, and vice versa. + * Applications should probably not depend on this. + */ + pthread_exit((void *) 0); +#else + /* + * Notes from the MSVC++ manual: + * 1) A term_func() should call exit(), otherwise + * abort() will be called on return to the caller. + * abort() raises SIGABRT. The default signal handler + * for all signals terminates the calling program with + * exit code 3. + * 2) A term_func() must not throw an exception. Therefore + * term_func() should not call pthread_exit() if an + * an exception-using version of pthreads-win32 library + * is being used (i.e. either pthreadVCE or pthreadVSE). + */ + exit(0); +#endif +} + +void * +exceptionedThread(void * arg) +{ + int dummy = 0x1; + + (void) set_terminate(&terminateFunction); + + throw dummy; + + return (void *) 0; +} + +int +main() +{ + int i; + pthread_t mt; + pthread_t et[NUMTHREADS]; + pthread_mutexattr_t ma; + + assert((mt = pthread_self()).p != NULL); + + printf("See the notes inside of exception3.c re term_funcs.\n"); + + assert(pthread_mutexattr_init(&ma) == 0); + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&caughtLock, &ma) == 0); + assert(pthread_mutexattr_destroy(&ma) == 0); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&et[i], NULL, exceptionedThread, NULL) == 0); + } + + Sleep(5000); + + assert(caught == NUMTHREADS); + + /* + * Success. + */ + return 0; +} + +#else /* defined(__cplusplus) */ + +#include <stdio.h> + +int +main() +{ + fprintf(stderr, "Test N/A for this compiler environment.\n"); + return 0; +} + +#endif /* defined(__cplusplus) */ diff --git a/pthreads/tests/exit1.c b/pthreads/tests/exit1.c new file mode 100644 index 000000000..38f218211 --- /dev/null +++ b/pthreads/tests/exit1.c @@ -0,0 +1,50 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: None. + */ + +#include "test.h" + +int +main(int argc, char * argv[]) +{ + /* A simple test first. */ + pthread_exit((void *) 0); + + /* Not reached */ + assert(0); + return 0; +} diff --git a/pthreads/tests/exit2.c b/pthreads/tests/exit2.c new file mode 100644 index 000000000..196139a9f --- /dev/null +++ b/pthreads/tests/exit2.c @@ -0,0 +1,64 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: + * pthread_create() + * pthread_exit() + */ + +#include "test.h" + +void * +func(void * arg) +{ + pthread_exit(arg); + + /* Never reached. */ + assert(0); + + return NULL; +} + +int +main(int argc, char * argv[]) +{ + pthread_t t; + + assert(pthread_create(&t, NULL, func, (void *) NULL) == 0); + + Sleep(1000); + + return 0; +} diff --git a/pthreads/tests/exit3.c b/pthreads/tests/exit3.c new file mode 100644 index 000000000..574a92df7 --- /dev/null +++ b/pthreads/tests/exit3.c @@ -0,0 +1,68 @@ +/* + * Test for pthread_exit(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + pthread_exit(arg); + + /* Never reached. */ + assert(0); + + return NULL; +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[4]; + int i; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + Sleep(1000); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/exit4.c b/pthreads/tests/exit4.c new file mode 100644 index 000000000..1ceca4e35 --- /dev/null +++ b/pthreads/tests/exit4.c @@ -0,0 +1,199 @@ +/* + * File: exit4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_exit from a Win32 thread + * without having created an implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#ifndef _UWIN +#include <process.h> +#endif + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +unsigned __stdcall +#else +void +#endif +Win32thread(void * arg) +{ + int result = 1; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + /* + * Doesn't return and doesn't create an implicit POSIX handle. + */ + pthread_exit((void *) result); + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + HANDLE h[NUMTHREADS + 1]; + unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */ + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr); +#else + h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]); +#endif + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE); +#else + /* + * Can't get a result code. + */ + result = 1; +#endif + + fail = (result != 1); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/pthreads/tests/exit5.c b/pthreads/tests/exit5.c new file mode 100644 index 000000000..450ed3bea --- /dev/null +++ b/pthreads/tests/exit5.c @@ -0,0 +1,205 @@ +/* + * File: exit5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Test calling pthread_exit from a Win32 thread + * having created an implicit POSIX handle for it. + * + * Test Method (Validation or Falsification): + * - Validate return value and that POSIX handle is created and destroyed. + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock + * pthread_testcancel, pthread_cancel, pthread_join + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" +#ifndef _UWIN +#include <process.h> +#endif + +/* + * Create NUMTHREADS threads in addition to the Main thread. + */ +enum { + NUMTHREADS = 4 +}; + +typedef struct bag_t_ bag_t; +struct bag_t_ { + int threadnum; + int started; + /* Add more per-thread state variables here */ + int count; + pthread_t self; +}; + +static bag_t threadbag[NUMTHREADS + 1]; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) +unsigned __stdcall +#else +void +#endif +Win32thread(void * arg) +{ + int result = 1; + bag_t * bag = (bag_t *) arg; + + assert(bag == &threadbag[bag->threadnum]); + assert(bag->started == 0); + bag->started = 1; + + assert((bag->self = pthread_self()).p != NULL); + assert(pthread_kill(bag->self, 0) == 0); + + /* + * Doesn't return. + */ + pthread_exit((void *) result); + + return 0; +} + +int +main() +{ + int failed = 0; + int i; + HANDLE h[NUMTHREADS + 1]; + unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */ + + for (i = 1; i <= NUMTHREADS; i++) + { + threadbag[i].started = 0; + threadbag[i].threadnum = i; +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr); +#else + h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]); +#endif + } + + /* + * Code to control or munipulate child threads should probably go here. + */ + Sleep(500); + + /* + * Give threads time to run. + */ + Sleep(NUMTHREADS * 100); + + /* + * Standard check that all threads started. + */ + for (i = 1; i <= NUMTHREADS; i++) + { + if (!threadbag[i].started) + { + failed |= !threadbag[i].started; + fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); + } + } + + assert(!failed); + + /* + * Check any results here. Set "failed" and only print output on failure. + */ + failed = 0; + for (i = 1; i <= NUMTHREADS; i++) + { + int fail = 0; + int result = 0; + +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE); +#else + /* + * Can't get a result code. + */ + result = 1; +#endif + + assert(threadbag[i].self.p != NULL && pthread_kill(threadbag[i].self, 0) == ESRCH); + + fail = (result != 1); + + if (fail) + { + fprintf(stderr, "Thread %d: started %d: count %d\n", + i, + threadbag[i].started, + threadbag[i].count); + } + failed = (failed || fail); + } + + assert(!failed); + + /* + * Success. + */ + return 0; +} + diff --git a/pthreads/tests/eyal1.c b/pthreads/tests/eyal1.c new file mode 100644 index 000000000..72b5697e9 --- /dev/null +++ b/pthreads/tests/eyal1.c @@ -0,0 +1,367 @@ +/* Simple POSIX threads program. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Author: Eyal Lebedinsky eyal@eyal.emu.id.au + * Written: Sep 1998. + * Version Date: 12 Sep 1998 + * + * Do we need to lock stdout or is it thread safe? + * + * Used: + * pthread_t + * pthread_attr_t + * pthread_create() + * pthread_join() + * pthread_mutex_t + * PTHREAD_MUTEX_INITIALIZER + * pthread_mutex_init() [not used now] + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + * + * What this program does is establish a work queue (implemented using + * four mutexes for each thread). It then schedules work (by storing + * a number in 'todo') and releases the threads. When the work is done + * the threads will block. The program then repeats the same thing once + * more (just to test the logic) and when the work is done it destroyes + * the threads. + * + * The 'work' we do is simply burning CPU cycles in a loop. + * The 'todo' work queue is trivial - each threads pops one element + * off it by incrementing it, the poped number is the 'work' to do. + * When 'todo' reaches the limit (nwork) the queue is considered + * empty. + * + * The number displayed at the end is the amount of work each thread + * did, so we can see if the load was properly distributed. + * + * The program was written to test a threading setup (not seen here) + * rather than to demonstrate correct usage of the pthread facilities. + * + * Note how each thread is given access to a thread control structure + * (TC) which is used for communicating to/from the main program (e.g. + * the threads knows its 'id' and also filles in the 'work' done). +*/ + +#include "test.h" + +#include <stdlib.h> +#include <math.h> + +struct thread_control { + int id; + pthread_t thread; /* thread id */ + pthread_mutex_t mutex_start; + pthread_mutex_t mutex_started; + pthread_mutex_t mutex_end; + pthread_mutex_t mutex_ended; + long work; /* work done */ + int stat; /* pthread_init status */ +}; + +typedef struct thread_control TC; + +static TC *tcs = NULL; +static int nthreads = 10; +static int nwork = 100; +static int quiet = 0; + +static int todo = -1; + +static pthread_mutex_t mutex_todo = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mutex_stdout = PTHREAD_MUTEX_INITIALIZER; + + +static void +die (int ret) +{ + if (NULL != tcs) + { + free (tcs); + tcs = NULL; + } + + if (ret) + exit (ret); +} + + +static double +waste_time (int n) +{ + int i; + double f, g, h, s; + + s = 0.0; + + /* + * Useless work. + */ + for (i = n*100; i > 0; --i) + { + f = rand (); + g = rand (); + h = rand (); + s += 2.0 * f * g / (h != 0.0 ? (h * h) : 1.0); + } + return s; +} + +static int +do_work_unit (int who, int n) +{ + int i; + static int nchars = 0; + double f = 0.0; + + if (quiet) + i = 0; + else { + /* + * get lock on stdout + */ + assert(pthread_mutex_lock (&mutex_stdout) == 0); + + /* + * do our job + */ + i = printf ("%c", "0123456789abcdefghijklmnopqrstuvwxyz"[who]); + + if (!(++nchars % 50)) + printf ("\n"); + + fflush (stdout); + + /* + * release lock on stdout + */ + assert(pthread_mutex_unlock (&mutex_stdout) == 0); + } + + n = rand () % 10000; /* ignore incoming 'n' */ + f = waste_time (n); + + /* This prevents the statement above from being optimised out */ + if (f > 0.0) + return(n); + + return (n); +} + +static int +print_server (void *ptr) +{ + int mywork; + int n; + TC *tc = (TC *)ptr; + + assert(pthread_mutex_lock (&tc->mutex_started) == 0); + + for (;;) + { + assert(pthread_mutex_lock (&tc->mutex_start) == 0); + assert(pthread_mutex_unlock (&tc->mutex_start) == 0); + assert(pthread_mutex_lock (&tc->mutex_ended) == 0); + assert(pthread_mutex_unlock (&tc->mutex_started) == 0); + + for (;;) + { + + /* + * get lock on todo list + */ + assert(pthread_mutex_lock (&mutex_todo) == 0); + + mywork = todo; + if (todo >= 0) + { + ++todo; + if (todo >= nwork) + todo = -1; + } + assert(pthread_mutex_unlock (&mutex_todo) == 0); + + if (mywork < 0) + break; + + assert((n = do_work_unit (tc->id, mywork)) >= 0); + tc->work += n; + } + + assert(pthread_mutex_lock (&tc->mutex_end) == 0); + assert(pthread_mutex_unlock (&tc->mutex_end) == 0); + assert(pthread_mutex_lock (&tc->mutex_started) == 0); + assert(pthread_mutex_unlock (&tc->mutex_ended) == 0); + + if (-2 == mywork) + break; + } + + assert(pthread_mutex_unlock (&tc->mutex_started) == 0); + + return (0); +} + +static void +dosync (void) +{ + int i; + + for (i = 0; i < nthreads; ++i) + { + assert(pthread_mutex_lock (&tcs[i].mutex_end) == 0); + assert(pthread_mutex_unlock (&tcs[i].mutex_start) == 0); + assert(pthread_mutex_lock (&tcs[i].mutex_started) == 0); + assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0); + } + + /* + * Now threads do their work + */ + for (i = 0; i < nthreads; ++i) + { + assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0); + assert(pthread_mutex_unlock (&tcs[i].mutex_end) == 0); + assert(pthread_mutex_lock (&tcs[i].mutex_ended) == 0); + assert(pthread_mutex_unlock (&tcs[i].mutex_ended) == 0); + } +} + +static void +dowork (void) +{ + todo = 0; + dosync(); + + todo = 0; + dosync(); +} + +int +main (int argc, char *argv[]) +{ + int i; + + assert(NULL != (tcs = (TC *) calloc (nthreads, sizeof (*tcs)))); + + /* + * Launch threads + */ + for (i = 0; i < nthreads; ++i) + { + tcs[i].id = i; + + assert(pthread_mutex_init (&tcs[i].mutex_start, NULL) == 0); + assert(pthread_mutex_init (&tcs[i].mutex_started, NULL) == 0); + assert(pthread_mutex_init (&tcs[i].mutex_end, NULL) == 0); + assert(pthread_mutex_init (&tcs[i].mutex_ended, NULL) == 0); + + tcs[i].work = 0; + + assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0); + assert((tcs[i].stat = + pthread_create (&tcs[i].thread, + NULL, + (void *(*)(void *))print_server, + (void *) &tcs[i]) + ) == 0); + + /* + * Wait for thread initialisation + */ + { + int trylock = 0; + + while (trylock == 0) + { + trylock = pthread_mutex_trylock(&tcs[i].mutex_started); + assert(trylock == 0 || trylock == EBUSY); + + if (trylock == 0) + { + assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0); + } + } + } + } + + dowork (); + + /* + * Terminate threads + */ + todo = -2; /* please terminate */ + dosync(); + + for (i = 0; i < nthreads; ++i) + { + if (0 == tcs[i].stat) + assert(pthread_join (tcs[i].thread, NULL) == 0); + } + + /* + * destroy locks + */ + assert(pthread_mutex_destroy (&mutex_stdout) == 0); + assert(pthread_mutex_destroy (&mutex_todo) == 0); + + /* + * Cleanup + */ + printf ("\n"); + + /* + * Show results + */ + for (i = 0; i < nthreads; ++i) + { + printf ("%2d ", i); + if (0 == tcs[i].stat) + printf ("%10ld\n", tcs[i].work); + else + printf ("failed %d\n", tcs[i].stat); + + assert(pthread_mutex_unlock(&tcs[i].mutex_start) == 0); + + assert(pthread_mutex_destroy (&tcs[i].mutex_start) == 0); + assert(pthread_mutex_destroy (&tcs[i].mutex_started) == 0); + assert(pthread_mutex_destroy (&tcs[i].mutex_end) == 0); + assert(pthread_mutex_destroy (&tcs[i].mutex_ended) == 0); + } + + die (0); + + return (0); +} diff --git a/pthreads/tests/inherit1.c b/pthreads/tests/inherit1.c new file mode 100644 index 000000000..482a5a884 --- /dev/null +++ b/pthreads/tests/inherit1.c @@ -0,0 +1,177 @@ +/* + * File: inherit1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority inheritance. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; + + +void * func(void * arg) +{ + int policy; + struct sched_param param; + + assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); + return (void *) param.sched_priority; +} + + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t thread = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(thread); + struct sched_param param; + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + param.sched_priority = prioSet; + assert(pthread_setschedparam(thread, SCHED_OTHER, ¶m) == 0); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + } + + return (void *) 0; +} + + +int +main() +{ + pthread_t t; + pthread_t mainThread = pthread_self(); + pthread_attr_t attr; + void * result = NULL; + struct sched_param param; + struct sched_param mainParam; + int prio; + int policy; + int inheritsched = -1; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); + + assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); + assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED) == 0); + assert(pthread_attr_getinheritsched(&attr, &inheritsched) == 0); + assert(inheritsched == PTHREAD_INHERIT_SCHED); + + for (prio = minPrio; prio <= maxPrio; prio++) + { + mainParam.sched_priority = prio; + + /* Set the thread's priority to a known initial value. */ + SetThreadPriority(threadH, PTW32TEST_THREAD_INIT_PRIO); + + /* Change the main thread priority */ + assert(pthread_setschedparam(mainThread, SCHED_OTHER, &mainParam) == 0); + assert(pthread_getschedparam(mainThread, &policy, &mainParam) == 0); + assert(policy == SCHED_OTHER); + /* Priority returned below should be the level set by pthread_setschedparam(). */ + assert(mainParam.sched_priority == prio); + assert(GetThreadPriority(threadH) == + validPriorities[prio+(PTW32TEST_MAXPRIORITIES/2)]); + + for (param.sched_priority = prio; + param.sched_priority <= maxPrio; + param.sched_priority++) + { + /* The new thread create should ignore this new priority */ + assert(pthread_attr_setschedparam(&attr, ¶m) == 0); + assert(pthread_create(&t, &attr, func, NULL) == 0); + pthread_join(t, &result); + assert((int) result == mainParam.sched_priority); + } + } + + return 0; +} diff --git a/pthreads/tests/join0.c b/pthreads/tests/join0.c new file mode 100644 index 000000000..a6cb25dcc --- /dev/null +++ b/pthreads/tests/join0.c @@ -0,0 +1,67 @@ +/* + * Test for pthread_join(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_exit(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + Sleep(2000); + + pthread_exit(arg); + + /* Never reached. */ + exit(1); +} + +int +main(int argc, char * argv[]) +{ + pthread_t id; + int result; + + /* Create a single thread and wait for it to exit. */ + assert(pthread_create(&id, NULL, func, (void *) 123) == 0); + + assert(pthread_join(id, (void **) &result) == 0); + + assert(result == 123); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/join1.c b/pthreads/tests/join1.c new file mode 100644 index 000000000..8b11e9503 --- /dev/null +++ b/pthreads/tests/join1.c @@ -0,0 +1,78 @@ +/* + * Test for pthread_join(). + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(), pthread_join(), pthread_exit(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + int i = (int) arg; + + Sleep(i * 100); + + pthread_exit(arg); + + /* Never reached. */ + exit(1); +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + /* Some threads will finish before they are joined, some after. */ + Sleep(2 * 100 + 50); + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/join2.c b/pthreads/tests/join2.c new file mode 100644 index 000000000..4fa30129e --- /dev/null +++ b/pthreads/tests/join2.c @@ -0,0 +1,69 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + Sleep(1000); + return arg; +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/join3.c b/pthreads/tests/join3.c new file mode 100644 index 000000000..70cf3e97f --- /dev/null +++ b/pthreads/tests/join3.c @@ -0,0 +1,75 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + sched_yield(); + return arg; +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + /* + * Let threads exit before we join them. + * We should still retrieve the exit code for the threads. + */ + Sleep(1000); + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void **) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/kill1.c b/pthreads/tests/kill1.c new file mode 100644 index 000000000..fd1eaee2b --- /dev/null +++ b/pthreads/tests/kill1.c @@ -0,0 +1,83 @@ +/* + * File: kill1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - pthread_kill() does not support non zero signals.. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + + +int +main() +{ + assert(pthread_kill(pthread_self(), 1) == EINVAL); + + return 0; +} diff --git a/pthreads/tests/loadfree.c b/pthreads/tests/loadfree.c new file mode 100644 index 000000000..65bb15c7b --- /dev/null +++ b/pthreads/tests/loadfree.c @@ -0,0 +1,70 @@ +/* + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * From: Todd Owen <towen@lucidcalm.dropbear.id.au> + * To: pthreads-win32@sourceware.cygnus.com + * Subject: invalid page fault when using LoadLibrary/FreeLibrary + * + * hi, + * for me, pthread.dll consistently causes an "invalid page fault in + * kernel32.dll" when I load it "explicitly"...to be precise, loading (with + * LoadLibrary) isn't a problem, it gives the error when I call FreeLibrary. + * I guess that the dll's cleanup must be causing the error. + * + * Implicit linkage of the dll has never given me this problem. Here's a + * program (console application) that gives me the error. + * + * I compile with: mingw32 (gcc-2.95 release), with the MSVCRT add-on (not + * that the compiler should make much difference in this case). + * PTHREAD.DLL: is the precompiled 1999-11-02 one (I tried an older one as + * well, with the same result). + * + * Fascinatingly, if you have your own dll (mycode.dll) which implicitly + * loads pthread.dll, and then do LoadLibrary/FreeLibrary on _this_ dll, the + * same thing happens. + * + */ + +#include "test.h" + +int main() { + HINSTANCE hinst; + + assert((hinst = LoadLibrary("pthread")) != (HINSTANCE) 0); + + Sleep(100); + + FreeLibrary(hinst); + return 0; +} + diff --git a/pthreads/tests/mutex1.c b/pthreads/tests/mutex1.c new file mode 100644 index 000000000..918c90330 --- /dev/null +++ b/pthreads/tests/mutex1.c @@ -0,0 +1,68 @@ +/* + * mutex1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create a simple mutex object, lock it, and then unlock it again. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + * pthread_mutex_destroy() + */ + +#include "test.h" + +pthread_mutex_t mutex = NULL; + +int +main() +{ + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex1e.c b/pthreads/tests/mutex1e.c new file mode 100644 index 000000000..e52810728 --- /dev/null +++ b/pthreads/tests/mutex1e.c @@ -0,0 +1,74 @@ +/* + * mutex1e.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_ERRORCHECK. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include "test.h" + +pthread_mutex_t mutex = NULL; +pthread_mutexattr_t mxAttr; + +int +main() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex1n.c b/pthreads/tests/mutex1n.c new file mode 100644 index 000000000..74850d6c8 --- /dev/null +++ b/pthreads/tests/mutex1n.c @@ -0,0 +1,74 @@ +/* + * mutex1n.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_NORMAL. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include "test.h" + +pthread_mutex_t mutex = NULL; +pthread_mutexattr_t mxAttr; + +int +main() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex1r.c b/pthreads/tests/mutex1r.c new file mode 100644 index 000000000..0666dec0d --- /dev/null +++ b/pthreads/tests/mutex1r.c @@ -0,0 +1,74 @@ +/* + * mutex1r.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * As for mutex1.c but with type set to PTHREAD_MUTEX_RECURSIVE. + * + * Create a simple mutex object, lock it, unlock it, then destroy it. + * This is the simplest test of the pthread mutex family that we can do. + * + * Depends on API functions: + * pthread_mutexattr_settype() + * pthread_mutex_init() + * pthread_mutex_destroy() + */ + +#include "test.h" + +pthread_mutex_t mutex = NULL; +pthread_mutexattr_t mxAttr; + +int +main() +{ + assert(pthread_mutexattr_init(&mxAttr) == 0); + + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + + assert(mutex == NULL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(mutex != NULL); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex2.c b/pthreads/tests/mutex2.c new file mode 100644 index 000000000..377468e90 --- /dev/null +++ b/pthreads/tests/mutex2.c @@ -0,0 +1,66 @@ +/* + * mutex2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +int +main() +{ + assert(mutex == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex2e.c b/pthreads/tests/mutex2e.c new file mode 100644 index 000000000..7df6073d2 --- /dev/null +++ b/pthreads/tests/mutex2e.c @@ -0,0 +1,66 @@ +/* + * mutex2e.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +int +main() +{ + assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex2r.c b/pthreads/tests/mutex2r.c new file mode 100644 index 000000000..c96e366f1 --- /dev/null +++ b/pthreads/tests/mutex2r.c @@ -0,0 +1,66 @@ +/* + * mutex2r.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +int +main() +{ + assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(mutex != PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(mutex != NULL); + + assert(pthread_mutex_unlock(&mutex) == 0); + + assert(pthread_mutex_destroy(&mutex) == 0); + + assert(mutex == NULL); + + return 0; +} diff --git a/pthreads/tests/mutex3.c b/pthreads/tests/mutex3.c new file mode 100644 index 000000000..bc1429e0b --- /dev/null +++ b/pthreads/tests/mutex3.c @@ -0,0 +1,75 @@ +/* + * mutex3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/mutex3e.c b/pthreads/tests/mutex3e.c new file mode 100644 index 000000000..66cfcb71c --- /dev/null +++ b/pthreads/tests/mutex3e.c @@ -0,0 +1,75 @@ +/* + * mutex3e.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex1 = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/mutex3r.c b/pthreads/tests/mutex3r.c new file mode 100644 index 000000000..8fa7f2547 --- /dev/null +++ b/pthreads/tests/mutex3r.c @@ -0,0 +1,75 @@ +/* + * mutex3r.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static mutex object, lock it, trylock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +pthread_mutex_t mutex1 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_mutex_trylock(&mutex1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_lock(&mutex1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_mutex_unlock(&mutex1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/mutex4.c b/pthreads/tests/mutex4.c new file mode 100644 index 000000000..547d9cb73 --- /dev/null +++ b/pthreads/tests/mutex4.c @@ -0,0 +1,111 @@ +/* + * mutex4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Thread A locks mutex - thread B tries to unlock. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int wasHere = 0; + +static pthread_mutex_t mutex1; + +void * unlocker(void * arg) +{ + int expectedResult = (int) arg; + + wasHere++; + assert(pthread_mutex_unlock(&mutex1) == expectedResult); + wasHere++; + return NULL; +} + +int +main() +{ + pthread_t t; + pthread_mutexattr_t ma; + + assert(pthread_mutexattr_init(&ma) == 0); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_DEFAULT) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + /* + * NORMAL (fast) mutexes don't check ownership. + */ + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(wasHere == 2); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + /* + * NORMAL (fast) mutexes don't check ownership. + */ + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == EPERM); + assert(wasHere == 2); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(wasHere == 2); + + wasHere = 0; + assert(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&mutex1, &ma) == 0); + assert(pthread_mutex_lock(&mutex1) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) EPERM) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_mutex_unlock(&mutex1) == 0); + assert(wasHere == 2); + + return 0; +} diff --git a/pthreads/tests/mutex5.c b/pthreads/tests/mutex5.c new file mode 100644 index 000000000..a71f9d893 --- /dev/null +++ b/pthreads/tests/mutex5.c @@ -0,0 +1,67 @@ +/* + * mutex5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Confirm the equality/inequality of the various mutex types, + * and the default not-set value. + */ + +#include "test.h" + +static pthread_mutexattr_t mxAttr; + +/* Prevent optimiser from removing dead or obvious asserts. */ +int _optimiseFoil; +#define FOIL(x) (_optimiseFoil = x) + +int +main() +{ + int mxType = -1; + + assert(FOIL(PTHREAD_MUTEX_DEFAULT) == PTHREAD_MUTEX_NORMAL); + assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_ERRORCHECK); + assert(FOIL(PTHREAD_MUTEX_DEFAULT) != PTHREAD_MUTEX_RECURSIVE); + assert(FOIL(PTHREAD_MUTEX_RECURSIVE) != PTHREAD_MUTEX_ERRORCHECK); + + assert(FOIL(PTHREAD_MUTEX_NORMAL) == PTHREAD_MUTEX_FAST_NP); + assert(FOIL(PTHREAD_MUTEX_RECURSIVE) == PTHREAD_MUTEX_RECURSIVE_NP); + assert(FOIL(PTHREAD_MUTEX_ERRORCHECK) == PTHREAD_MUTEX_ERRORCHECK_NP); + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + return 0; +} diff --git a/pthreads/tests/mutex6.c b/pthreads/tests/mutex6.c new file mode 100644 index 000000000..15649fc8d --- /dev/null +++ b/pthreads/tests/mutex6.c @@ -0,0 +1,93 @@ +/* + * mutex6.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks mutex twice (recursive lock). + * Locking thread should deadlock on second attempt. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + Sleep (1000); + + assert(lockCount == 2); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex6e.c b/pthreads/tests/mutex6e.c new file mode 100644 index 000000000..8af9274f2 --- /dev/null +++ b/pthreads/tests/mutex6e.c @@ -0,0 +1,102 @@ +/* + * mutex6e.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type. + * Thread locks mutex twice (recursive lock). + * This should fail with an EDEADLK error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == EDEADLK); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + exit(0); + + /* Never reached */ + return 0; +} + diff --git a/pthreads/tests/mutex6es.c b/pthreads/tests/mutex6es.c new file mode 100644 index 000000000..0d879c4ea --- /dev/null +++ b/pthreads/tests/mutex6es.c @@ -0,0 +1,94 @@ +/* + * mutex6es.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK static mutex type. + * Thread locks mutex twice (recursive lock). + * This should fail with an EDEADLK error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == EDEADLK); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + + assert(mutex == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + + exit(0); + + /* Never reached */ + return 0; +} + diff --git a/pthreads/tests/mutex6n.c b/pthreads/tests/mutex6n.c new file mode 100644 index 000000000..9b4bbb920 --- /dev/null +++ b/pthreads/tests/mutex6n.c @@ -0,0 +1,104 @@ +/* + * mutex6n.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_NORMAL mutex type. + * Thread locks mutex twice (recursive lock). + * The thread should deadlock. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + Sleep (1000); + + assert(lockCount == 2); + + exit(0); + + /* Never reached */ + return 0; +} + diff --git a/pthreads/tests/mutex6r.c b/pthreads/tests/mutex6r.c new file mode 100644 index 000000000..4bf853f8d --- /dev/null +++ b/pthreads/tests/mutex6r.c @@ -0,0 +1,100 @@ +/* + * mutex6r.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type. + * Thread locks mutex twice (recursive lock). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex6rs.c b/pthreads/tests/mutex6rs.c new file mode 100644 index 000000000..4ebe44ef0 --- /dev/null +++ b/pthreads/tests/mutex6rs.c @@ -0,0 +1,92 @@ +/* + * mutex6rs.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE static mutex type. + * Thread locks mutex twice (recursive lock). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + + assert(mutex == PTHREAD_RECURSIVE_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex6s.c b/pthreads/tests/mutex6s.c new file mode 100644 index 000000000..8b82dc3fa --- /dev/null +++ b/pthreads/tests/mutex6s.c @@ -0,0 +1,93 @@ +/* + * mutex6s.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) static mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks mutex twice (recursive lock). + * Locking thread should deadlock on second attempt. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + + /* Should wait here (deadlocked) */ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(mutex == PTHREAD_MUTEX_INITIALIZER); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(1000); + + assert(lockCount == 1); + + /* + * Should succeed even though we don't own the lock + * because FAST mutexes don't check ownership. + */ + assert(pthread_mutex_unlock(&mutex) == 0); + + Sleep (1000); + + assert(lockCount == 2); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex7.c b/pthreads/tests/mutex7.c new file mode 100644 index 000000000..8772b9712 --- /dev/null +++ b/pthreads/tests/mutex7.c @@ -0,0 +1,82 @@ +/* + * mutex7.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) mutex type. + * Should be the same as PTHREAD_MUTEX_NORMAL. + * Thread locks then trylocks mutex (attempted recursive lock). + * The thread should lock first time and EBUSY second time. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_trylock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(1000); + + assert(lockCount == 2); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex7e.c b/pthreads/tests/mutex7e.c new file mode 100644 index 000000000..854789b9b --- /dev/null +++ b/pthreads/tests/mutex7e.c @@ -0,0 +1,102 @@ +/* + * mutex7e.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type. + * Thread locks and then trylocks mutex (attempted recursive lock). + * Trylock should fail with an EBUSY error. + * The second unlock attempt should fail with an EPERM error. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + exit(0); + + /* Never reached */ + return 0; +} + diff --git a/pthreads/tests/mutex7n.c b/pthreads/tests/mutex7n.c new file mode 100644 index 000000000..174355fca --- /dev/null +++ b/pthreads/tests/mutex7n.c @@ -0,0 +1,93 @@ +/* + * mutex7n.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_NORMAL mutex type. + * Thread locks then trylocks mutex (attempted recursive lock). + * The thread should lock first time and EBUSY second time. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == EBUSY); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == EPERM); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(1000); + + assert(lockCount == 2); + + exit(0); + + /* Never reached */ + return 0; +} + diff --git a/pthreads/tests/mutex7r.c b/pthreads/tests/mutex7r.c new file mode 100644 index 000000000..f9e5ff0e2 --- /dev/null +++ b/pthreads/tests/mutex7r.c @@ -0,0 +1,100 @@ +/* + * mutex7r.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type. + * Thread locks mutex then trylocks mutex (recursive lock twice). + * Both locks and unlocks should succeed. + * + * Depends on API functions: + * pthread_create() + * pthread_join() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_unlock() + */ + +#include "test.h" + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + assert(pthread_mutex_lock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_trylock(&mutex) == 0); + lockCount++; + assert(pthread_mutex_unlock(&mutex) == 0); + assert(pthread_mutex_unlock(&mutex) == 0); + + return (void *) 555; +} + +int +main() +{ + pthread_t t; + int result = 0; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result == 555); + + assert(lockCount == 2); + + assert(pthread_mutex_destroy(&mutex) == 0); + assert(pthread_mutexattr_destroy(&mxAttr) == 0); + + exit(0); + + /* Never reached */ + return 0; +} diff --git a/pthreads/tests/mutex8.c b/pthreads/tests/mutex8.c new file mode 100644 index 000000000..5ca99822e --- /dev/null +++ b/pthreads/tests/mutex8.c @@ -0,0 +1,82 @@ +/* + * mutex8.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Test the default (type not set) mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static int lockCount = 0; + +static pthread_mutex_t mutex; + +void * locker(void * arg) +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_mutex_init(&mutex, NULL) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} diff --git a/pthreads/tests/mutex8e.c b/pthreads/tests/mutex8e.c new file mode 100644 index 000000000..b99d24edd --- /dev/null +++ b/pthreads/tests/mutex8e.c @@ -0,0 +1,97 @@ +/* + * mutex8e.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_ERRORCHECK mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +main() +{ + pthread_t t; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_ERRORCHECK) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_ERRORCHECK); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + diff --git a/pthreads/tests/mutex8n.c b/pthreads/tests/mutex8n.c new file mode 100644 index 000000000..3cfdae620 --- /dev/null +++ b/pthreads/tests/mutex8n.c @@ -0,0 +1,97 @@ +/* + * mutex8n.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_NORMAL mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +main() +{ + pthread_t t; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_NORMAL) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_NORMAL); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + diff --git a/pthreads/tests/mutex8r.c b/pthreads/tests/mutex8r.c new file mode 100644 index 000000000..d1328cad9 --- /dev/null +++ b/pthreads/tests/mutex8r.c @@ -0,0 +1,97 @@ +/* + * mutex8r.c + * + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright (C) 1998 Ben Elliston and Ross Johnson + * Copyright (C) 1999,2000,2001 Ross Johnson + * + * Contact Email: rpj@ise.canberra.edu.au + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------- + * + * Tests PTHREAD_MUTEX_RECURSIVE mutex type exercising timedlock. + * Thread locks mutex, another thread timedlocks the mutex. + * Timed thread should timeout. + * + * Depends on API functions: + * pthread_create() + * pthread_mutexattr_init() + * pthread_mutexattr_destroy() + * pthread_mutexattr_settype() + * pthread_mutexattr_gettype() + * pthread_mutex_init() + * pthread_mutex_destroy() + * pthread_mutex_lock() + * pthread_mutex_timedlock() + * pthread_mutex_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static int lockCount = 0; + +static pthread_mutex_t mutex; +static pthread_mutexattr_t mxAttr; + +void * locker(void * arg) +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_mutex_timedlock(&mutex, &abstime) == ETIMEDOUT); + + lockCount++; + + return 0; +} + +int +main() +{ + pthread_t t; + int mxType = -1; + + assert(pthread_mutexattr_init(&mxAttr) == 0); + assert(pthread_mutexattr_settype(&mxAttr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutexattr_gettype(&mxAttr, &mxType) == 0); + assert(mxType == PTHREAD_MUTEX_RECURSIVE); + + assert(pthread_mutex_init(&mutex, &mxAttr) == 0); + + assert(pthread_mutex_lock(&mutex) == 0); + + assert(pthread_create(&t, NULL, locker, NULL) == 0); + + Sleep(2000); + + assert(lockCount == 1); + + assert(pthread_mutex_unlock(&mutex) == 0); + + return 0; +} + diff --git a/pthreads/tests/once1.c b/pthreads/tests/once1.c new file mode 100644 index 000000000..daec112d7 --- /dev/null +++ b/pthreads/tests/once1.c @@ -0,0 +1,77 @@ +/* + * once1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create a static pthread_once and test that it calls myfunc once. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + */ + +#include "test.h" + +pthread_once_t once = PTHREAD_ONCE_INIT; + +static int washere = 0; + +void +myfunc(void) +{ + washere++; +} + +void * +mythread(void * arg) +{ + assert(pthread_once(&once, myfunc) == 0); + + return 0; +} + +int +main() +{ + pthread_t t1, t2; + + assert(pthread_create(&t1, NULL, mythread, NULL) == 0); + + assert(pthread_create(&t2, NULL, mythread, NULL) == 0); + + Sleep(2000); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/once2.c b/pthreads/tests/once2.c new file mode 100644 index 000000000..248ccb1a7 --- /dev/null +++ b/pthreads/tests/once2.c @@ -0,0 +1,109 @@ +/* + * once2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create several static pthread_once objects and channel several threads + * through each. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + */ + +#include "test.h" + +#define NUM_THREADS 100 /* Targeting each once control */ +#define NUM_ONCE 10 + +pthread_once_t o = PTHREAD_ONCE_INIT; +pthread_once_t once[NUM_ONCE]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t numOnce = {0, {0}}; +static sharedInt_t numThreads = {0, {0}}; + +void +myfunc(void) +{ + EnterCriticalSection(&numOnce.cs); + numOnce.i++; + LeaveCriticalSection(&numOnce.cs); + /* Simulate slow once routine so that following threads pile up behind it */ + Sleep(100); +} + +void * +mythread(void * arg) +{ + assert(pthread_once(&once[(int) arg], myfunc) == 0); + EnterCriticalSection(&numThreads.cs); + numThreads.i++; + LeaveCriticalSection(&numThreads.cs); + return 0; +} + +int +main() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + + InitializeCriticalSection(&numThreads.cs); + InitializeCriticalSection(&numOnce.cs); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 0); + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if (pthread_join(t[i][j], NULL) != 0) + printf("Join failed for [thread,once] = [%d,%d]\n", i, j); + + assert(numOnce.i == NUM_ONCE); + assert(numThreads.i == NUM_THREADS * NUM_ONCE); + + DeleteCriticalSection(&numOnce.cs); + DeleteCriticalSection(&numThreads.cs); + + return 0; +} diff --git a/pthreads/tests/once3.c b/pthreads/tests/once3.c new file mode 100644 index 000000000..981bbf7d8 --- /dev/null +++ b/pthreads/tests/once3.c @@ -0,0 +1,132 @@ +/* + * once3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create several pthread_once objects and channel several threads + * through each. Make the init_routine cancelable and cancel them with + * waiters waiting. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + * pthread_testcancel() + * pthread_cancel() + * pthread_once() + */ + +#define ASSERT_TRACE + +#include "test.h" + +#define NUM_THREADS 100 /* Targeting each once control */ +#define NUM_ONCE 10 + +pthread_once_t o = PTHREAD_ONCE_INIT; +pthread_once_t once[NUM_ONCE]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t numOnce = {0, {0}}; +static sharedInt_t numThreads = {0, {0}}; + +void +myfunc(void) +{ + EnterCriticalSection(&numOnce.cs); + numOnce.i++; + assert(numOnce.i > 0); + LeaveCriticalSection(&numOnce.cs); + /* Simulate slow once routine so that following threads pile up behind it */ + Sleep(10); + /* test for cancelation late so we're sure to have waiters. */ + pthread_testcancel(); +} + +void * +mythread(void * arg) +{ + /* + * Cancel every thread. These threads are deferred cancelable only, so + * only the thread performing the once routine (my_func) will see it (there are + * no other cancelation points here). The result will be that every thread + * eventually cancels only when it becomes the new once thread. + */ + assert(pthread_cancel(pthread_self()) == 0); + assert(pthread_once(&once[(int) arg], myfunc) == 0); + EnterCriticalSection(&numThreads.cs); + numThreads.i++; + LeaveCriticalSection(&numThreads.cs); + return 0; +} + +int +main() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + + InitializeCriticalSection(&numThreads.cs); + InitializeCriticalSection(&numOnce.cs); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + { + assert(pthread_create(&t[i][j], NULL, mythread, (void *) j) == 0); + } + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if (pthread_join(t[i][j], NULL) != 0) + printf("Join failed for [thread,once] = [%d,%d]\n", i, j); + + /* + * All threads will cancel, none will return normally from + * pthread_once and so numThreads should never be incremented. However, + * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE). + */ + assert(numOnce.i == NUM_ONCE * NUM_THREADS); + assert(numThreads.i == 0); + + DeleteCriticalSection(&numOnce.cs); + DeleteCriticalSection(&numThreads.cs); + + return 0; +} diff --git a/pthreads/tests/once4.c b/pthreads/tests/once4.c new file mode 100644 index 000000000..f5be64486 --- /dev/null +++ b/pthreads/tests/once4.c @@ -0,0 +1,191 @@ +/* + * once4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create several pthread_once objects and channel several threads + * through each. Make the init_routine cancelable and cancel them + * waiters waiting. Vary the priorities. + * + * Depends on API functions: + * pthread_once() + * pthread_create() + * pthread_testcancel() + * pthread_cancel() + * pthread_once() + */ + +#include "test.h" + +#define NUM_THREADS 100 /* Targeting each once control */ +#define NUM_ONCE 10 + +pthread_once_t o = PTHREAD_ONCE_INIT; +pthread_once_t once[NUM_ONCE]; + +typedef struct { + int i; + CRITICAL_SECTION cs; +} sharedInt_t; + +static sharedInt_t numOnce = {0, {0}}; +static sharedInt_t numThreads = {0, {0}}; + +typedef struct { + int threadnum; + int oncenum; + int myPrio; + HANDLE w32Thread; +} bag_t; + +static bag_t threadbag[NUM_THREADS][NUM_ONCE]; + +CRITICAL_SECTION print_lock; + +void +mycleanupfunc(void * arg) +{ + bag_t * bag = (bag_t *) arg; + EnterCriticalSection(&print_lock); + /* once thrd prio error */ + printf("%4d %4d %4d %4d\n", + bag->oncenum, + bag->threadnum, + bag->myPrio, + bag->myPrio - GetThreadPriority(bag->w32Thread)); + LeaveCriticalSection(&print_lock); +} + +void +myinitfunc(void) +{ + EnterCriticalSection(&numOnce.cs); + numOnce.i++; + LeaveCriticalSection(&numOnce.cs); + /* Simulate slow once routine so that following threads pile up behind it */ + Sleep(10); + /* test for cancelation late so we're sure to have waiters. */ + pthread_testcancel(); +} + +void * +mythread(void * arg) +{ + bag_t * bag = (bag_t *) arg; + struct sched_param param; + + /* + * Cancel every thread. These threads are deferred cancelable only, so + * only the thread performing the init_routine will see it (there are + * no other cancelation points here). The result will be that every thread + * eventually cancels only when it becomes the new initter. + */ + pthread_t self = pthread_self(); + bag->w32Thread = pthread_getw32threadhandle_np(self); + /* + * Set priority between -2 and 2 inclusive. + */ + bag->myPrio = (bag->threadnum % 5) - 2; + param.sched_priority = bag->myPrio; + pthread_setschedparam(self, SCHED_OTHER, ¶m); + + /* Trigger a cancellation at the next cancellation point in this thread */ + pthread_cancel(self); +#if 0 + pthread_cleanup_push(mycleanupfunc, arg); + assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0); + pthread_cleanup_pop(1); +#else + assert(pthread_once(&once[bag->oncenum], myinitfunc) == 0); +#endif + EnterCriticalSection(&numThreads.cs); + numThreads.i++; + LeaveCriticalSection(&numThreads.cs); + return 0; +} + +int +main() +{ + pthread_t t[NUM_THREADS][NUM_ONCE]; + int i, j; + + InitializeCriticalSection(&print_lock); + InitializeCriticalSection(&numThreads.cs); + InitializeCriticalSection(&numOnce.cs); + +#if 0 + /* once thrd prio change */ + printf("once thrd prio error\n"); +#endif + + /* + * Set the priority class to realtime - otherwise normal + * Windows random priority boosting will obscure any problems. + */ + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + /* Set main thread to lower prio than threads */ + SetThreadPriority(GetCurrentThread(), -2); + + for (j = 0; j < NUM_ONCE; j++) + { + once[j] = o; + + for (i = 0; i < NUM_THREADS; i++) + { + bag_t * bag = &threadbag[i][j]; + bag->threadnum = i; + bag->oncenum = j; + assert(pthread_create(&t[i][j], NULL, mythread, (void *) bag) == 0); + } + } + + for (j = 0; j < NUM_ONCE; j++) + for (i = 0; i < NUM_THREADS; i++) + if (pthread_join(t[i][j], NULL) != 0) + printf("Join failed for [thread,once] = [%d,%d]\n", i, j); + + /* + * All threads will cancel, none will return normally from + * pthread_once and so numThreads should never be incremented. However, + * numOnce should be incremented by every thread (NUM_THREADS*NUM_ONCE). + */ + assert(numOnce.i == NUM_ONCE * NUM_THREADS); + assert(numThreads.i == 0); + + DeleteCriticalSection(&numOnce.cs); + DeleteCriticalSection(&numThreads.cs); + DeleteCriticalSection(&print_lock); + + return 0; +} diff --git a/pthreads/tests/priority1.c b/pthreads/tests/priority1.c new file mode 100644 index 000000000..c270e998a --- /dev/null +++ b/pthreads/tests/priority1.c @@ -0,0 +1,172 @@ +/* + * File: priority1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority explicit setting using thread attribute. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; + +void * +func(void * arg) +{ + int policy; + struct sched_param param; + pthread_t threadID = pthread_self(); + + assert(pthread_getschedparam(threadID, &policy, ¶m) == 0); + assert(policy == SCHED_OTHER); + return (void *) (param.sched_priority); +} + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t threadID = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(threadID); + + printf("Using GetThreadPriority\n"); + printf("%10s %10s\n", "Set value", "Get value"); + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + if (prioSet < 0) + SetThreadPriority(threadH, THREAD_PRIORITY_LOWEST); + else + SetThreadPriority(threadH, THREAD_PRIORITY_HIGHEST); + SetThreadPriority(threadH, prioSet); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + printf("%10d %10d\n", prioSet, validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)]); + } + + return (void *) 0; +} + + +int +main() +{ + pthread_t t; + pthread_attr_t attr; + void * result = NULL; + struct sched_param param; + + assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); + assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0); + + /* Set the thread's priority to a known initial value. */ + SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()), + PTW32TEST_THREAD_INIT_PRIO); + + printf("Using pthread_getschedparam\n"); + printf("%10s %10s %10s\n", "Set value", "Get value", "Win priority"); + + for (param.sched_priority = minPrio; + param.sched_priority <= maxPrio; + param.sched_priority++) + { + int prio; + + assert(pthread_attr_setschedparam(&attr, ¶m) == 0); + assert(pthread_create(&t, &attr, func, (void *) &attr) == 0); + + assert((prio = GetThreadPriority(pthread_getw32threadhandle_np(t))) + == validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); + + assert(pthread_join(t, &result) == 0); + + assert(param.sched_priority == (int) result); + printf("%10d %10d %10d\n", param.sched_priority, (int) result, prio); + } + + return 0; +} diff --git a/pthreads/tests/priority2.c b/pthreads/tests/priority2.c new file mode 100644 index 000000000..a5575abe9 --- /dev/null +++ b/pthreads/tests/priority2.c @@ -0,0 +1,169 @@ +/* + * File: priority2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test thread priority setting after creation. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + PTW32TEST_THREAD_INIT_PRIO = 0, + PTW32TEST_MAXPRIORITIES = 512 +}; + +int minPrio; +int maxPrio; +int validPriorities[PTW32TEST_MAXPRIORITIES]; +pthread_barrier_t startBarrier, endBarrier; + +void * func(void * arg) +{ + int policy; + int result; + struct sched_param param; + + result = pthread_barrier_wait(&startBarrier); + assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD); + assert(pthread_getschedparam(pthread_self(), &policy, ¶m) == 0); + assert(policy == SCHED_OTHER); + result = pthread_barrier_wait(&endBarrier); + assert(result == 0 || result == PTHREAD_BARRIER_SERIAL_THREAD); + return (void *) param.sched_priority; +} + + +void * +getValidPriorities(void * arg) +{ + int prioSet; + pthread_t thread = pthread_self(); + HANDLE threadH = pthread_getw32threadhandle_np(thread); + struct sched_param param; + + for (prioSet = minPrio; + prioSet <= maxPrio; + prioSet++) + { + /* + * If prioSet is invalid then the threads priority is unchanged + * from the previous value. Make the previous value a known + * one so that we can check later. + */ + param.sched_priority = prioSet; + assert(pthread_setschedparam(thread, SCHED_OTHER, ¶m) == 0); + validPriorities[prioSet+(PTW32TEST_MAXPRIORITIES/2)] = GetThreadPriority(threadH); + } + + return (void *) 0; +} + + +int +main() +{ + pthread_t t; + void * result = NULL; + int result2; + struct sched_param param; + + assert((maxPrio = sched_get_priority_max(SCHED_OTHER)) != -1); + assert((minPrio = sched_get_priority_min(SCHED_OTHER)) != -1); + + assert(pthread_create(&t, NULL, getValidPriorities, NULL) == 0); + assert(pthread_join(t, &result) == 0); + + assert(pthread_barrier_init(&startBarrier, NULL, 2) == 0); + assert(pthread_barrier_init(&endBarrier, NULL, 2) == 0); + + /* Set the thread's priority to a known initial value. + * If the new priority is invalid then the threads priority + * is unchanged from the previous value. + */ + SetThreadPriority(pthread_getw32threadhandle_np(pthread_self()), + PTW32TEST_THREAD_INIT_PRIO); + + for (param.sched_priority = minPrio; + param.sched_priority <= maxPrio; + param.sched_priority++) + { + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_setschedparam(t, SCHED_OTHER, ¶m) == 0); + result2 = pthread_barrier_wait(&startBarrier); + assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD); + result2 = pthread_barrier_wait(&endBarrier); + assert(result2 == 0 || result2 == PTHREAD_BARRIER_SERIAL_THREAD); + assert(GetThreadPriority(pthread_getw32threadhandle_np(t)) == + validPriorities[param.sched_priority+(PTW32TEST_MAXPRIORITIES/2)]); + pthread_join(t, &result); + assert(param.sched_priority == (int)result); + } + + return 0; +} diff --git a/pthreads/tests/reuse1.c b/pthreads/tests/reuse1.c new file mode 100644 index 000000000..ae9efe400 --- /dev/null +++ b/pthreads/tests/reuse1.c @@ -0,0 +1,124 @@ +/* + * File: reuse1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Confirm that thread reuse works for joined threads. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + NUMTHREADS = 100 +}; + +static int washere = 0; + +void * func(void * arg) +{ + washere = 1; + return arg; +} + +int +main() +{ + pthread_t t, + last_t; + pthread_attr_t attr; + void * result = NULL; + int i; + + assert(pthread_attr_init(&attr) == 0);; + assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0); + + washere = 0; + assert(pthread_create(&t, &attr, func, NULL) == 0); + assert(pthread_join(t, &result) == 0);; + assert(result == 0); + assert(washere == 1); + last_t = t; + + for (i = 1; i < NUMTHREADS; i++) + { + washere = 0; + assert(pthread_create(&t, &attr, func, (void *) i) == 0); + pthread_join(t, &result); + assert((int) result == i); + assert(washere == 1); + /* thread IDs should be unique */ + assert(!pthread_equal(t, last_t)); + /* thread struct pointers should be the same */ + assert(t.p == last_t.p); + /* thread handle reuse counter should be different by one */ + assert(t.x == last_t.x+1); + last_t = t; + } + + return 0; +} diff --git a/pthreads/tests/reuse2.c b/pthreads/tests/reuse2.c new file mode 100644 index 000000000..c4db81199 --- /dev/null +++ b/pthreads/tests/reuse2.c @@ -0,0 +1,167 @@ +/* + * File: reuse2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that thread reuse works for detached threads. + * - Analyse thread struct reuse. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - This test is implementation specific + * because it uses knowledge of internals that should be + * opaque to an application. + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +/* + */ + +enum { + NUMTHREADS = 10000 +}; + + +static long done = 0; + +void * func(void * arg) +{ + sched_yield(); + + InterlockedIncrement(&done); + + return (void *) 0; +} + +int +main() +{ + pthread_t t[NUMTHREADS]; + pthread_attr_t attr; + int i; + unsigned int notUnique = 0, + totalHandles = 0, + reuseMax = 0, + reuseMin = NUMTHREADS; + + assert(pthread_attr_init(&attr) == 0); + assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + + for (i = 0; i < NUMTHREADS; i++) + { + assert(pthread_create(&t[i], &attr, func, NULL) == 0); + } + + while (NUMTHREADS > InterlockedExchangeAdd((LPLONG)&done, 0L)) + Sleep(100); + + Sleep(100); + + /* + * Analyse reuse by computing min and max number of times pthread_create() + * returned the same pthread_t value. + */ + for (i = 0; i < NUMTHREADS; i++) + { + if (t[i].p != NULL) + { + unsigned int j, thisMax; + + thisMax = t[i].x; + + for (j = i+1; j < NUMTHREADS; j++) + if (t[i].p == t[j].p) + { + if (t[i].x == t[j].x) + notUnique++; + if (thisMax < t[j].x) + thisMax = t[j].x; + t[j].p = NULL; + } + + if (reuseMin > thisMax) + reuseMin = thisMax; + + if (reuseMax < thisMax) + reuseMax = thisMax; + } + } + + for (i = 0; i < NUMTHREADS; i++) + if (t[i].p != NULL) + totalHandles++; + + /* + * pthread_t reuse counts start at 0, so we need to add 1 + * to the max and min values derived above. + */ + printf("For %d total threads:\n", NUMTHREADS); + printf("Non-unique IDs = %d\n", notUnique); + printf("Reuse maximum = %d\n", reuseMax + 1); + printf("Reuse minimum = %d\n", reuseMin + 1); + printf("Total handles = %d\n", totalHandles); + + return 0; +} diff --git a/pthreads/tests/rwlock1.c b/pthreads/tests/rwlock1.c new file mode 100644 index 000000000..3d08ac993 --- /dev/null +++ b/pthreads/tests/rwlock1.c @@ -0,0 +1,61 @@ +/* + * rwlock1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create a simple rwlock object and then destroy it. + * + * Depends on API functions: + * pthread_rwlock_init() + * pthread_rwlock_destroy() + */ + +#include "test.h" + +pthread_rwlock_t rwlock = NULL; + +int +main() +{ + assert(rwlock == NULL); + + assert(pthread_rwlock_init(&rwlock, NULL) == 0); + + assert(rwlock != NULL); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/pthreads/tests/rwlock2.c b/pthreads/tests/rwlock2.c new file mode 100644 index 000000000..07518ebde --- /dev/null +++ b/pthreads/tests/rwlock2.c @@ -0,0 +1,66 @@ +/* + * rwlock2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + +int +main() +{ + assert(rwlock == PTHREAD_RWLOCK_INITIALIZER); + + assert(pthread_rwlock_rdlock(&rwlock) == 0); + + assert(rwlock != PTHREAD_RWLOCK_INITIALIZER); + + assert(rwlock != NULL); + + assert(pthread_rwlock_unlock(&rwlock) == 0); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/pthreads/tests/rwlock2_t.c b/pthreads/tests/rwlock2_t.c new file mode 100644 index 000000000..8e6ab6da0 --- /dev/null +++ b/pthreads/tests/rwlock2_t.c @@ -0,0 +1,78 @@ +/* + * rwlock2_t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-lock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; + +int +main() +{ + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(rwlock == PTHREAD_RWLOCK_INITIALIZER); + + assert(pthread_rwlock_timedrdlock(&rwlock, &abstime) == 0); + + assert(rwlock != PTHREAD_RWLOCK_INITIALIZER); + + assert(rwlock != NULL); + + assert(pthread_rwlock_unlock(&rwlock) == 0); + + assert(pthread_rwlock_destroy(&rwlock) == 0); + + assert(rwlock == NULL); + + return 0; +} diff --git a/pthreads/tests/rwlock3.c b/pthreads/tests/rwlock3.c new file mode 100644 index 000000000..4b22c5a16 --- /dev/null +++ b/pthreads/tests/rwlock3.c @@ -0,0 +1,76 @@ +/* + * rwlock3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, wrlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_wrlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock3_t.c b/pthreads/tests/rwlock3_t.c new file mode 100644 index 000000000..bc45abc4d --- /dev/null +++ b/pthreads/tests/rwlock3_t.c @@ -0,0 +1,87 @@ +/* + * rwlock3_t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-wrlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedwrlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedwrlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock4.c b/pthreads/tests/rwlock4.c new file mode 100644 index 000000000..edd9dc2c3 --- /dev/null +++ b/pthreads/tests/rwlock4.c @@ -0,0 +1,76 @@ +/* + * rwlock4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock4_t.c b/pthreads/tests/rwlock4_t.c new file mode 100644 index 000000000..37ec34fa3 --- /dev/null +++ b/pthreads/tests/rwlock4_t.c @@ -0,0 +1,87 @@ +/* + * rwlock4_t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-rdlock it, trywrlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_trywrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_trywrlock(&rwlock1) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock5.c b/pthreads/tests/rwlock5.c new file mode 100644 index 000000000..75b82f32a --- /dev/null +++ b/pthreads/tests/rwlock5.c @@ -0,0 +1,78 @@ +/* + * rwlock5.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, rdlock it, tryrdlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_tryrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_tryrdlock(&rwlock1) == 0); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock5_t.c b/pthreads/tests/rwlock5_t.c new file mode 100644 index 000000000..bf473a40e --- /dev/null +++ b/pthreads/tests/rwlock5_t.c @@ -0,0 +1,89 @@ +/* + * rwlock5_t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static rwlock object, timed-rdlock it, tryrdlock it, + * and then unlock it again. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_tryrdlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_rwlock_tryrdlock(&rwlock1) == 0); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + Sleep(2000); + + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/rwlock6.c b/pthreads/tests/rwlock6.c new file mode 100644 index 000000000..22d10db42 --- /dev/null +++ b/pthreads/tests/rwlock6.c @@ -0,0 +1,101 @@ +/* + * rwlock6.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Check writer and reader locking + * + * Depends on API functions: + * pthread_rwlock_rdlock() + * pthread_rwlock_wrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; + +void * wrfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + Sleep(2000); + bankAccount += 10; + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +void * rdfunc(void * arg) +{ + int ba; + + assert(pthread_rwlock_rdlock(&rwlock1) == 0); + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) ba); +} + +int +main() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt; + int wr1Result = 0; + int wr2Result = 0; + int rdResult = 0; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt, (void **) &rdResult) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + + assert(wr1Result == 10); + assert(rdResult == 10); + assert(wr2Result == 20); + + return 0; +} diff --git a/pthreads/tests/rwlock6_t.c b/pthreads/tests/rwlock6_t.c new file mode 100644 index 000000000..aa38bf564 --- /dev/null +++ b/pthreads/tests/rwlock6_t.c @@ -0,0 +1,126 @@ +/* + * rwlock6_t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Check writer and reader locking with reader timeouts + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_wrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; + +void * wrfunc(void * arg) +{ + assert(pthread_rwlock_wrlock(&rwlock1) == 0); + Sleep(2000); + bankAccount += 10; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + + return ((void *) bankAccount); +} + +void * rdfunc(void * arg) +{ + int ba = -1; + struct timespec abstime = { 0, 0 }; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + + if ((int) arg == 1) + { + abstime.tv_sec += 1; + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); + ba = 0; + } + else if ((int) arg == 2) + { + abstime.tv_sec += 3; + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == 0); + ba = bankAccount; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + } + + return ((void *) ba); +} + +int +main() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt1; + pthread_t rdt2; + int wr1Result = 0; + int wr2Result = 0; + int rd1Result = 0; + int rd2Result = 0; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&rdt1, NULL, rdfunc, (void *) 1) == 0); + Sleep(500); + assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); + Sleep(500); + assert(pthread_create(&rdt2, NULL, rdfunc, (void *) 2) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt1, (void **) &rd1Result) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + assert(pthread_join(rdt2, (void **) &rd2Result) == 0); + + assert(wr1Result == 10); + assert(rd1Result == 0); + assert(wr2Result == 20); + assert(rd2Result == 20); + + return 0; +} + + diff --git a/pthreads/tests/rwlock6_t2.c b/pthreads/tests/rwlock6_t2.c new file mode 100644 index 000000000..58bfc3d94 --- /dev/null +++ b/pthreads/tests/rwlock6_t2.c @@ -0,0 +1,119 @@ +/* + * rwlock6_t2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Check writer and reader timeouts. + * + * Depends on API functions: + * pthread_rwlock_timedrdlock() + * pthread_rwlock_timedwrlock() + * pthread_rwlock_unlock() + */ + +#include "test.h" +#include <sys/timeb.h> + +static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; + +static int bankAccount = 0; +struct timespec abstime = { 0, 0 }; + +void * wrfunc(void * arg) +{ + int result; + + result = pthread_rwlock_timedwrlock(&rwlock1, &abstime); + if ((int) arg == 1) + { + assert(result == 0); + Sleep(2000); + bankAccount += 10; + assert(pthread_rwlock_unlock(&rwlock1) == 0); + return ((void *) bankAccount); + } + else if ((int) arg == 2) + { + assert(result == ETIMEDOUT); + return ((void *) 100); + } + + return ((void *) -1); +} + +void * rdfunc(void * arg) +{ + int ba = 0; + + assert(pthread_rwlock_timedrdlock(&rwlock1, &abstime) == ETIMEDOUT); + + return ((void *) ba); +} + +int +main() +{ + pthread_t wrt1; + pthread_t wrt2; + pthread_t rdt; + int wr1Result = 0; + int wr2Result = 0; + int rdResult = 0; + struct _timeb currSysTime; + const DWORD NANOSEC_PER_MILLISEC = 1000000; + + _ftime(&currSysTime); + + abstime.tv_sec = currSysTime.time; + abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; + + abstime.tv_sec += 1; + + bankAccount = 0; + + assert(pthread_create(&wrt1, NULL, wrfunc, (void *) 1) == 0); + Sleep(100); + assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); + Sleep(100); + assert(pthread_create(&wrt2, NULL, wrfunc, (void *) 2) == 0); + + assert(pthread_join(wrt1, (void **) &wr1Result) == 0); + assert(pthread_join(rdt, (void **) &rdResult) == 0); + assert(pthread_join(wrt2, (void **) &wr2Result) == 0); + + assert(wr1Result == 10); + assert(rdResult == 0); + assert(wr2Result == 100); + + return 0; +} diff --git a/pthreads/tests/rwlock7.c b/pthreads/tests/rwlock7.c new file mode 100644 index 000000000..91466e4de --- /dev/null +++ b/pthreads/tests/rwlock7.c @@ -0,0 +1,199 @@ +/* + * rwlock7.c + * + * Hammer on a bunch of rwlocks to test robustness and fairness. + * Printed stats should be roughly even for each thread. + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#define THREADS 5 +#define DATASIZE 7 +#define ITERATIONS 1000000 + +/* + * Keep statistics for each thread. + */ +typedef struct thread_tag { + int thread_num; + pthread_t thread_id; + int updates; + int reads; + int changed; + int seed; +} thread_t; + +/* + * Read-write lock and shared data + */ +typedef struct data_tag { + pthread_rwlock_t lock; + int data; + int updates; +} data_t; + +static thread_t threads[THREADS]; +static data_t data[DATASIZE]; + +/* + * Thread start routine that uses read-write locks + */ +void *thread_routine (void *arg) +{ + thread_t *self = (thread_t*)arg; + int iteration; + int element = 0; + int seed = self->seed; + int interval = 1 + rand_r (&seed) % 71; + + self->changed = 0; + + for (iteration = 0; iteration < ITERATIONS; iteration++) + { + if (iteration % (ITERATIONS / 10) == 0) + { + putchar('.'); + fflush(stdout); + } + /* + * Each "self->interval" iterations, perform an + * update operation (write lock instead of read + * lock). + */ + if ((iteration % interval) == 0) + { + assert(pthread_rwlock_wrlock (&data[element].lock) == 0); + data[element].data = self->thread_num; + data[element].updates++; + self->updates++; + interval = 1 + rand_r (&seed) % 71; + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } else { + /* + * Look at the current data element to see whether + * the current thread last updated it. Count the + * times, to report later. + */ + assert(pthread_rwlock_rdlock (&data[element].lock) == 0); + + self->reads++; + + if (data[element].data != self->thread_num) + { + self->changed++; + interval = 1 + self->changed % 71; + } + + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + + element = (element + 1) % DATASIZE; + + } + + return NULL; +} + +int +main (int argc, char *argv[]) +{ + int count; + int data_count; + int thread_updates = 0; + int data_updates = 0; + int seed = 1; + + struct _timeb currSysTime1; + struct _timeb currSysTime2; + + /* + * Initialize the shared data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data[data_count].data = 0; + data[data_count].updates = 0; + + assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); + } + + _ftime(&currSysTime1); + + /* + * Create THREADS threads to access shared data. + */ + for (count = 0; count < THREADS; count++) + { + threads[count].thread_num = count; + threads[count].updates = 0; + threads[count].reads = 0; + threads[count].seed = 1 + rand_r (&seed) % 71; + + assert(pthread_create (&threads[count].thread_id, + NULL, thread_routine, (void*)&threads[count]) == 0); + } + + /* + * Wait for all threads to complete, and collect + * statistics. + */ + for (count = 0; count < THREADS; count++) + { + assert(pthread_join (threads[count].thread_id, NULL) == 0); + } + + putchar('\n'); + fflush(stdout); + + for (count = 0; count < THREADS; count++) + { + if (threads[count].changed > 0) + { + printf ("Thread %d found changed elements %d times\n", + count, threads[count].changed); + } + } + + putchar('\n'); + fflush(stdout); + + for (count = 0; count < THREADS; count++) + { + thread_updates += threads[count].updates; + printf ("%02d: seed %d, updates %d, reads %d\n", + count, threads[count].seed, + threads[count].updates, threads[count].reads); + } + + putchar('\n'); + fflush(stdout); + + /* + * Collect statistics for the data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data_updates += data[data_count].updates; + printf ("data %02d: value %d, %d updates\n", + data_count, data[data_count].data, data[data_count].updates); + assert(pthread_rwlock_destroy (&data[data_count].lock) == 0); + } + + printf ("%d thread updates, %d data updates\n", + thread_updates, data_updates); + + _ftime(&currSysTime2); + + printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", + currSysTime1.time,currSysTime1.millitm, + currSysTime2.time,currSysTime2.millitm, + (currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)); + + return 0; +} diff --git a/pthreads/tests/rwlock8.c b/pthreads/tests/rwlock8.c new file mode 100644 index 000000000..c83a775ce --- /dev/null +++ b/pthreads/tests/rwlock8.c @@ -0,0 +1,205 @@ +/* + * rwlock8.c + * + * Hammer on a bunch of rwlocks to test robustness and fairness. + * Printed stats should be roughly even for each thread. + * + * Yield during each access to exercise lock contention code paths + * more than rwlock7.c does (particularly on uni-processor systems). + */ + +#include "test.h" +#include <sys/timeb.h> + +#ifdef __GNUC__ +#include <stdlib.h> +#endif + +#define THREADS 5 +#define DATASIZE 7 +#define ITERATIONS 100000 + +/* + * Keep statistics for each thread. + */ +typedef struct thread_tag { + int thread_num; + pthread_t thread_id; + int updates; + int reads; + int changed; + int seed; +} thread_t; + +/* + * Read-write lock and shared data + */ +typedef struct data_tag { + pthread_rwlock_t lock; + int data; + int updates; +} data_t; + +static thread_t threads[THREADS]; +static data_t data[DATASIZE]; + +/* + * Thread start routine that uses read-write locks + */ +void *thread_routine (void *arg) +{ + thread_t *self = (thread_t*)arg; + int iteration; + int element = 0; + int seed = self->seed; + int interval = 1 + rand_r (&seed) % 71; + + self->changed = 0; + + for (iteration = 0; iteration < ITERATIONS; iteration++) + { + if (iteration % (ITERATIONS / 10) == 0) + { + putchar('.'); + fflush(stdout); + } + /* + * Each "self->interval" iterations, perform an + * update operation (write lock instead of read + * lock). + */ + if ((iteration % interval) == 0) + { + assert(pthread_rwlock_wrlock (&data[element].lock) == 0); + data[element].data = self->thread_num; + data[element].updates++; + self->updates++; + interval = 1 + rand_r (&seed) % 71; + sched_yield(); + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } else { + /* + * Look at the current data element to see whether + * the current thread last updated it. Count the + * times, to report later. + */ + assert(pthread_rwlock_rdlock (&data[element].lock) == 0); + + self->reads++; + + if (data[element].data != self->thread_num) + { + self->changed++; + interval = 1 + self->changed % 71; + } + + sched_yield(); + + assert(pthread_rwlock_unlock (&data[element].lock) == 0); + } + + element = (element + 1) % DATASIZE; + + } + + return NULL; +} + +int +main (int argc, char *argv[]) +{ + int count; + int data_count; + int thread_updates = 0; + int data_updates = 0; + int seed = 1; + + struct _timeb currSysTime1; + struct _timeb currSysTime2; + + /* + * Initialize the shared data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data[data_count].data = 0; + data[data_count].updates = 0; + + assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); + } + + _ftime(&currSysTime1); + + /* + * Create THREADS threads to access shared data. + */ + for (count = 0; count < THREADS; count++) + { + threads[count].thread_num = count; + threads[count].updates = 0; + threads[count].reads = 0; + threads[count].seed = 1 + rand_r (&seed) % 71; + + assert(pthread_create (&threads[count].thread_id, + NULL, thread_routine, (void*)&threads[count]) == 0); + } + + /* + * Wait for all threads to complete, and collect + * statistics. + */ + for (count = 0; count < THREADS; count++) + { + assert(pthread_join (threads[count].thread_id, NULL) == 0); + } + + putchar('\n'); + fflush(stdout); + + for (count = 0; count < THREADS; count++) + { + if (threads[count].changed > 0) + { + printf ("Thread %d found changed elements %d times\n", + count, threads[count].changed); + } + } + + putchar('\n'); + fflush(stdout); + + for (count = 0; count < THREADS; count++) + { + thread_updates += threads[count].updates; + printf ("%02d: seed %d, updates %d, reads %d\n", + count, threads[count].seed, + threads[count].updates, threads[count].reads); + } + + putchar('\n'); + fflush(stdout); + + /* + * Collect statistics for the data. + */ + for (data_count = 0; data_count < DATASIZE; data_count++) + { + data_updates += data[data_count].updates; + printf ("data %02d: value %d, %d updates\n", + data_count, data[data_count].data, data[data_count].updates); + assert(pthread_rwlock_destroy (&data[data_count].lock) == 0); + } + + printf ("%d thread updates, %d data updates\n", + thread_updates, data_updates); + + _ftime(&currSysTime2); + + printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", + currSysTime1.time,currSysTime1.millitm, + currSysTime2.time,currSysTime2.millitm, + (currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)); + + return 0; +} diff --git a/pthreads/tests/self1.c b/pthreads/tests/self1.c new file mode 100644 index 000000000..59498d97e --- /dev/null +++ b/pthreads/tests/self1.c @@ -0,0 +1,69 @@ +/* + * self1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test for pthread_self(). + * + * Depends on API functions: + * pthread_self() + * + * Implicitly depends on: + * pthread_getspecific() + * pthread_setspecific() + */ + +#include "test.h" + +int +main(int argc, char * argv[]) +{ + /* + * This should always succeed unless the system has no + * resources (memory) left. + */ + pthread_t self; + +#ifdef PTW32_STATIC_LIB + pthread_win32_process_attach_np(); +#endif + + self = pthread_self(); + + assert(self.p != NULL); + +#ifdef PTW32_STATIC_LIB + pthread_win32_process_detach_np(); +#endif + return 0; +} diff --git a/pthreads/tests/self2.c b/pthreads/tests/self2.c new file mode 100644 index 000000000..28e57252e --- /dev/null +++ b/pthreads/tests/self2.c @@ -0,0 +1,73 @@ +/* + * self2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test for pthread_self(). + * + * Depends on API functions: + * pthread_create() + * pthread_self() + * + * Implicitly depends on: + * pthread_getspecific() + * pthread_setspecific() + */ + +#include "test.h" +#include <string.h> + +static pthread_t me; + +void * +entry(void * arg) +{ + me = pthread_self(); + + return arg; +} + +int +main() +{ + pthread_t t; + + assert(pthread_create(&t, NULL, entry, NULL) == 0); + + Sleep(100); + + assert(pthread_equal(t, me) != 0); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/semaphore1.c b/pthreads/tests/semaphore1.c new file mode 100644 index 000000000..f89a43081 --- /dev/null +++ b/pthreads/tests/semaphore1.c @@ -0,0 +1,161 @@ +/* + * File: semaphore1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify trywait() returns -1 and sets EAGAIN. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +void * +thr(void * arg) +{ + sem_t s; + int result; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + + assert((result = sem_trywait(&s)) == -1); + + if ( result == -1 ) + { + int err = errno; + printf("thread: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); + assert(err == EAGAIN); + } + else + { + printf("thread: ok 1\n"); + } + + assert((result = sem_post(&s)) == 0); + + assert((result = sem_trywait(&s)) == 0); + + if ( result == -1 ) + { + perror("thread: sem_trywait 2"); + } + else + { + printf("thread: ok 2\n"); + } + + assert(sem_post(&s) == 0); + + return 0; +} + + +int +main() +{ + pthread_t t; + sem_t s; + int result; + + assert(pthread_create(&t, NULL, thr, NULL) == 0); + assert(pthread_join(t, (void **)&result) == 0); + assert(result == 0); + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + + assert((result = sem_trywait(&s)) == -1); + + if ( result == -1 ) + { + int err = errno; + printf("main: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); + assert(err == EAGAIN); + } + else + { + printf("main: ok 1\n"); + } + + assert((result = sem_post(&s)) == 0); + + assert((result = sem_trywait(&s)) == 0); + + if ( result == -1 ) + { + perror("main: sem_trywait 2"); + } + else + { + printf("main: ok 2\n"); + } + + assert(sem_post(&s) == 0); + + return 0; +} + diff --git a/pthreads/tests/semaphore2.c b/pthreads/tests/semaphore2.c new file mode 100644 index 000000000..af4d0ea70 --- /dev/null +++ b/pthreads/tests/semaphore2.c @@ -0,0 +1,108 @@ +/* + * File: semaphore2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct value. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 100 + +int +main() +{ + sem_t s; + int value = 0; + int i; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, MAX_COUNT) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(value == MAX_COUNT); +// printf("Value = %ld\n", value); + + for (i = MAX_COUNT - 1; i >= 0; i--) + { + assert(sem_wait(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %ld\n", value); + assert(value == i); + } + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %ld\n", value); + assert(value == i); + } + + return 0; +} + diff --git a/pthreads/tests/semaphore3.c b/pthreads/tests/semaphore3.c new file mode 100644 index 000000000..a0dfcb6f6 --- /dev/null +++ b/pthreads/tests/semaphore3.c @@ -0,0 +1,121 @@ +/* + * File: semaphore3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 100 + +sem_t s; + +void * +thr (void * arg) +{ + assert(sem_wait(&s) == 0); + assert(pthread_detach(pthread_self()) == 0); + return NULL; +} + +int +main() +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, NULL) == 0); + do { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } while (value != -i); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + for (i = MAX_COUNT - 1; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + return 0; +} + diff --git a/pthreads/tests/semaphore4.c b/pthreads/tests/semaphore4.c new file mode 100644 index 000000000..37613ac39 --- /dev/null +++ b/pthreads/tests/semaphore4.c @@ -0,0 +1,138 @@ +/* + * File: semaphore4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters + * after threads are cancelled. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 100 + +sem_t s; + +void * +thr (void * arg) +{ + assert(sem_wait(&s) == 0); + return NULL; +} + +int +main() +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, NULL) == 0); + do { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } while (value != -i); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT); +//printf("value = %d\n", -value); fflush(stdout); + assert(pthread_cancel(t[50]) == 0); + { + int result; + assert(pthread_join(t[50], (void **) &result) == 0); +// printf("result = %d\n", result); fflush(stdout); + } + assert(sem_getvalue(&s, &value) == 0); +//printf("value = %d\n", -value); fflush(stdout); + assert(-value == (MAX_COUNT - 1)); + + for (i = MAX_COUNT - 2; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + for (i = 1; i <= MAX_COUNT; i++) + if (i != 50) + assert(pthread_join(t[i], NULL) == 0); + + return 0; +} + diff --git a/pthreads/tests/semaphore4t.c b/pthreads/tests/semaphore4t.c new file mode 100644 index 000000000..14a46694c --- /dev/null +++ b/pthreads/tests/semaphore4t.c @@ -0,0 +1,132 @@ +/* + * File: semaphore4t.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: Verify sem_getvalue returns the correct number of waiters + * after threads are cancelled. + * - + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - sem_timedwait cancellation. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +#define MAX_COUNT 100 + +sem_t s; + +void * +thr (void * arg) +{ + assert(sem_timedwait(&s, NULL) == 0); + return NULL; +} + +int +main() +{ + int value = 0; + int i; + pthread_t t[MAX_COUNT+1]; + + assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(value == 0); + + for (i = 1; i <= MAX_COUNT; i++) + { + assert(pthread_create(&t[i], NULL, thr, NULL) == 0); + do { + sched_yield(); + assert(sem_getvalue(&s, &value) == 0); + } while (value != -i); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT); + assert(pthread_cancel(t[50]) == 0); + assert(pthread_join(t[50], NULL) == 0); + assert(sem_getvalue(&s, &value) == 0); + assert(-value == MAX_COUNT - 1); + + for (i = MAX_COUNT - 2; i >= 0; i--) + { + assert(sem_post(&s) == 0); + assert(sem_getvalue(&s, &value) == 0); +// printf("Value = %d\n", value); fflush(stdout); + assert(-value == i); + } + + for (i = 1; i <= MAX_COUNT; i++) + if (i != 50) + assert(pthread_join(t[i], NULL) == 0); + + return 0; +} + diff --git a/pthreads/tests/sizes.c b/pthreads/tests/sizes.c new file mode 100644 index 000000000..73c726171 --- /dev/null +++ b/pthreads/tests/sizes.c @@ -0,0 +1,32 @@ +#define _WIN32_WINNT 0x400 + +#include "test.h" +#include "../implement.h" + +int +main() +{ + printf("Sizes of pthreads-win32 structs\n"); + printf("-------------------------------\n"); + printf("%30s %4d\n", "pthread_t", sizeof(pthread_t)); + printf("%30s %4d\n", "ptw32_thread_t", sizeof(ptw32_thread_t)); + printf("%30s %4d\n", "pthread_attr_t_", sizeof(struct pthread_attr_t_)); + printf("%30s %4d\n", "sem_t_", sizeof(struct sem_t_)); + printf("%30s %4d\n", "pthread_mutex_t_", sizeof(struct pthread_mutex_t_)); + printf("%30s %4d\n", "pthread_mutexattr_t_", sizeof(struct pthread_mutexattr_t_)); + printf("%30s %4d\n", "pthread_spinlock_t_", sizeof(struct pthread_spinlock_t_)); + printf("%30s %4d\n", "pthread_barrier_t_", sizeof(struct pthread_barrier_t_)); + printf("%30s %4d\n", "pthread_barrierattr_t_", sizeof(struct pthread_barrierattr_t_)); + printf("%30s %4d\n", "pthread_key_t_", sizeof(struct pthread_key_t_)); + printf("%30s %4d\n", "pthread_cond_t_", sizeof(struct pthread_cond_t_)); + printf("%30s %4d\n", "pthread_condattr_t_", sizeof(struct pthread_condattr_t_)); + printf("%30s %4d\n", "pthread_rwlock_t_", sizeof(struct pthread_rwlock_t_)); + printf("%30s %4d\n", "pthread_rwlockattr_t_", sizeof(struct pthread_rwlockattr_t_)); + printf("%30s %4d\n", "pthread_once_t_", sizeof(struct pthread_once_t_)); + printf("%30s %4d\n", "ptw32_cleanup_t", sizeof(struct ptw32_cleanup_t)); + printf("%30s %4d\n", "ptw32_mcs_node_t_", sizeof(struct ptw32_mcs_node_t_)); + printf("%30s %4d\n", "sched_param", sizeof(struct sched_param)); + printf("-------------------------------\n"); + + return 0; +} diff --git a/pthreads/tests/spin1.c b/pthreads/tests/spin1.c new file mode 100644 index 000000000..00ecd11b1 --- /dev/null +++ b/pthreads/tests/spin1.c @@ -0,0 +1,59 @@ +/* + * spin1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Create a simple spinlock object, lock it, and then unlock it again. + * This is the simplest test of the pthread mutex family that we can do. + * + */ + +#include "test.h" + +pthread_spinlock_t lock; + +int +main() +{ + assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0); + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(pthread_spin_lock(&lock) == EINVAL); + + return 0; +} diff --git a/pthreads/tests/spin2.c b/pthreads/tests/spin2.c new file mode 100644 index 000000000..b13c29c4e --- /dev/null +++ b/pthreads/tests/spin2.c @@ -0,0 +1,75 @@ +/* + * spin2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a spinlock object, lock it, trylock it, + * and then unlock it again. + * + */ + +#include "test.h" + +pthread_spinlock_t lock = NULL; + +static int washere = 0; + +void * func(void * arg) +{ + assert(pthread_spin_trylock(&lock) == EBUSY); + + washere = 1; + + return 0; +} + +int +main() +{ + pthread_t t; + + assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0); + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, NULL) == 0); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/spin3.c b/pthreads/tests/spin3.c new file mode 100644 index 000000000..8c0dae69f --- /dev/null +++ b/pthreads/tests/spin3.c @@ -0,0 +1,72 @@ +/* + * spin3.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Thread A locks spin - thread B tries to unlock. + * This should succeed, but it's undefined behaviour. + * + */ + +#include "test.h" + +static int wasHere = 0; + +static pthread_spinlock_t spin; + +void * unlocker(void * arg) +{ + int expectedResult = (int) arg; + + wasHere++; + assert(pthread_spin_unlock(&spin) == expectedResult); + wasHere++; + return NULL; +} + +int +main() +{ + pthread_t t; + + wasHere = 0; + assert(pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE) == 0); + assert(pthread_spin_lock(&spin) == 0); + assert(pthread_create(&t, NULL, unlocker, (void *) 0) == 0); + assert(pthread_join(t, NULL) == 0); + assert(pthread_spin_unlock(&spin) == EPERM); + assert(pthread_spin_destroy(&spin) == 0); + assert(wasHere == 2); + + return 0; +} diff --git a/pthreads/tests/spin4.c b/pthreads/tests/spin4.c new file mode 100644 index 000000000..8386d0956 --- /dev/null +++ b/pthreads/tests/spin4.c @@ -0,0 +1,103 @@ +/* + * spin4.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Declare a static spinlock object, lock it, spin on it, + * and then unlock it again. + */ + +#include "test.h" +#include <sys/timeb.h> + +pthread_spinlock_t lock = PTHREAD_SPINLOCK_INITIALIZER; +struct _timeb currSysTimeStart; +struct _timeb currSysTimeStop; + +#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm)) + +static int washere = 0; + +void * func(void * arg) +{ + _ftime(&currSysTimeStart); + washere = 1; + assert(pthread_spin_lock(&lock) == 0); + assert(pthread_spin_unlock(&lock) == 0); + _ftime(&currSysTimeStop); + + return (void *) GetDurationMilliSecs(currSysTimeStart, currSysTimeStop); +} + +int +main() +{ + long result = 0; + pthread_t t; + int CPUs; + struct _timeb sysTime; + + if ((CPUs = pthread_num_processors_np()) == 1) + { + printf("Test not run - it requires multiple CPUs.\n"); + exit(0); + } + + assert(pthread_spin_lock(&lock) == 0); + + assert(pthread_create(&t, NULL, func, NULL) == 0); + + while (washere == 0) + { + sched_yield(); + } + + do + { + sched_yield(); + _ftime(&sysTime); + } + while (GetDurationMilliSecs(currSysTimeStart, sysTime) <= 1000); + + assert(pthread_spin_unlock(&lock) == 0); + + assert(pthread_join(t, (void **) &result) == 0); + assert(result > 1000); + + assert(pthread_spin_destroy(&lock) == 0); + + assert(washere == 1); + + return 0; +} diff --git a/pthreads/tests/stress1.c b/pthreads/tests/stress1.c new file mode 100644 index 000000000..efaf44517 --- /dev/null +++ b/pthreads/tests/stress1.c @@ -0,0 +1,278 @@ +/* + * stress1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Stress test condition variables, mutexes, semaphores. + * + * Test Method (Validation or Falsification): + * - Validation + * + * Requirements Tested: + * - Correct accounting of semaphore and condition variable waiters. + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * Attempting to expose race conditions in cond vars, semaphores etc. + * - Master attempts to signal slave close to when timeout is due. + * - Master and slave do battle continuously until main tells them to stop. + * - Afterwards, the CV must be successfully destroyed (will return an + * error if there are waiters (including any internal semaphore waiters, + * which, if there are, cannot not be real waiters). + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - CV is successfully destroyed. + * + * Fail Criteria: + * - CV destroy fails. + */ + +#include "test.h" +#include <string.h> +#include <sys/timeb.h> + + +const unsigned int ITERATIONS = 1000; + +static pthread_t master, slave; +typedef struct { + int value; + pthread_cond_t cv; + pthread_mutex_t mx; +} mysig_t; + +static int allExit; +static mysig_t control = {0, PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}; +static pthread_barrier_t startBarrier, readyBarrier, holdBarrier; +static int timeoutCount = 0; +static int signalsTakenCount = 0; +static int signalsSent = 0; +static int bias = 0; +static int timeout = 10;
// Must be > 0 + +enum { + CTL_STOP = -1 +}; + +/* + * Returns abstime 'milliseconds' from 'now'. + * + * Works for: -INT_MAX <= millisecs <= INT_MAX + */ +struct timespec * +millisecondsFromNow (struct timespec * time, int millisecs) +{ + struct _timeb currSysTime; + int64_t nanosecs, secs; + const int64_t NANOSEC_PER_MILLISEC = 1000000; + const int64_t NANOSEC_PER_SEC = 1000000000; + + /* get current system time and add millisecs */ + _ftime(&currSysTime); + + secs = (int64_t)(currSysTime.time) + (millisecs / 1000); + nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; + if (nanosecs >= NANOSEC_PER_SEC) + { + secs++; + nanosecs -= NANOSEC_PER_SEC; + } + else if (nanosecs < 0) + { + secs--; + nanosecs += NANOSEC_PER_SEC; + } + + time->tv_nsec = (long)nanosecs; + time->tv_sec = (long)secs; + + return time; +} + +void * +masterThread (void * arg) +{ + int dither = (int) arg; + + timeout = (int) arg; + + pthread_barrier_wait(&startBarrier); + + do + { + int sleepTime; + + assert(pthread_mutex_lock(&control.mx) == 0); + control.value = timeout; + assert(pthread_mutex_unlock(&control.mx) == 0); + + /* + * We are attempting to send the signal close to when the slave + * is due to timeout. We feel around by adding some [non-random] dither. + * + * dither is in the range 2*timeout peak-to-peak + * sleep time is the average of timeout plus dither. + * e.g. + * if timeout = 10 then dither = 20 and + * sleep millisecs is: 5 <= ms <= 15 + * + * The bias value attempts to apply some negative feedback to keep + * the ratio of timeouts to signals taken close to 1:1. + * bias changes more slowly than dither so as to average more. + * + * Finally, if abs(bias) exceeds timeout then timeout is incremented. + */ + if (signalsSent % timeout == 0) + { + if (timeoutCount > signalsTakenCount) + { + bias++; + } + else if (timeoutCount < signalsTakenCount) + { + bias--; + } + if (bias < -timeout || bias > timeout) + { + timeout++; + } + } + dither = (dither + 1 ) % (timeout * 2); + sleepTime = (timeout - bias + dither) / 2; + Sleep(sleepTime); + assert(pthread_cond_signal(&control.cv) == 0); + signalsSent++; + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +void * +slaveThread (void * arg) +{ + struct timespec time; + + pthread_barrier_wait(&startBarrier); + + do + { + assert(pthread_mutex_lock(&control.mx) == 0); + if (pthread_cond_timedwait(&control.cv, + &control.mx, + millisecondsFromNow(&time, control.value)) == ETIMEDOUT) + { + timeoutCount++; + } + else + { + signalsTakenCount++; + } + assert(pthread_mutex_unlock(&control.mx) == 0); + + pthread_barrier_wait(&holdBarrier); + pthread_barrier_wait(&readyBarrier); + } + while (!allExit); + + return NULL; +} + +int +main () +{ + unsigned int i; + + assert(pthread_barrier_init(&startBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&readyBarrier, NULL, 3) == 0); + assert(pthread_barrier_init(&holdBarrier, NULL, 3) == 0); + + assert(pthread_create(&master, NULL, masterThread, (void *) timeout) == 0); + assert(pthread_create(&slave, NULL, slaveThread, NULL) == 0); + + allExit = FALSE; + + pthread_barrier_wait(&startBarrier); + + for (i = 1; !allExit; i++) + { + pthread_barrier_wait(&holdBarrier); + if (i >= ITERATIONS) + { + allExit = TRUE; + } + pthread_barrier_wait(&readyBarrier); + } + + assert(pthread_join(slave, NULL) == 0); + assert(pthread_join(master, NULL) == 0); + + printf("Signals sent = %d\nWait timeouts = %d\nSignals taken = %d\nBias = %d\nTimeout = %d\n", + signalsSent, + timeoutCount, + signalsTakenCount, + (int) bias, + timeout); + + /* Cleanup */ + assert(pthread_barrier_destroy(&holdBarrier) == 0); + assert(pthread_barrier_destroy(&readyBarrier) == 0); + assert(pthread_barrier_destroy(&startBarrier) == 0); + assert(pthread_cond_destroy(&control.cv) == 0); + assert(pthread_mutex_destroy(&control.mx) == 0); + + /* Success. */ + return 0; +} diff --git a/pthreads/tests/test.h b/pthreads/tests/test.h new file mode 100644 index 000000000..3132c6914 --- /dev/null +++ b/pthreads/tests/test.h @@ -0,0 +1,140 @@ +/* + * test.h + * + * Useful definitions and declarations for tests. + * + * + * -------------------------------------------------------------------------- + * + * 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 _PTHREAD_TEST_H_ +#define _PTHREAD_TEST_H_ + +#include "pthread.h" +#include "sched.h" +#include "semaphore.h" + +#include <windows.h> +#include <stdio.h> + +#define PTW32_THREAD_NULL_ID {NULL,0} + +#if defined(__MINGW32__) +#include <stdint.h> +#elif defined(__BORLANDC__) +#define int64_t ULONGLONG +#else +#define int64_t _int64 +#endif + + +char * error_string[] = { + "ZERO_or_EOK", + "EPERM", + "ENOFILE_or_ENOENT", + "ESRCH", + "EINTR", + "EIO", + "ENXIO", + "E2BIG", + "ENOEXEC", + "EBADF", + "ECHILD", + "EAGAIN", + "ENOMEM", + "EACCES", + "EFAULT", + "UNKNOWN_15", + "EBUSY", + "EEXIST", + "EXDEV", + "ENODEV", + "ENOTDIR", + "EISDIR", + "EINVAL", + "ENFILE", + "EMFILE", + "ENOTTY", + "UNKNOWN_26", + "EFBIG", + "ENOSPC", + "ESPIPE", + "EROFS", + "EMLINK", + "EPIPE", + "EDOM", + "ERANGE", + "UNKNOWN_35", + "EDEADLOCK_or_EDEADLK", + "UNKNOWN_37", + "ENAMETOOLONG", + "ENOLCK", + "ENOSYS", + "ENOTEMPTY", + "EILSEQ", +}; + +/* + * The Mingw32 assert macro calls the CRTDLL _assert function + * which pops up a dialog. We want to run in batch mode so + * we define our own assert macro. + */ +#ifdef assert +# undef assert +#endif + +#ifndef ASSERT_TRACE +# define ASSERT_TRACE 0 +#else +# undef ASSERT_TRACE +# define ASSERT_TRACE 1 +#endif + +# define assert(e) \ + ((e) ? ((ASSERT_TRACE) ? fprintf(stderr, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stderr) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), exit(1), 0)) + +int assertE; +# define assert_e(e, o, r) \ + (((assertE = e) o (r)) ? ((ASSERT_TRACE) ? fprintf(stderr, \ + "Assertion succeeded: (%s), file %s, line %d\n", \ + #e, __FILE__, (int) __LINE__), \ + fflush(stderr) : \ + 0) : \ + (fprintf(stderr, "Assertion failed: (%s %s %s), file %s, line %d, error %s\n", \ + #e,#o,#r, __FILE__, (int) __LINE__, error_string[assertE]), exit(1), 0)) + +#endif diff --git a/pthreads/tests/tryentercs.c b/pthreads/tests/tryentercs.c new file mode 100644 index 000000000..13a6e096d --- /dev/null +++ b/pthreads/tests/tryentercs.c @@ -0,0 +1,103 @@ +/* + * tryentercs.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * See if we have the TryEnterCriticalSection function. + * Does not use any part of pthreads. + */ + +#include <windows.h> +#include <process.h> +#include <stdio.h> + +/* + * Function pointer to TryEnterCriticalSection if it exists + * - otherwise NULL + */ +BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) = +NULL; + +/* + * Handle to kernel32.dll + */ +static HINSTANCE _h_kernel32; + + +int +main() +{ + CRITICAL_SECTION cs; + + SetLastError(0); + + printf("Last Error [main enter] %ld\n", (long) GetLastError()); + + /* + * Load KERNEL32 and try to get address of TryEnterCriticalSection + */ + _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); + _try_enter_critical_section = + (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION)) + GetProcAddress(_h_kernel32, + (LPCSTR) "TryEnterCriticalSection"); + + if (_try_enter_critical_section != NULL) + { + InitializeCriticalSection(&cs); + + SetLastError(0); + + if ((*_try_enter_critical_section)(&cs) != 0) + { + LeaveCriticalSection(&cs); + } + else + { + printf("Last Error [try enter] %ld\n", (long) GetLastError()); + + _try_enter_critical_section = NULL; + } + DeleteCriticalSection(&cs); + } + + (void) FreeLibrary(_h_kernel32); + + printf("This system %s TryEnterCriticalSection.\n", + (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS"); + printf("POSIX Mutexes will be based on Win32 %s.\n", + (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections"); + + return(0); +} + diff --git a/pthreads/tests/tryentercs2.c b/pthreads/tests/tryentercs2.c new file mode 100644 index 000000000..a1c4d97f3 --- /dev/null +++ b/pthreads/tests/tryentercs2.c @@ -0,0 +1,92 @@ +/* + * tryentercs.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * See if we have the TryEnterCriticalSection function. + * Does not use any part of pthreads. + */ + +#include <windows.h> +#include <process.h> +#include <stdio.h> + +/* + * Function pointer to TryEnterCriticalSection if it exists + * - otherwise NULL + */ +BOOL (WINAPI *_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL; + +/* + * Handle to kernel32.dll + */ +static HINSTANCE _h_kernel32; + + +int +main() +{ + LPCRITICAL_SECTION lpcs = NULL; + + SetLastError(0); + + printf("Last Error [main enter] %ld\n", (long) GetLastError()); + + /* + * Load KERNEL32 and try to get address of TryEnterCriticalSection + */ + _h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); + _try_enter_critical_section = + (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION)) + GetProcAddress(_h_kernel32, + (LPCSTR) "TryEnterCriticalSection"); + + if (_try_enter_critical_section != NULL) + { + SetLastError(0); + + (*_try_enter_critical_section)(lpcs); + + printf("Last Error [try enter] %ld\n", (long) GetLastError()); + } + + (void) FreeLibrary(_h_kernel32); + + printf("This system %s TryEnterCriticalSection.\n", + (_try_enter_critical_section == NULL) ? "DOES NOT SUPPORT" : "SUPPORTS"); + printf("POSIX Mutexes will be based on Win32 %s.\n", + (_try_enter_critical_section == NULL) ? "Mutexes" : "Critical Sections"); + + return(0); +} + diff --git a/pthreads/tests/tsd1.c b/pthreads/tests/tsd1.c new file mode 100644 index 000000000..c28e4c53e --- /dev/null +++ b/pthreads/tests/tsd1.c @@ -0,0 +1,211 @@ +/* + * tsd1.c + * + * Test Thread Specific Data (TSD) key creation and destruction. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * + * -------------------------------------------------------------------------- + * + * Description: + * - + * + * Test Method (validation or falsification): + * - validation + * + * Requirements Tested: + * - keys are created for each existing thread including the main thread + * - keys are created for newly created threads + * - keys are thread specific + * - destroy routine is called on each thread exit including the main thread + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Environment: + * - + * + * Input: + * - none + * + * Output: + * - text to stdout + * + * Assumptions: + * - already validated: pthread_create() + * pthread_once() + * - main thread also has a POSIX thread identity + * + * Pass Criteria: + * - stdout matches file reference/tsd1.out + * + * Fail Criteria: + * - fails to match file reference/tsd1.out + * - output identifies failed component + */ + +#include <sched.h> +#include "test.h" + +enum { + NUM_THREADS = 100 +}; + +static pthread_key_t key = NULL; +static int accesscount[NUM_THREADS]; +static int thread_set[NUM_THREADS]; +static int thread_destroyed[NUM_THREADS]; +static pthread_barrier_t startBarrier; + +static void +destroy_key(void * arg) +{ + int * j = (int *) arg; + + (*j)++; + + assert(*j == 2); + + thread_destroyed[j - accesscount] = 1; +} + +static void +setkey(void * arg) +{ + int * j = (int *) arg; + + thread_set[j - accesscount] = 1; + + assert(*j == 0); + + assert(pthread_getspecific(key) == NULL); + + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + + assert(pthread_getspecific(key) == arg); + + (*j)++; + + assert(*j == 1); +} + +static void * +mythread(void * arg) +{ + (void) pthread_barrier_wait(&startBarrier); + + setkey(arg); + + return 0; + + /* Exiting the thread will call the key destructor. */ +} + +int +main() +{ + int i; + int fail = 0; + pthread_t thread[NUM_THREADS]; + + assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0); + + for (i = 1; i < NUM_THREADS/2; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Here we test that existing threads will get a key created + * for them. + */ + assert(pthread_key_create(&key, destroy_key) == 0); + + (void) pthread_barrier_wait(&startBarrier); + + /* + * Test main thread key. + */ + accesscount[0] = 0; + setkey((void *) &accesscount[0]); + + /* + * Here we test that new threads will get a key created + * for them. + */ + for (i = NUM_THREADS/2; i < NUM_THREADS; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Wait for all threads to complete. + */ + for (i = 1; i < NUM_THREADS; i++) + { + int result = 0; + + assert(pthread_join(thread[i], (void **) &result) == 0); + } + + assert(pthread_key_delete(key) == 0); + + assert(pthread_barrier_destroy(&startBarrier) == 0); + + for (i = 1; i < NUM_THREADS; i++) + { + /* + * The counter is incremented once when the key is set to + * a value, and again when the key is destroyed. If the key + * doesn't get set for some reason then it will still be + * NULL and the destroy function will not be called, and + * hence accesscount will not equal 2. + */ + if (accesscount[i] != 2) + { + fail++; + fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n", + i, thread_set[i], thread_destroyed[i]); + } + } + + fflush(stderr); + + return (fail); +} diff --git a/pthreads/tests/tsd2.c b/pthreads/tests/tsd2.c new file mode 100644 index 000000000..d1f50cde3 --- /dev/null +++ b/pthreads/tests/tsd2.c @@ -0,0 +1,215 @@ +/* + * tsd2.c + * + * Test Thread Specific Data (TSD) key creation and destruction. + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * + * -------------------------------------------------------------------------- + * + * Description: + * - + * + * Test Method (validation or falsification): + * - validation + * + * Requirements Tested: + * - keys are created for each existing thread including the main thread + * - keys are created for newly created threads + * - keys are thread specific + * - destroy routine is called on each thread exit including the main thread + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Environment: + * - + * + * Input: + * - none + * + * Output: + * - text to stdout + * + * Assumptions: + * - already validated: pthread_create() + * pthread_once() + * - main thread also has a POSIX thread identity + * + * Pass Criteria: + * - stdout matches file reference/tsd1.out + * + * Fail Criteria: + * - fails to match file reference/tsd1.out + * - output identifies failed component + */ + +#include <sched.h> +#include "test.h" + +enum { + NUM_THREADS = 100 +}; + +static pthread_key_t key = NULL; +static int accesscount[NUM_THREADS]; +static int thread_set[NUM_THREADS]; +static int thread_destroyed[NUM_THREADS]; +static pthread_barrier_t startBarrier; + +static void +destroy_key(void * arg) +{ + int * j = (int *) arg; + + (*j)++; + + /* Set TSD key from the destructor to test destructor iteration */ + if (*j == 2) + assert(pthread_setspecific(key, arg) == 0); + else + assert(*j == 3); + + thread_destroyed[j - accesscount] = 1; +} + +static void +setkey(void * arg) +{ + int * j = (int *) arg; + + thread_set[j - accesscount] = 1; + + assert(*j == 0); + + assert(pthread_getspecific(key) == NULL); + + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + + assert(pthread_getspecific(key) == arg); + + (*j)++; + + assert(*j == 1); +} + +static void * +mythread(void * arg) +{ + (void) pthread_barrier_wait(&startBarrier); + + setkey(arg); + + return 0; + + /* Exiting the thread will call the key destructor. */ +} + +int +main() +{ + int i; + int fail = 0; + pthread_t thread[NUM_THREADS]; + + assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0); + + for (i = 1; i < NUM_THREADS/2; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Here we test that existing threads will get a key created + * for them. + */ + assert(pthread_key_create(&key, destroy_key) == 0); + + (void) pthread_barrier_wait(&startBarrier); + + /* + * Test main thread key. + */ + accesscount[0] = 0; + setkey((void *) &accesscount[0]); + + /* + * Here we test that new threads will get a key created + * for them. + */ + for (i = NUM_THREADS/2; i < NUM_THREADS; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Wait for all threads to complete. + */ + for (i = 1; i < NUM_THREADS; i++) + { + int result = 0; + + assert(pthread_join(thread[i], (void **) &result) == 0); + } + + assert(pthread_key_delete(key) == 0); + + assert(pthread_barrier_destroy(&startBarrier) == 0); + + for (i = 1; i < NUM_THREADS; i++) + { + /* + * The counter is incremented once when the key is set to + * a value, and again when the key is destroyed. If the key + * doesn't get set for some reason then it will still be + * NULL and the destroy function will not be called, and + * hence accesscount will not equal 2. + */ + if (accesscount[i] != 3) + { + fail++; + fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n", + i, thread_set[i], thread_destroyed[i]); + } + } + + fflush(stderr); + + return (fail); +} diff --git a/pthreads/tests/valid1.c b/pthreads/tests/valid1.c new file mode 100644 index 000000000..4d5cab592 --- /dev/null +++ b/pthreads/tests/valid1.c @@ -0,0 +1,103 @@ +/* + * File: valid1.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Test that thread validation works. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +enum { + NUMTHREADS = 1 +}; + +static int washere = 0; + +void * func(void * arg) +{ + washere = 1; + return (void *) 0; +} + +int +main() +{ + pthread_t t; + void * result = NULL; + + washere = 0; + assert(pthread_create(&t, NULL, func, NULL) == 0); + assert(pthread_join(t, &result) == 0); + assert(result == 0); + assert(washere == 1); + sched_yield(); + assert(pthread_kill(t, 0) == ESRCH); + + return 0; +} diff --git a/pthreads/tests/valid2.c b/pthreads/tests/valid2.c new file mode 100644 index 000000000..b9671798b --- /dev/null +++ b/pthreads/tests/valid2.c @@ -0,0 +1,84 @@ +/* + * File: valid2.c + * + * + * -------------------------------------------------------------------------- + * + * 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 + * + * -------------------------------------------------------------------------- + * + * Test Synopsis: + * - Confirm that thread validation fails for garbage thread ID. + * + * Test Method (Validation or Falsification): + * - + * + * Requirements Tested: + * - + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Description: + * - + * + * Environment: + * - + * + * Input: + * - None. + * + * Output: + * - File name, Line number, and failed expression on failure. + * - No output on success. + * + * Assumptions: + * - + * + * Pass Criteria: + * - Process returns zero exit status. + * + * Fail Criteria: + * - Process returns non-zero exit status. + */ + +#include "test.h" + +int +main() +{ + pthread_t NullThread = PTW32_THREAD_NULL_ID; + + assert(pthread_kill(NullThread, 0) == ESRCH); + + return 0; +} |