Jason Schmidlapp 17 жил өмнө
commit
062c5bc4df
100 өөрчлөгдсөн 15613 нэмэгдсэн , 0 устгасан
  1. 476 0
      ANNOUNCE
  2. 129 0
      CONTRIBUTORS.ptw32
  3. 150 0
      COPYING
  4. 504 0
      COPYING.LIB
  5. 5 0
      TODO
  6. 154 0
      cleanup.c
  7. 259 0
      create.c
  8. 98 0
      global.c
  9. 516 0
      implement.h
  10. 90 0
      need_errno.h
  11. 26 0
      platform/dspbios/dspbios-config.h
  12. 923 0
      platform/dspbios/dspbios-osal.c
  13. 102 0
      platform/dspbios/dspbios-osal.h
  14. 46 0
      platform/dspbios/main.c
  15. 36 0
      platform/dspbios/pte-config.h
  16. 156 0
      platform/dspbios/pte_lib/pte_lib.pjt
  17. 12 0
      platform/dspbios/pte_osal.h
  18. 1322 0
      platform/dspbios/pte_test/Configuration1.cdb
  19. 47 0
      platform/dspbios/pte_test/Configuration1.tcf
  20. 6 0
      platform/dspbios/pte_test/Configuration1.tco
  21. 185 0
      platform/dspbios/pte_test/pte_test.pjt
  22. 185 0
      platform/helper/tls-helper.c
  23. 47 0
      platform/helper/tls-helper.h
  24. 194 0
      platform/psp/Makefile
  25. 212 0
      platform/psp/Makefile.tests
  26. 76 0
      platform/psp/main.c
  27. 0 0
      platform/psp/psp_osal.c
  28. 66 0
      platform/psp/psp_osal.h
  29. 34 0
      platform/psp/pte-config.h
  30. 12 0
      platform/psp/pte_osal.h
  31. 229 0
      pte_callUserDestroyRoutines.c
  32. 130 0
      pte_cancellable_wait.c
  33. 103 0
      pte_cond_check_need_init.c
  34. 106 0
      pte_detach.c
  35. 449 0
      pte_generic_osal.h
  36. 69 0
      pte_getprocessors.c
  37. 53 0
      pte_is_attr.c
  38. 129 0
      pte_mutex_check_need_init.c
  39. 93 0
      pte_new.c
  40. 97 0
      pte_relmillisecs.c
  41. 158 0
      pte_reuse.c
  42. 56 0
      pte_rwlock_cancelwrwait.c
  43. 102 0
      pte_rwlock_check_need_init.c
  44. 89 0
      pte_spinlock_check_need_init.c
  45. 101 0
      pte_threadDestroy.c
  46. 248 0
      pte_threadStart.c
  47. 142 0
      pte_throw.c
  48. 126 0
      pte_tkAssocCreate.c
  49. 122 0
      pte_tkAssocDestroy.c
  50. 1006 0
      pthread.h
  51. 87 0
      pthread_attr_destroy.c
  52. 93 0
      pthread_attr_getdetachstate.c
  53. 57 0
      pthread_attr_getinheritsched.c
  54. 61 0
      pthread_attr_getschedparam.c
  55. 67 0
      pthread_attr_getschedpolicy.c
  56. 56 0
      pthread_attr_getscope.c
  57. 99 0
      pthread_attr_getstackaddr.c
  58. 102 0
      pthread_attr_getstacksize.c
  59. 119 0
      pthread_attr_init.c
  60. 97 0
      pthread_attr_setdetachstate.c
  61. 63 0
      pthread_attr_setinheritsched.c
  62. 72 0
      pthread_attr_setschedparam.c
  63. 61 0
      pthread_attr_setschedpolicy.c
  64. 64 0
      pthread_attr_setscope.c
  65. 103 0
      pthread_attr_setstackaddr.c
  66. 116 0
      pthread_attr_setstacksize.c
  67. 75 0
      pthread_barrier_destroy.c
  68. 89 0
      pthread_barrier_init.c
  69. 101 0
      pthread_barrier_wait.c
  70. 91 0
      pthread_barrierattr_destroy.c
  71. 101 0
      pthread_barrierattr_getpshared.c
  72. 93 0
      pthread_barrierattr_init.c
  73. 125 0
      pthread_barrierattr_setpshared.c
  74. 173 0
      pthread_cancel.c
  75. 256 0
      pthread_cond_destroy.c
  76. 174 0
      pthread_cond_init.c
  77. 238 0
      pthread_cond_signal.c
  78. 568 0
      pthread_cond_wait.c
  79. 94 0
      pthread_condattr_destroy.c
  80. 103 0
      pthread_condattr_getpshared.c
  81. 95 0
      pthread_condattr_init.c
  82. 123 0
      pthread_condattr_setpshared.c
  83. 166 0
      pthread_delay_np.c
  84. 142 0
      pthread_detach.c
  85. 82 0
      pthread_equal.c
  86. 101 0
      pthread_exit.c
  87. 51 0
      pthread_getconcurrency.c
  88. 81 0
      pthread_getschedparam.c
  89. 86 0
      pthread_getspecific.c
  90. 91 0
      pthread_init.c
  91. 164 0
      pthread_join.c
  92. 119 0
      pthread_key_create.c
  93. 140 0
      pthread_key_delete.c
  94. 107 0
      pthread_kill.c
  95. 154 0
      pthread_mutex_destroy.c
  96. 83 0
      pthread_mutex_init.c
  97. 140 0
      pthread_mutex_lock.c
  98. 189 0
      pthread_mutex_timedlock.c
  99. 95 0
      pthread_mutex_trylock.c
  100. 130 0
      pthread_mutex_unlock.c

+ 476 - 0
ANNOUNCE

@@ -0,0 +1,476 @@
+	     PTHREADS-WIN32 RELEASE 2.8.0 (2006-12-22)
+	     -----------------------------------------
+	 Web Site: http://sources.redhat.com/pthreads-win32/
+	FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
+	 Maintainer: Ross Johnson <[email protected]>
+
+
+We are pleased to announce the availability of a new release of
+Pthreads-win32, an Open Source Software implementation of the
+Threads component of the POSIX 1003.1 2001 Standard for Microsoft's
+Win32 environment. Some functions from other sections of POSIX
+1003.1 2001 are also supported including semaphores and scheduling
+functions.
+
+Some common non-portable functions are also implemented for
+additional compatibility, as are a few functions specific
+to pthreads-win32 for easier integration with Win32 applications.
+
+Pthreads-win32 is free software, distributed under the GNU Lesser
+General Public License (LGPL).
+
+
+Acknowledgements
+----------------
+This library is based originally on a Win32 pthreads
+implementation contributed by John Bossom <[email protected]>.
+
+The implementation of Condition Variables uses algorithms developed
+by Alexander Terekhov and Louis Thomas.
+
+The implementation of POSIX mutexes has been improved by Thomas Pfaff
+and later by Alexander Terekhov.
+
+The implementation of Spinlocks and Barriers was contributed
+by Ross Johnson.
+
+The implementation of read/write locks was contributed by
+Aurelio Medina and improved by Alexander Terekhov.
+
+Many others have contributed significant time and effort to solve crutial
+problems in order to make the library workable, robust and reliable.
+
+Thanks to Xavier Leroy for granting permission to use and modify his
+LinuxThreads manual pages.
+
+Thanks to The Open Group for making the Single Unix Specification
+publicly available - many of the manual pages included in the package
+were extracted from it.
+
+There is also a separate CONTRIBUTORS file. This file and others are
+on the web site:
+
+	http://sources.redhat.com/pthreads-win32
+
+As much as possible, the ChangeLog file acknowledges contributions to the
+code base in more detail.
+
+
+Changes since the last release
+------------------------------
+These are now documented in the NEWS file.
+See the ChangeLog file also.
+
+
+Known Bugs
+----------
+These are now documented in the BUGS file.
+
+
+Level of standards conformance
+------------------------------
+
+The following POSIX 1003.1 2001 options are defined and set to 200112L:
+
+      _POSIX_THREADS
+      _POSIX_THREAD_SAFE_FUNCTIONS
+      _POSIX_THREAD_ATTR_STACKSIZE
+      _POSIX_THREAD_PRIORITY_SCHEDULING
+      _POSIX_SEMAPHORES
+      _POSIX_READER_WRITER_LOCKS
+      _POSIX_SPIN_LOCKS
+      _POSIX_BARRIERS
+
+
+The following POSIX 1003.1 2001 options are defined and set to -1:
+
+      _POSIX_THREAD_ATTR_STACKADDR
+      _POSIX_THREAD_PRIO_INHERIT
+      _POSIX_THREAD_PRIO_PROTECT
+      _POSIX_THREAD_PROCESS_SHARED
+
+
+The following POSIX 1003.1 2001 limits are defined and set:
+
+      _POSIX_THREAD_THREADS_MAX
+      _POSIX_SEM_VALUE_MAX
+      _POSIX_SEM_NSEMS_MAX
+      _POSIX_THREAD_KEYS_MAX
+      _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+      PTHREAD_STACK_MIN
+      PTHREAD_THREADS_MAX
+      SEM_VALUE_MAX
+      SEM_NSEMS_MAX
+      PTHREAD_KEYS_MAX
+      PTHREAD_DESTRUCTOR_ITERATIONS
+
+
+The following functions are implemented:
+
+      ---------------------------
+      PThreads
+      ---------------------------
+      pthread_attr_init
+      pthread_attr_destroy
+      pthread_attr_getdetachstate
+      pthread_attr_getstackaddr
+      pthread_attr_getstacksize
+      pthread_attr_setdetachstate
+      pthread_attr_setstackaddr
+      pthread_attr_setstacksize
+
+      pthread_create
+      pthread_detach
+      pthread_equal
+      pthread_exit
+      pthread_join
+      pthread_once
+      pthread_self
+
+      pthread_cancel
+      pthread_cleanup_pop
+      pthread_cleanup_push
+      pthread_setcancelstate
+      pthread_setcanceltype
+      pthread_testcancel
+
+      ---------------------------
+      Thread Specific Data
+      ---------------------------
+      pthread_key_create
+      pthread_key_delete
+      pthread_setspecific
+      pthread_getspecific
+
+      ---------------------------
+      Mutexes
+      ---------------------------
+      pthread_mutexattr_init
+      pthread_mutexattr_destroy
+      pthread_mutexattr_getpshared
+      pthread_mutexattr_setpshared
+      pthread_mutexattr_gettype
+      pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT
+					PTHREAD_MUTEX_NORMAL
+					PTHREAD_MUTEX_ERRORCHECK
+					PTHREAD_MUTEX_RECURSIVE  )
+      pthread_mutex_init
+      pthread_mutex_destroy
+      pthread_mutex_lock
+      pthread_mutex_trylock
+      pthread_mutex_timedlock
+      pthread_mutex_unlock
+
+      ---------------------------
+      Condition Variables
+      ---------------------------
+      pthread_condattr_init
+      pthread_condattr_destroy
+      pthread_condattr_getpshared
+      pthread_condattr_setpshared
+
+      pthread_cond_init
+      pthread_cond_destroy
+      pthread_cond_wait
+      pthread_cond_timedwait
+      pthread_cond_signal
+      pthread_cond_broadcast
+
+      ---------------------------
+      Read/Write Locks
+      ---------------------------
+      pthread_rwlock_init
+      pthread_rwlock_destroy
+      pthread_rwlock_tryrdlock
+      pthread_rwlock_trywrlock
+      pthread_rwlock_rdlock
+      pthread_rwlock_timedrdlock
+      pthread_rwlock_rwlock
+      pthread_rwlock_timedwrlock
+      pthread_rwlock_unlock
+      pthread_rwlockattr_init
+      pthread_rwlockattr_destroy
+      pthread_rwlockattr_getpshared
+      pthread_rwlockattr_setpshared
+
+      ---------------------------
+      Spin Locks
+      ---------------------------
+      pthread_spin_init
+      pthread_spin_destroy
+      pthread_spin_lock
+      pthread_spin_unlock
+      pthread_spin_trylock
+
+      ---------------------------
+      Barriers
+      ---------------------------
+      pthread_barrier_init
+      pthread_barrier_destroy
+      pthread_barrier_wait
+      pthread_barrierattr_init
+      pthread_barrierattr_destroy
+      pthread_barrierattr_getpshared
+      pthread_barrierattr_setpshared
+
+      ---------------------------
+      Semaphores
+      ---------------------------
+      sem_init
+      sem_destroy
+      sem_post
+      sem_wait
+      sem_trywait
+      sem_timedwait
+      sem_getvalue	     (# free if +ve, # of waiters if -ve)
+      sem_open		     (returns an error ENOSYS)
+      sem_close 	     (returns an error ENOSYS)
+      sem_unlink	     (returns an error ENOSYS)
+
+      ---------------------------
+      RealTime Scheduling
+      ---------------------------
+      pthread_attr_getschedparam
+      pthread_attr_setschedparam
+      pthread_attr_getinheritsched
+      pthread_attr_setinheritsched
+      pthread_attr_getschedpolicy (only supports SCHED_OTHER)
+      pthread_attr_setschedpolicy (only supports SCHED_OTHER)
+      pthread_getschedparam
+      pthread_setschedparam
+      pthread_getconcurrency
+      pthread_setconcurrency
+      pthread_attr_getscope
+      pthread_attr_setscope  (only supports PTHREAD_SCOPE_SYSTEM)
+      sched_get_priority_max
+      sched_get_priority_min
+      sched_rr_get_interval  (returns an error ENOTSUP)
+      sched_setscheduler     (only supports SCHED_OTHER)
+      sched_getscheduler     (only supports SCHED_OTHER)
+      sched_yield
+
+      ---------------------------
+      Signals
+      ---------------------------
+      pthread_sigmask
+      pthread_kill           (only supports zero sig value,
+                              for thread validity checking)
+
+      ---------------------------
+      Non-portable routines (see the README.NONPORTABLE file for usage)
+      ---------------------------
+      pthread_getw32threadhandle_np
+      pthread_timechange_handler_np
+      pthread_delay_np
+      pthread_mutexattr_getkind_np
+      pthread_mutexattr_setkind_np	(types: PTHREAD_MUTEX_FAST_NP,
+						PTHREAD_MUTEX_ERRORCHECK_NP,
+						PTHREAD_MUTEX_RECURSIVE_NP,
+						PTHREAD_MUTEX_ADAPTIVE_NP,
+						PTHREAD_MUTEX_TIMED_NP)
+      pthread_num_processors_np
+      pthread_win32_process_attach_np	(Required when statically linking
+                                         the library)
+      pthread_win32_process_detach_np	(Required when statically linking
+                                         the library)
+      pthread_win32_thread_attach_np	(Required when statically linking
+                                         the library)
+      pthread_win32_thread_detach_np	(Required when statically linking
+                                         the library)
+
+      ---------------------------
+      Static Initializers
+      ---------------------------
+      PTHREAD_ONCE_INIT
+      PTHREAD_MUTEX_INITIALIZER
+      PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+      PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+      PTHREAD_COND_INITIALIZER
+      PTHREAD_RWLOCK_INITIALIZER
+      PTHREAD_SPINLOCK_INITIALIZER
+
+      ---------------------------
+      Thread-Safe C Runtime Library (macros)
+      ---------------------------
+      strtok_r
+      asctime_r
+      ctime_r
+      gmtime_r
+      localtime_r
+      rand_r
+
+
+The following functions are not implemented:
+      
+      ---------------------------
+      RealTime Scheduling
+      ---------------------------
+      pthread_mutex_getprioceiling
+      pthread_mutex_setprioceiling
+      pthread_mutex_attr_getprioceiling
+      pthread_mutex_attr_getprotocol
+      pthread_mutex_attr_setprioceiling
+      pthread_mutex_attr_setprotocol
+
+      ---------------------------
+      Fork Handlers
+      ---------------------------
+      pthread_atfork
+
+      ---------------------------
+      Stdio
+      --------------------------- 
+      flockfile
+      ftrylockfile
+      funlockfile
+      getc_unlocked
+      getchar_unlocked	
+      putc_unlocked
+      putchar_unlocked
+
+      ---------------------------
+      Thread-Safe C Runtime Library
+      ---------------------------
+      readdir_r
+      getgrgid_r
+      getgrnam_r
+      getpwuid_r
+      getpwnam_r
+      
+      ---------------------------
+      Signals
+      ---------------------------
+      sigtimedwait
+      sigwait
+      sigwaitinfo
+
+      ---------------------------
+      General
+      ---------------------------
+      sysconf      
+
+The library includes two non-API functions for creating cancellation
+points in applications and libraries:
+      
+      pthreadCancelableWait
+      pthreadCancelableTimedWait
+
+      
+Availability
+------------ 
+
+The prebuilt DLL, export libs (for both MSVC and Mingw32), and the header
+files (pthread.h, semaphore.h, sched.h) are available along with the
+complete source code.
+
+The source code can be found at:
+
+	ftp://sources.redhat.com/pub/pthreads-win32
+
+and as individual source code files at
+
+	ftp://sources.redhat.com/pub/pthreads-win32/source
+
+The pre-built DLL, export libraries and include files can be found at:
+
+	ftp://sources.redhat.com/pub/pthreads-win32/dll-latest
+
+
+      
+Mailing List 
+------------  
+      
+There is a mailing list for discussing pthreads on Win32. To join,
+send email to:
+
+	[email protected]
+      
+
+Application Development Environments
+------------------------------------
+
+See the README file for more information.
+      
+MSVC:
+MSVC using SEH works. Distribute pthreadVSE.dll with your application.
+MSVC using C++ EH works. Distribute pthreadVCE.dll with your application.
+MSVC using C setjmp/longjmp works. Distribute pthreadVC.dll with your application.
+
+
+Mingw32:
+See the FAQ, Questions 6 and 10.
+
+Mingw using C++ EH works. Distribute pthreadGCE.dll with your application.
+Mingw using C setjmp/longjmp works. Distribute pthreadGC.dll with your application.
+
+
+Cygwin: (http://sourceware.cygnus.com/cygwin/)
+Developers using Cygwin will not need pthreads-win32 since it has POSIX threads
+support. Refer to its documentation for details and extent.
+
+
+UWIN:
+UWIN is a complete Unix-like environment for Windows from AT&T. Pthreads-win32
+doesn't currently support UWIN (and vice versa), but that may change in the
+future.
+
+Generally:
+For convenience, the following pre-built files are available on the FTP site
+(see Availability above):
+
+	pthread.h	- for POSIX 1c threads
+	semaphore.h	- for POSIX 1b semaphores
+	sched.h 	- for POSIX 1b scheduling
+	pthreadVCE.dll	- built with MSVC++ compiler using C++ EH
+	pthreadVCE.lib
+	pthreadVC.dll	- built with MSVC compiler using C setjmp/longjmp
+	pthreadVC.lib
+	pthreadVSE.dll	- built with MSVC compiler using SEH
+	pthreadVSE.lib
+	pthreadGCE.dll	- built with Mingw32 G++ 2.95.2-1
+	pthreadGC.dll	- built with Mingw32 GCC 2.95.2-1 using setjmp/longjmp
+	libpthreadGCE.a - derived from pthreadGCE.dll
+	libpthreadGC.a	- derived from pthreadGC.dll
+	gcc.dll 	- needed if distributing applications that use
+			  pthreadGCE.dll (but see the FAQ Q 10 for the latest
+			  related information)
+
+These are the only files you need in order to build POSIX threads
+applications for Win32 using either MSVC or Mingw32.
+
+See the FAQ file in the source tree for additional information.
+
+
+Documentation
+-------------
+
+For the authoritative reference, see the online POSIX
+standard reference at:
+
+       http://www.OpenGroup.org
+
+For POSIX Thread API programming, several reference books are
+available:
+
+       Programming with POSIX Threads
+       David R. Butenhof
+       Addison-Wesley (pub)
+
+       Pthreads Programming
+       By Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell
+       O'Reilly (pub)
+
+On the web: see the links at the bottom of the pthreads-win32 site:
+
+       http://sources.redhat.com/pthreads-win32/
+
+       Currently, there is no documentation included in the package apart
+       from the copious comments in the source code.
+
+
+
+Enjoy!
+
+Ross Johnson

+ 129 - 0
CONTRIBUTORS.ptw32

@@ -0,0 +1,129 @@
+Contributors (in approximate order of appearance)
+
+[See also the ChangeLog file where individuals are
+attributed in log entries. Likewise in the FAQ file.]
+
+Ben Elliston		bje at cygnus dot com
+					Initiated the project;
+					setup the project infrastructure (CVS, web page, etc.);
+					early prototype routines.
+Ross Johnson		rpj at callisto dot canberra dot edu dot au
+					early prototype routines;
+					ongoing project coordination/maintenance;
+					implementation of spin locks and barriers;
+					various enhancements;
+					bug fixes;
+					documentation;
+					testsuite.
+Robert Colquhoun	rjc at trump dot net dot au
+					Early bug fixes.
+John E. Bossom		John dot Bossom at cognos dot com
+					Contributed substantial original working implementation;
+					bug fixes;
+					ongoing guidance and standards interpretation.
+Anders Norlander	anorland at hem2 dot passagen dot se
+					Early enhancements and runtime checking for supported
+					Win32 routines.
+Tor Lillqvist		tml at iki dot fi
+					General enhancements;
+					early bug fixes to condition variables.
+Scott Lightner		scott at curriculum dot com
+					Bug fix.
+Kevin Ruland		Kevin dot Ruland at anheuser-busch dot com
+					Various bug fixes.
+Mike Russo		miker at eai dot com
+					Bug fix.
+Mark E. Armstrong	avail at pacbell dot net
+					Bug fixes.
+Lorin Hochstein 	lmh at xiphos dot ca
+					general bug fixes; bug fixes to condition variables.
+Peter Slacik		Peter dot Slacik at tatramed dot sk
+					Bug fixes.
+Mumit Khan		khan at xraylith dot wisc dot edu
+					Fixes to work with Mingw32.
+Milan Gardian		mg at tatramed dot sk
+					Bug fixes and reports/analyses of obscure problems.
+Aurelio Medina		aureliom at crt dot com
+					First implementation of read-write locks.
+Graham Dumpleton	Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au
+					Bug fix in condition variables.
+Tristan Savatier	tristan at mpegtv dot com
+					WinCE port.
+Erik Hensema		erik at hensema dot xs4all dot nl
+					Bug fixes.
+Rich Peters		rpeters at micro-magic dot com
+Todd Owen		towen at lucidcalm dot dropbear dot id dot au
+					Bug fixes to dll loading.
+Jason Nye		jnye at nbnet dot nb dot ca
+					Implementation of async cancelation.
+Fred Forester		fforest at eticomm dot net
+Kevin D. Clark		kclark at cabletron dot com
+David Baggett		dmb at itasoftware dot com
+					Bug fixes.
+Paul Redondo		paul at matchvision dot com
+Scott McCaskill 	scott at 3dfx dot com
+					Bug fixes.
+Jef Gearhart		jgearhart at tpssys dot com
+					Bug fix.
+Arthur Kantor		akantor at bexusa dot com
+					Mutex enhancements.
+Steven Reddie		smr at essemer dot com dot au
+					Bug fix.
+Alexander Terekhov	TEREKHOV at de dot ibm dot com
+					Re-implemented and improved read-write locks;
+					(with Louis Thomas) re-implemented and improved
+					condition variables;
+					enhancements to semaphores;
+					enhancements to mutexes;
+					new mutex implementation in 'futex' style;
+					suggested a robust implementation of pthread_once
+					similar to that implemented by V.Kliathcko;
+					system clock change handling re CV timeouts;
+					bug fixes.
+Thomas Pfaff		tpfaff at gmx dot net
+					Changes to make C version usable with C++ applications;
+					re-implemented mutex routines to avoid Win32 mutexes
+					and TryEnterCriticalSection;
+					procedure to fix Mingw32 thread-safety issues.
+Franco Bez		franco dot bez at gmx dot de
+					procedure to fix Mingw32 thread-safety issues.
+Louis Thomas		lthomas at arbitrade dot com
+					(with Alexander Terekhov) re-implemented and improved
+					condition variables.
+David Korn		dgk at research dot att dot com
+					Ported to UWIN.
+Phil Frisbie, Jr.	phil at hawksoft dot com
+					Bug fix.
+Ralf Brese		Ralf dot Brese at pdb4 dot siemens dot de
+					Bug fix.
+prionx at juno dot com 	prionx at juno dot com
+					Bug fixes.
+Max Woodbury		mtew at cds dot duke dot edu
+					POSIX versioning conditionals;
+					reduced namespace pollution;
+					idea to separate routines to reduce statically
+					linked image sizes.
+Rob Fanner		rfanner at stonethree dot com
+					Bug fix.
+Michael Johnson 	michaelj at maine dot rr dot com
+					Bug fix.
+Nicolas Barry		boozai at yahoo dot com
+					Bug fixes.
+Piet van Bruggen	pietvb at newbridges dot nl
+					Bug fix.
+Makoto Kato		raven at oldskool dot jp
+					AMD64 port.
+Panagiotis E. Hadjidoukas	peh at hpclab dot ceid dot upatras dot gr
+					Contributed the QueueUserAPCEx package which
+					makes preemptive async cancelation possible.
+Will Bryant		will dot bryant at ecosm dot com
+					Borland compiler patch and makefile.
+Anuj Goyal		anuj dot goyal at gmail dot com
+					Port to Digital Mars compiler.
+Gottlob Frege		gottlobfrege at  gmail dot com
+					re-implemented pthread_once (version 2)
+					(pthread_once cancellation added by rpj).
+Vladimir Kliatchko	vladimir at kliatchko dot com
+					reimplemented pthread_once with the same form
+					as described by A.Terekhov (later version 2);
+					implementation of MCS (Mellor-Crummey/Scott) locks.

+ 150 - 0
COPYING

@@ -0,0 +1,150 @@
+	pthreads-win32 - a POSIX threads library for Microsoft Windows
+
+
+This file is Copyrighted
+------------------------
+
+    This file is covered under the following Copyright:
+
+	Copyright (C) 2001,2006 Ross P. Johnson
+	All rights reserved.
+
+	Everyone is permitted to copy and distribute verbatim copies
+	of this license document, but changing it is not allowed.
+
+Pthreads-win32 is covered by the GNU Lesser General Public License
+------------------------------------------------------------------
+
+    Pthreads-win32 is open 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 version 2.1 of the
+    License.
+
+    Pthreads-win32 is several binary link libraries, several modules,
+    associated interface definition files and scripts used to control
+    its compilation and installation.
+
+    Pthreads-win32 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.
+
+    A copy of the GNU Lesser General Public License is distributed with
+    pthreads-win32 under the filename:
+
+	    COPYING.LIB
+
+    You should have received a copy of the version 2.1 GNU Lesser General
+    Public License with pthreads-win32; if not, write to:
+
+	    Free Software Foundation, Inc.
+	    59 Temple Place
+	    Suite 330
+	    Boston, MA	02111-1307
+	    USA
+
+    The contact addresses for pthreads-win32 is as follows:
+
+        Web:	http://sources.redhat.com/pthreads-win32
+        Email:  Ross Johnson
+                Please use: [email protected]
+
+
+
+Pthreads-win32 copyrights and exception files
+---------------------------------------------
+
+    With the exception of the files listed below, Pthreads-win32
+    is covered under the following GNU Lesser General Public License
+    Copyrights:
+
+	Pthreads-win32 - POSIX Threads Library for Win32
+	Copyright(C) 1998 John E. Bossom
+	Copyright(C) 1999,2006 Pthreads-win32 contributors
+
+	The current list of contributors is contained
+        in the file CONTRIBUTORS included with the source
+	code distribution. The current list of CONTRIBUTORS
+	can also be seen at the following WWW location:
+        http://sources.redhat.com/pthreads-win32/contributors.html
+
+    Contact Email: Ross Johnson
+                   Please use: [email protected]
+
+    These files are not covered under one of the Copyrights listed above:
+
+            COPYING
+	    COPYING.LIB
+            tests/rwlock7.c
+
+    This file, COPYING, is distributed under the Copyright found at the
+    top of this file.  It is important to note that you may distribute
+    verbatim copies of this file but you may not modify this file.
+
+    The file COPYING.LIB, which contains a copy of the version 2.1
+    GNU Lesser General Public License, is itself copyrighted by the
+    Free Software Foundation, Inc.  Please note that the Free Software
+    Foundation, Inc. does NOT have a copyright over Pthreads-win32,
+    only the COPYING.LIB that is supplied with pthreads-win32.
+
+    The file tests/rwlock7.c is derived from code written by
+    Dave Butenhof for his book 'Programming With POSIX(R) Threads'.
+    The original code was obtained by free download from his website
+    http://home.earthlink.net/~anneart/family/Threads/source.html
+    and did not contain a copyright or author notice. It is assumed to
+    be freely distributable.
+
+    In all cases one may use and distribute these exception files freely.
+    And because one may freely distribute the LGPL covered files, the
+    entire pthreads-win32 source may be freely used and distributed.
+
+
+
+General Copyleft and License info
+---------------------------------
+
+    For general information on Copylefts, see:
+
+	http://www.gnu.org/copyleft/
+
+    For information on GNU Lesser General Public Licenses, see:
+
+	http://www.gnu.org/copyleft/lesser.html
+	http://www.gnu.org/copyleft/lesser.txt
+
+
+Why pthreads-win32 did not use the GNU General Public License
+-------------------------------------------------------------
+
+    The goal of the pthreads-win32 project has been to
+    provide a quality and complete implementation of the POSIX
+    threads API for Microsoft Windows within the limits imposed
+    by virtue of it being a stand-alone library and not
+    linked directly to other POSIX compliant libraries. For
+    example, some functions and features, such as those based
+    on POSIX signals, are missing.
+
+    Pthreads-win32 is a library, available in several different
+    versions depending on supported compilers, and may be used
+    as a dynamically linked module or a statically linked set of
+    binary modules. It is not an application on it's own.
+
+    It was fully intended that pthreads-win32 be usable with
+    commercial software not covered by either the GPL or the LGPL
+    licenses. Pthreads-win32 has many contributors to it's
+    code base, many of whom have done so because they have
+    used the library in commercial or proprietry software
+    projects.
+
+    Releasing pthreads-win32 under the LGPL ensures that the
+    library can be used widely, while at the same time ensures
+    that bug fixes and improvements to the pthreads-win32 code
+    itself is returned to benefit all current and future users
+    of the library.
+
+    Although pthreads-win32 makes it possible for applications
+    that use POSIX threads to be ported to Win32 platforms, the
+    broader goal of the project is to encourage the use of open
+    standards, and in particular, to make it just a little easier
+    for developers writing Win32 applications to consider
+    widening the potential market for their products.

+ 504 - 0
COPYING.LIB

@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+

+ 5 - 0
TODO

@@ -0,0 +1,5 @@
+1. Clean up compiler #defines
+8. Check NP routines.
+9. Check for printfs
+10. Remove  -Werror from Makefiles
+

+ 154 - 0
cleanup.c

@@ -0,0 +1,154 @@
+/*
+ * cleanup.c
+ *
+ * Description:
+ * This translation unit implements routines associated
+ * with cleaning up threads.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * The functions pte_pop_cleanup and pte_push_cleanup
+ * are implemented here for applications written in C with no
+ * C++ destructor support.
+ */
+
+pte_cleanup_t *
+pte_pop_cleanup (int execute)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function pops the most recently pushed cleanup
+ *      handler. If execute is nonzero, then the cleanup handler
+ *      is executed if non-null.
+ *
+ * PARAMETERS
+ *      execute
+ *              if nonzero, execute the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ *      This function pops the most recently pushed cleanup
+ *      handler. If execute is nonzero, then the cleanup handler
+ *      is executed if non-null.
+ *      NOTE: specify 'execute' as nonzero to avoid duplication
+ *                of common cleanup code.
+ *
+ * RESULTS
+ *              N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+  pte_cleanup_t *cleanup;
+
+  cleanup = (pte_cleanup_t *) pthread_getspecific (pte_cleanupKey);
+
+  if (cleanup != NULL)
+    {
+      if (execute && (cleanup->routine != NULL))
+        {
+
+          (*cleanup->routine) (cleanup->arg);
+
+        }
+
+      pthread_setspecific (pte_cleanupKey, (void *) cleanup->prev);
+
+    }
+
+  return (cleanup);
+
+}				/* pte_pop_cleanup */
+
+
+void
+pte_push_cleanup (pte_cleanup_t * cleanup,
+                  pte_cleanup_callback_t routine, void *arg)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function pushes a new cleanup handler onto the thread's stack
+ *      of cleanup handlers. Each cleanup handler pushed onto the stack is
+ *      popped and invoked with the argument 'arg' when
+ *              a) the thread exits by calling 'pthread_exit',
+ *              b) when the thread acts on a cancellation request,
+ *              c) or when the thread calls pthread_cleanup_pop with a nonzero
+ *                 'execute' argument
+ *
+ * PARAMETERS
+ *      cleanup
+ *              a pointer to an instance of pthread_cleanup_t,
+ *
+ *      routine
+ *              pointer to a cleanup handler,
+ *
+ *      arg
+ *              parameter to be passed to the cleanup handler
+ *
+ *
+ * DESCRIPTION
+ *      This function pushes a new cleanup handler onto the thread's stack
+ *      of cleanup handlers. Each cleanup handler pushed onto the stack is
+ *      popped and invoked with the argument 'arg' when
+ *              a) the thread exits by calling 'pthread_exit',
+ *              b) when the thread acts on a cancellation request,
+ *              c) or when the thrad calls pthread_cleanup_pop with a nonzero
+ *                 'execute' argument
+ *      NOTE: pthread_push_cleanup, pte_pop_cleanup must be paired
+ *                in the same lexical scope.
+ *
+ * RESULTS
+ *              pthread_cleanup_t *
+ *                              pointer to the previous cleanup
+ *
+ * ------------------------------------------------------
+ */
+{
+  cleanup->routine = routine;
+  cleanup->arg = arg;
+
+  cleanup->prev = (pte_cleanup_t *) pthread_getspecific (pte_cleanupKey);
+
+  pthread_setspecific (pte_cleanupKey, (void *) cleanup);
+
+}				/* pte_push_cleanup */

+ 259 - 0
create.c

@@ -0,0 +1,259 @@
+/*
+ * create.c
+ *
+ * Description:
+ * This translation unit implements routines associated with spawning a new
+ * thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 "pte_osal.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_create (pthread_t * tid,
+                const pthread_attr_t * attr,
+                void *(*start) (void *), void *arg)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function creates a thread running the start function,
+ *      passing it the parameter value, 'arg'. The 'attr'
+ *      argument specifies optional creation attributes.
+ *      The identity of the new thread is returned
+ *      via 'tid', which should not be NULL.
+ *
+ * PARAMETERS
+ *      tid
+ *              pointer to an instance of pthread_t
+ *
+ *      attr
+ *              optional pointer to an instance of pthread_attr_t
+ *
+ *      start
+ *              pointer to the starting routine for the new thread
+ *
+ *      arg
+ *              optional parameter passed to 'start'
+ *
+ *
+ * DESCRIPTION
+ *      This function creates a thread running the start function,
+ *      passing it the parameter value, 'arg'. The 'attr'
+ *      argument specifies optional creation attributes.
+ *      The identity of the new thread is returned
+ *      via 'tid', which should not be the NULL pointer.
+ *
+ * RESULTS
+ *              0               successfully created thread,
+ *              EINVAL          attr invalid,
+ *              EAGAIN          insufficient resources.
+ *
+ * ------------------------------------------------------
+ */
+{
+  pthread_t thread;
+  pte_thread_t * tp;
+  register pthread_attr_t a;
+  int result = EAGAIN;
+  int run = PTE_TRUE;
+  ThreadParms *parms = NULL;
+  long stackSize;
+  int priority = 0;
+  pthread_t self;
+  pte_osResult osResult;
+
+  /*
+   * Before doing anything, check that tid can be stored through
+   * without invoking a memory protection error (segfault).
+   * Make sure that the assignment below can't be optimised out by the compiler.
+   * This is assured by conditionally assigning *tid again at the end.
+   */
+  if (tid != NULL)
+    {
+      tid->x = 0;
+    }
+
+  if (attr != NULL)
+    {
+      a = *attr;
+    }
+  else
+    {
+      a = NULL;
+    }
+
+  if ((thread = pte_new ()).p == NULL)
+    {
+      goto FAIL0;
+    }
+
+  tp = (pte_thread_t *) thread.p;
+
+  priority = tp->sched_priority;
+
+  if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
+    {
+      goto FAIL0;
+    }
+
+  parms->tid = thread;
+  parms->start = start;
+  parms->arg = arg;
+
+  if (a != NULL)
+    {
+      stackSize = a->stacksize;
+      tp->detachState = a->detachstate;
+      priority = a->param.sched_priority;
+
+      if ( (priority > pte_osThreadGetMaxPriority()) ||
+           (priority < pte_osThreadGetMinPriority()) )
+        {
+          result = EINVAL;
+          goto FAIL0;
+        }
+
+      /* Everything else */
+
+      /*
+       * Thread priority must be set to a valid system level
+       * without altering the value set by pthread_attr_setschedparam().
+       */
+
+      if (PTHREAD_INHERIT_SCHED == a->inheritsched)
+        {
+          /*
+           * If the thread that called pthread_create() is an OS thread
+           * then the inherited priority could be the result of a temporary
+           * system adjustment. This is not the case for POSIX threads.
+           */
+          self = pthread_self ();
+          priority = ((pte_thread_t *) self.p)->sched_priority;
+        }
+
+
+    }
+  else
+    {
+      /*
+       * Default stackSize
+       */
+      stackSize = PTHREAD_STACK_MIN;
+
+    }
+
+  tp->state = run ? PThreadStateInitial : PThreadStateSuspended;
+
+  tp->keys = NULL;
+
+  /*
+   * Threads must be started in suspended mode and resumed if necessary
+   * after _beginthreadex returns us the handle. Otherwise we set up a
+   * race condition between the creating and the created threads.
+   * Note that we also retain a local copy of the handle for use
+   * by us in case thread.p->threadH gets NULLed later but before we've
+   * finished with it here.
+   */
+  result = pthread_mutex_lock (&tp->threadLock);
+
+  if (0 == result)
+    {
+      /*
+       * Must record the thread's sched_priority as given,
+       * not as finally adjusted.
+       */
+      tp->sched_priority = priority;
+
+      (void) pthread_mutex_unlock (&tp->threadLock);
+    }
+
+  osResult = pte_osThreadCreate(pte_threadStart,
+                                stackSize,
+                                priority,
+                                parms,
+                                &(tp->threadId));
+
+  if (osResult == PTE_OS_OK)
+    {
+      pte_osThreadStart(tp->threadId);
+      result = 0;
+    }
+  else
+    {
+      tp->threadId = 0;
+      result = EAGAIN;
+      goto FAIL0;
+    }
+
+  /*
+   * Fall Through Intentionally
+   */
+
+  /*
+   * ------------
+   * Failure Code
+   * ------------
+   */
+
+FAIL0:
+  if (result != 0)
+    {
+
+      pte_threadDestroy (thread);
+      tp = NULL;
+
+      if (parms != NULL)
+        {
+          free (parms);
+        }
+    }
+  else
+    {
+      if (tid != NULL)
+        {
+          *tid = thread;
+        }
+    }
+
+  return (result);
+
+}				/* pthread_create */

+ 98 - 0
global.c

@@ -0,0 +1,98 @@
+/*
+ * global.c
+ *
+ * Description:
+ * This translation unit instantiates data associated with the implementation
+ * as a whole.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int pte_processInitialized = PTE_FALSE;
+pte_thread_t * pte_threadReuseTop = PTE_THREAD_REUSE_EMPTY;
+pte_thread_t * pte_threadReuseBottom = PTE_THREAD_REUSE_EMPTY;
+pthread_key_t pte_selfThreadKey = NULL;
+pthread_key_t pte_cleanupKey = NULL;
+pthread_cond_t pte_cond_list_head = NULL;
+pthread_cond_t pte_cond_list_tail = NULL;
+
+int pte_concurrency = 0;
+
+/* What features have been auto-detaected */
+int pte_features = 0;
+
+unsigned char pte_smp_system = PTE_TRUE;  /* Safer if assumed true initially. */
+
+/*
+ * Global lock for managing pthread_t struct reuse.
+ */
+pte_osMutexHandle pte_thread_reuse_lock;
+
+/*
+ * Global lock for testing internal state of statically declared mutexes.
+ */
+pte_osMutexHandle pte_mutex_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_COND_INITIALIZER
+ * created condition variables.
+ */
+pte_osMutexHandle pte_cond_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_RWLOCK_INITIALIZER
+ * created read/write locks.
+ */
+pte_osMutexHandle pte_rwlock_test_init_lock;
+
+/*
+ * Global lock for testing internal state of PTHREAD_SPINLOCK_INITIALIZER
+ * created spin locks.
+ */
+pte_osMutexHandle pte_spinlock_test_init_lock;
+
+/*
+ * Global lock for condition variable linked list. The list exists
+ * to wake up CVs when a WM_TIMECHANGE message arrives. See
+ * w32_TimeChangeHandler.c.
+ */
+pte_osMutexHandle pte_cond_list_lock;
+
+

+ 516 - 0
implement.h

@@ -0,0 +1,516 @@
+/*
+ * implement.h
+ *
+ * Definitions that don't need to be public.
+ *
+ * Keeps all the internals out of pthread.h
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#ifndef _IMPLEMENT_H
+#define _IMPLEMENT_H
+
+#include "pte_osal.h"
+
+/* use local include files during development */
+#include "semaphore.h"
+#include "sched.h"
+
+
+typedef enum
+{
+  /*
+   * This enumeration represents the state of the thread;
+   * The thread is still "alive" if the numeric value of the
+   * state is greater or equal "PThreadStateRunning".
+   */
+  PThreadStateInitial = 0,	/* Thread not running                   */
+  PThreadStateRunning,		/* Thread alive & kicking               */
+  PThreadStateSuspended,	/* Thread alive but suspended           */
+  PThreadStateCancelPending,	/* Thread alive but is                  */
+  /* has cancelation pending.        */
+  PThreadStateCanceling,	/* Thread alive but is                  */
+  /* in the process of terminating        */
+  /* due to a cancellation request        */
+  PThreadStateException,	/* Thread alive but exiting             */
+  /* due to an exception                  */
+  PThreadStateLast
+}
+PThreadState;
+
+
+typedef struct pte_thread_t_ pte_thread_t;
+
+struct pte_thread_t_
+  {
+    pte_osThreadHandle threadId;      /* OS specific thread handle */
+    pthread_t ptHandle;		/* This thread's permanent pthread_t handle */
+    pte_thread_t * prevReuse;	/* Links threads on reuse stack */
+    volatile PThreadState state;
+    void *exitStatus;
+    void *parms;
+    int ptErrno;
+    int detachState;
+    pthread_mutex_t threadLock;	/* Used for serialised access to public thread state */
+    int sched_priority;		/* As set, not as currently is */
+    pthread_mutex_t cancelLock;	/* Used for async-cancel safety */
+    int cancelState;
+    int cancelType;
+    int cancelEvent;
+#ifdef PTE_CLEANUP_C
+    jmp_buf start_mark;
+#endif	/* PTE_CLEANUP_C */
+int implicit:
+    1;
+    void *keys;
+    void *nextAssoc;
+  };
+
+
+/*
+ * Special value to mark attribute objects as valid.
+ */
+#define PTE_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
+
+struct pthread_attr_t_
+  {
+    unsigned long valid;
+    void *stackaddr;
+    size_t stacksize;
+    int detachstate;
+    struct sched_param param;
+    int inheritsched;
+    int contentionscope;
+  };
+
+
+/*
+ * ====================
+ * ====================
+ * Semaphores, Mutexes and Condition Variables
+ * ====================
+ * ====================
+ */
+
+struct sem_t_
+  {
+    int value;
+    pthread_mutex_t lock;
+    pte_osSemaphoreHandle sem;
+  };
+
+#define PTE_OBJECT_AUTO_INIT ((void *) -1)
+#define PTE_OBJECT_INVALID   0
+
+struct pthread_mutex_t_
+  {
+    pte_osSemaphoreHandle handle;
+    int lock_idx;
+    /* Provides exclusive access to mutex state
+    				   via the Interlocked* mechanism.
+    				    0: unlocked/free.
+    				    1: locked - no other waiters.
+    				   -1: locked - with possible other waiters.
+    				*/
+    int recursive_count;		/* Number of unlocks a thread needs to perform
+				   before the lock is released (recursive
+				   mutexes only). */
+    int kind;			/* Mutex type. */
+    pthread_t ownerThread;
+  };
+
+struct pthread_mutexattr_t_
+  {
+    int pshared;
+    int kind;
+  };
+
+/*
+ * Possible values, other than PTE_OBJECT_INVALID,
+ * for the "interlock" element in a spinlock.
+ *
+ * In this implementation, when a spinlock is initialised,
+ * the number of cpus available to the process is checked.
+ * If there is only one cpu then "interlock" is set equal to
+ * PTE_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
+ * If the number of cpus is greater than 1 then "interlock"
+ * is set equal to PTE_SPIN_UNLOCKED and the number is
+ * stored in u.cpus. This arrangement allows the spinlock
+ * routines to attempt an InterlockedCompareExchange on "interlock"
+ * immediately and, if that fails, to try the inferior mutex.
+ *
+ * "u.cpus" isn't used for anything yet, but could be used at
+ * some point to optimise spinlock behaviour.
+ */
+#define PTE_SPIN_UNLOCKED    (1)
+#define PTE_SPIN_LOCKED      (2)
+#define PTE_SPIN_USE_MUTEX   (3)
+
+struct pthread_spinlock_t_
+  {
+    int interlock;		/* Locking element for multi-cpus. */
+    union
+      {
+        int cpus;			/* No. of cpus if multi cpus, or   */
+        pthread_mutex_t mutex;	/* mutex if single cpu.            */
+      } u;
+  };
+
+struct pthread_barrier_t_
+  {
+    unsigned int nCurrentBarrierHeight;
+    unsigned int nInitialBarrierHeight;
+    int iStep;
+    int pshared;
+    sem_t semBarrierBreeched[2];
+  };
+
+struct pthread_barrierattr_t_
+  {
+    int pshared;
+  };
+
+struct pthread_key_t_
+  {
+    unsigned key;
+    void (*destructor) (void *);
+    pthread_mutex_t keyLock;
+    void *threads;
+  };
+
+
+typedef struct ThreadParms ThreadParms;
+typedef struct ThreadKeyAssoc ThreadKeyAssoc;
+
+struct ThreadParms
+  {
+    pthread_t tid;
+    void *(*start) (void *);
+    void *arg;
+  };
+
+struct pthread_cond_t_
+  {
+    long nWaitersBlocked;		/* Number of threads blocked            */
+    long nWaitersGone;		/* Number of threads timed out          */
+    long nWaitersToUnblock;	/* Number of threads to unblock         */
+    sem_t semBlockQueue;		/* Queue up threads waiting for the     */
+    /*   condition to become signalled      */
+    sem_t semBlockLock;		/* Semaphore that guards access to      */
+    /* | waiters blocked count/block queue  */
+    /* +-> Mandatory Sync.LEVEL-1           */
+    pthread_mutex_t mtxUnblockLock;	/* Mutex that guards access to          */
+    /* | waiters (to)unblock(ed) counts     */
+    /* +-> Optional* Sync.LEVEL-2           */
+    pthread_cond_t next;		/* Doubly linked list                   */
+    pthread_cond_t prev;
+  };
+
+
+struct pthread_condattr_t_
+  {
+    int pshared;
+  };
+
+#define PTE_RWLOCK_MAGIC 0xfacade2
+
+struct pthread_rwlock_t_
+  {
+    pthread_mutex_t mtxExclusiveAccess;
+    pthread_mutex_t mtxSharedAccessCompleted;
+    pthread_cond_t cndSharedAccessCompleted;
+    int nSharedAccessCount;
+    int nExclusiveAccessCount;
+    int nCompletedSharedAccessCount;
+    int nMagic;
+  };
+
+struct pthread_rwlockattr_t_
+  {
+    int pshared;
+  };
+
+/*
+ * MCS lock queue node - see pte_MCS_lock.c
+ */
+struct pte_mcs_node_t_
+  {
+    struct pte_mcs_node_t_ **lock;        /* ptr to tail of queue */
+    struct pte_mcs_node_t_  *next;        /* ptr to successor in queue */
+    unsigned int                       readyFlag;   /* set after lock is released by
+                                             predecessor */
+    unsigned int                       nextFlag;    /* set after 'next' ptr is set by
+                                             successor */
+  };
+
+typedef struct pte_mcs_node_t_   pte_mcs_local_node_t;
+typedef struct pte_mcs_node_t_  *pte_mcs_lock_t;
+
+
+struct ThreadKeyAssoc
+  {
+    /*
+     * Purpose:
+     *      This structure creates an association between a thread and a key.
+     *      It is used to implement the implicit invocation of a user defined
+     *      destroy routine for thread specific data registered by a user upon
+     *      exiting a thread.
+     *
+     *      Graphically, the arrangement is as follows, where:
+     *
+     *         K - Key with destructor
+     *            (head of chain is key->threads)
+     *         T - Thread that has called pthread_setspecific(Kn)
+     *            (head of chain is thread->keys)
+     *         A - Association. Each association is a node at the
+     *             intersection of two doubly-linked lists.
+     *
+     *                 T1    T2    T3
+     *                 |     |     |
+     *                 |     |     |
+     *         K1 -----+-----A-----A----->
+     *                 |     |     |
+     *                 |     |     |
+     *         K2 -----A-----A-----+----->
+     *                 |     |     |
+     *                 |     |     |
+     *         K3 -----A-----+-----A----->
+     *                 |     |     |
+     *                 |     |     |
+     *                 V     V     V
+     *
+     *      Access to the association is guarded by two locks: the key's
+     *      general lock (guarding the row) and the thread's general
+     *      lock (guarding the column). This avoids the need for a
+     *      dedicated lock for each association, which not only consumes
+     *      more handles but requires that: before the lock handle can
+     *      be released - both the key must be deleted and the thread
+     *      must have called the destructor. The two-lock arrangement
+     *      allows the resources to be freed as soon as either thread or
+     *      key is concluded.
+     *
+     *      To avoid deadlock: whenever both locks are required, the key
+     *      and thread locks are always acquired in the order: key lock
+     *      then thread lock. An exception to this exists when a thread
+     *      calls the destructors, however this is done carefully to
+     *      avoid deadlock.
+     *
+     *      An association is created when a thread first calls
+     *      pthread_setspecific() on a key that has a specified
+     *      destructor.
+     *
+     *      An association is destroyed either immediately after the
+     *      thread calls the key destructor function on thread exit, or
+     *      when the key is deleted.
+     *
+     * Attributes:
+     *      thread
+     *              reference to the thread that owns the
+     *              association. This is actually the pointer to the
+     *              thread struct itself. Since the association is
+     *              destroyed before the thread exits, this can never
+     *              point to a different logical thread to the one that
+     *              created the assoc, i.e. after thread struct reuse.
+     *
+     *      key
+     *              reference to the key that owns the association.
+     *
+     *      nextKey
+     *              The pthread_t->keys attribute is the head of a
+     *              chain of associations that runs through the nextKey
+     *              link. This chain provides the 1 to many relationship
+     *              between a pthread_t and all pthread_key_t on which
+     *              it called pthread_setspecific.
+     *
+     *      prevKey
+     *              Similarly.
+     *
+     *      nextThread
+     *              The pthread_key_t->threads attribute is the head of
+     *              a chain of assoctiations that runs through the
+     *              nextThreads link. This chain provides the 1 to many
+     *              relationship between a pthread_key_t and all the
+     *              PThreads that have called pthread_setspecific for
+     *              this pthread_key_t.
+     *
+     *      prevThread
+     *              Similarly.
+     *
+     * Notes:
+     *      1)      As soon as either the key or the thread is no longer
+     *              referencing the association, it can be destroyed. The
+     *              association will be removed from both chains.
+     *
+     *      2)      An association is only created by
+     *              pthread_setspecific if the user provided a
+     *              destroyRoutine when they created the key.
+     *
+     *
+     */
+    pte_thread_t * thread;
+    pthread_key_t key;
+    ThreadKeyAssoc *nextKey;
+    ThreadKeyAssoc *nextThread;
+    ThreadKeyAssoc *prevKey;
+    ThreadKeyAssoc *prevThread;
+  };
+
+/*
+ * Services available through EXCEPTION_PTE_SERVICES
+ * and also used [as parameters to pte_throw()] as
+ * generic exception selectors.
+ */
+
+#define PTE_EPS_EXIT                  (1)
+#define PTE_EPS_CANCEL                (2)
+
+
+/* Useful macros */
+#define PTE_MAX(a,b)  ((a)<(b)?(b):(a))
+#define PTE_MIN(a,b)  ((a)>(b)?(b):(a))
+
+
+/* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
+#define PTE_THREAD_REUSE_EMPTY ((pte_thread_t *) 1)
+
+extern int pte_processInitialized;
+extern pte_thread_t * pte_threadReuseTop;
+extern pte_thread_t * pte_threadReuseBottom;
+extern pthread_key_t pte_selfThreadKey;
+extern pthread_key_t pte_cleanupKey;
+extern pthread_cond_t pte_cond_list_head;
+extern pthread_cond_t pte_cond_list_tail;
+
+extern int pte_mutex_default_kind;
+
+extern int pte_concurrency;
+
+extern int pte_features;
+
+extern pte_osMutexHandle pte_thread_reuse_lock;
+extern pte_osMutexHandle pte_mutex_test_init_lock;
+extern pte_osMutexHandle pte_cond_list_lock;
+extern pte_osMutexHandle pte_cond_test_init_lock;
+extern pte_osMutexHandle pte_rwlock_test_init_lock;
+extern pte_osMutexHandle pte_spinlock_test_init_lock;
+
+
+#ifdef __cplusplus
+extern "C"
+  {
+#endif				/* __cplusplus */
+
+    /*
+     * =====================
+     * =====================
+     * Forward Declarations
+     * =====================
+     * =====================
+     */
+
+    int pte_is_attr (const pthread_attr_t * attr);
+
+    int pte_cond_check_need_init (pthread_cond_t * cond);
+    int pte_mutex_check_need_init (pthread_mutex_t * mutex);
+    int pte_rwlock_check_need_init (pthread_rwlock_t * rwlock);
+    int pte_spinlock_check_need_init (pthread_spinlock_t * lock);
+
+    int pte_processInitialize (void);
+
+    void pte_processTerminate (void);
+
+    void pte_threadDestroy (pthread_t tid);
+    void pte_threadExitAndDestroy (pthread_t tid);
+
+    void pte_pop_cleanup_all (int execute);
+
+    pthread_t pte_new (void);
+
+    pthread_t pte_threadReusePop (void);
+
+    void pte_threadReusePush (pthread_t thread);
+
+    int pte_getprocessors (int *count);
+
+    int pte_setthreadpriority (pthread_t thread, int policy, int priority);
+
+    void pte_rwlock_cancelwrwait (void *arg);
+
+    int pte_threadStart (void *vthreadParms);
+
+    void pte_callUserDestroyRoutines (pthread_t thread);
+
+    int pte_tkAssocCreate (pte_thread_t * thread, pthread_key_t key);
+
+    void pte_tkAssocDestroy (ThreadKeyAssoc * assoc);
+
+    int sem_wait_nocancel (sem_t * sem);
+
+    unsigned int pte_relmillisecs (const struct timespec * abstime);
+
+    void pte_mcs_lock_acquire (pte_mcs_lock_t * lock, pte_mcs_local_node_t * node);
+
+    void pte_mcs_lock_release (pte_mcs_local_node_t * node);
+
+    /* Declared in private.c */
+    void pte_throw (unsigned int exception);
+
+    int pte_cancellable_wait (pte_osSemaphoreHandle semHandle, unsigned int* timeout);
+
+#define PTE_ATOMIC_EXCHANGE pte_osAtomicExchange
+#define PTE_ATOMIC_EXCHANGE_ADD pte_osAtomicExchangeAdd
+#define PTE_ATOMIC_COMPARE_EXCHANGE pte_osAtomicCompareExchange
+#define PTE_ATOMIC_DECREMENT pte_osAtomicDecrement
+#define PTE_ATOMIC_INCREMENT pte_osAtomicIncrement
+
+    int  pte_thread_detach_np();
+    int  pte_thread_detach_and_exit_np();
+
+
+#ifdef __cplusplus
+}
+#endif				/* __cplusplus */
+
+
+#endif				/* _IMPLEMENT_H */

+ 90 - 0
need_errno.h

@@ -0,0 +1,90 @@
+/***
+* errno.h - system wide error numbers (set by system calls)
+*
+*       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
+*
+* Purpose:
+*       This file defines the system-wide error numbers (set by
+*       system calls).  Conforms to the XENIX standard.  Extended
+*       for compatibility with Uniforum standard.
+*       [System V]
+*
+*       [Public]
+*
+****/
+
+#ifndef _INC_ERRNO
+#define _INC_ERRNO
+
+#ifdef  __cplusplus
+extern "C"
+  {
+#endif
+
+
+
+    /* declare reference to errno */
+
+    extern int errno;
+
+    /* Error Codes */
+
+#define EPERM           1
+#define ENOENT          2
+#define ESRCH           3
+#define EINTR           4
+#define EIO             5
+#define ENXIO           6
+#define E2BIG           7
+#define ENOEXEC         8
+#define EBADF           9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         36
+
+    /* defined differently in winsock.h on WinCE */
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG    38
+#endif
+
+#define ENOLCK          39
+#define ENOSYS          40
+
+    /* defined differently in winsock.h on WinCE */
+#ifndef ENOTEMPTY
+#define ENOTEMPTY       41
+#endif
+
+#define EILSEQ          42
+
+    /*
+     * Support EDEADLOCK for compatibiity with older MS-C versions.
+     */
+#define EDEADLOCK       EDEADLK
+
+#ifdef  __cplusplus
+  }
+#endif
+
+#endif  /* _INC_ERRNO */

+ 26 - 0
platform/dspbios/dspbios-config.h

@@ -0,0 +1,26 @@
+/* config.h  */
+
+#ifndef PTE_CONFIG_H
+#define PTE_CONFIG_H
+
+#define PTE_STATIC_LIB
+
+/*********************************************************************
+ * Defaults: see target specific redefinitions below.
+ *********************************************************************/
+
+/* We're building the pthreads-win32 library */
+#define PTE_BUILD
+
+/* Define if you don't have Win32 errno. (eg. WinCE) */
+#undef NEED_ERRNO
+#define NEED_ERRNO
+
+/* Do we know about type mode_t? */
+#undef HAVE_MODE_T
+
+/* Define if you have the timespec struct */
+#undef HAVE_STRUCT_TIMESPEC
+//#define HAVE_STRUCT_TIMESPEC
+
+#endif

+ 923 - 0
platform/dspbios/dspbios-osal.c

@@ -0,0 +1,923 @@
+/*
+ * psp_osal.h
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 <stdio.h>
+#include <stdlib.h>
+
+#include <std.h>
+#include <clk.h>
+#include <lck.h>
+#include <mbx.h>
+
+#include <pthread.h>
+
+#include "tls-helper.h"
+#include "pte_osal.h"
+
+#define POLLING_DELAY_IN_ticks 10
+
+#define DSPBIOS_MAX_TLS 32
+
+#define DEFAULT_STACK_SIZE_BYTES 4096
+
+/*
+ * Data stored on a per-thread basis - allocated in pte_osThreadCreate
+ * and freed in pte_osThreadDelete.
+ */
+typedef struct dspbiosThreadData
+  {
+    /* Semaphore used to wait for threads to end.  Posted to in pte_osThreadExit() */
+    SEM_Handle joinSem;
+
+    /* Semaphore used for cancellation.  Posted to by pte_osThreadCancel, polled in pte_osSemaphoreCancellablePend */
+    SEM_Handle cancelSem;
+
+    /* Initial priority of the thread. */
+    int priority;
+
+  } dspbiosThreadData;
+
+
+/* Task and mailbox used for cleaning up detached threads */
+static TSK_Handle gcTaskHandle;
+static MBX_Handle gcMailbox;
+
+/* TLS key used to access dspbiosThreadData struct for reach thread. */
+static unsigned int threadDataKey;
+
+
+/*
+ *
+ * Helper functions
+ *
+ */
+
+/* Returns a pointer to the per thread control info */
+static dspbiosThreadData * getThreadData(TSK_Handle threadHandle)
+{
+
+  dspbiosThreadData *pThreadData;
+  void * pTls;
+
+  pTls = (void *) TSK_getenv(threadHandle);
+
+  pThreadData = (dspbiosThreadData *) pteTlsGetValue(pTls, threadDataKey);
+
+  return pThreadData;
+}
+
+/* Converts milliseconds to system ticks (for TSK_sleep, SEM_pend, etc) */
+static int msecsToSysTicks(int msecs)
+{
+  int ticks = CLK_countspms() / CLK_getprd() * msecs;
+
+  ticks = ticks / 100; // sim only
+
+  return ticks;
+}
+
+/* Garbage collector thread to free resources from detached threads */
+void dspbiosGarbageCollectorMain()
+{
+
+  gcMailbox = MBX_create(sizeof(void*), 10, NULL);
+
+  while (1)
+    {
+      Bool status;
+      void * pTask;
+
+      /* Wait for dying threads to post their handles to our mailbox */
+      status = MBX_pend(gcMailbox, &pTask, SYS_FOREVER);
+
+      if (status)
+        {
+          TSK_delete((TSK_Handle) pTask);
+        }
+    }
+
+  /* Never returns */
+}
+
+/****************************************************************************
+ *
+ * Initialization
+ *
+ ***************************************************************************/
+
+/*
+ * Initializes the OSAL.
+ *
+ *   1. Initialize TLS support.
+ *   2. Allocate control data TLS key.
+ *   3. Start garbage collector thread.
+ */
+pte_osResult pte_osInit(void)
+{
+  pte_osResult result;
+  TSK_Attrs attrs;
+
+  /* Allocate and initialize TLS support */
+  result = pteTlsGlobalInit(DSPBIOS_MAX_TLS);
+  
+  if (result == PTE_OS_OK)
+    {
+      /* Allocate a key that we use to store control information (e.g. cancellation semaphore) per thread */
+      result = pteTlsAlloc(&threadDataKey);
+
+      if (result == PTE_OS_OK)
+	{
+	  /* Create a low priority task to free resources for detached threads */
+	  attrs = TSK_ATTRS;
+	  attrs.priority = 1; /* just above idle task */
+	  attrs.name = "pthread-gc";
+
+	  gcTaskHandle = TSK_create((Fxn) dspbiosGarbageCollectorMain, &attrs);
+
+	  /* Give the garbage collector task a chance to run and create the mailbox */
+	  TSK_sleep(1);
+
+	  if (gcTaskHandle == NULL)
+	    {
+	      result = PTE_OS_NO_RESOURCES;
+	    }
+	}
+    }
+
+  return result;
+}
+
+/****************************************************************************
+ *
+ * Threads
+ *
+ ***************************************************************************/
+
+
+/* Entry point for new threads */
+void dspbiosStubThreadEntry (void *argv, pte_osThreadEntryPoint entryPoint)
+{
+  (*(entryPoint))(argv);
+  return;
+}
+
+/*
+ * Creates a new thread, allocates resources, etc.
+ *
+ * The thread is created in a suspended state; execution will actually start
+ * when pte_osThreadStart() is called.  Setting the priority to a -1 will start the
+ * thread in a suspended state.  pte_osThreadStart then sets the real priority which
+ * will start the thread executing.
+ *
+ * In order for dynamic tasks to work, you must set up a heap for DSP/BIOS to allocate their
+ * stacks from.  This should be done in the projects tcf or cdb file.
+ *
+ */
+pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint,
+                                int stackSize,
+                                int initialPriority,
+                                void *argv,
+                                pte_osThreadHandle* ppte_osThreadHandle)
+{
+  TSK_Handle handle;
+  TSK_Attrs attrs;
+  void *pTls;
+  pte_osResult result;
+  dspbiosThreadData *pThreadData;
+
+  /* Make sure that the stack we're going to allocate is big enough */
+  if (stackSize < DEFAULT_STACK_SIZE_BYTES)
+    {
+      stackSize = DEFAULT_STACK_SIZE_BYTES;
+    }
+
+  /* Allocate TLS structure for this thread. */
+  pTls = pteTlsThreadInit();
+  if (pTls == NULL)
+    {
+      result = PTE_OS_NO_RESOURCES;
+      goto FAIL0;
+    }
+
+
+  /* Allocate some memory for our per-thread control data.  We use this for:
+   *   1. join semaphore (used to wait for thread termination)
+   *   2. cancellation semaphore (used to signal a thread to cancel)
+   *   3. initial priority (used in stub entry point)
+   */
+  pThreadData = (dspbiosThreadData*) malloc(sizeof(dspbiosThreadData));
+
+  if (pThreadData == NULL)
+    {
+      pteTlsThreadDestroy(pTls);
+
+      result = PTE_OS_NO_RESOURCES;
+      goto FAIL0;
+    }
+
+  /* Save a pointer to our per-thread control data as a TLS value */
+  pteTlsSetValue(pTls, threadDataKey, pThreadData);
+
+  /* Create semaphores and save handles */
+  pThreadData->joinSem = SEM_create(0, NULL);
+  pThreadData->cancelSem = SEM_create(0, NULL);
+
+  /* Save the initial priority - we need it when we
+   * actually start the thread */
+  pThreadData->priority = initialPriority;
+
+  /*
+   * Fill out parameters for TSK_create:
+   */
+  attrs = TSK_ATTRS;
+
+  /* Use  value specified by user */
+  attrs.stacksize = stackSize;
+
+  attrs.priority  = -1;
+
+  /* Save our TLS structure as the task's environment. */
+  attrs.environ   = pTls;
+
+  handle = TSK_create((Fxn) dspbiosStubThreadEntry, &attrs, argv, entryPoint);
+
+  if (handle != NULL)
+    {
+      /* Everything worked, return handle to caller */
+      *ppte_osThreadHandle = handle;
+      result = PTE_OS_OK;
+    }
+  else
+    {
+      /* Something went wrong - assume that it was due to lack of resources. */
+      free(pThreadData);
+      pteTlsThreadDestroy(pTls);
+
+      result = PTE_OS_NO_RESOURCES;
+    }
+
+FAIL0:
+  return result;
+}
+
+/* Start executing a thread.
+ *
+ * Get the priority that the user specified when they called
+ * pte_osThreadCreate and set the priority of the thread.  This
+ * will start the thread executing.
+ */
+pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle)
+{
+
+  dspbiosThreadData *pThreadData;
+
+  pThreadData = getThreadData(osThreadHandle);
+
+  TSK_setpri(osThreadHandle, pThreadData->priority);
+
+  return PTE_OS_OK;
+
+}
+
+
+/*
+ * Exit from a thread.
+ *
+ * Post to the join semaphore in case a pthread_join is
+ * waiting for us to exit.
+ */
+void pte_osThreadExit()
+{
+  TSK_Handle thisTask;
+  dspbiosThreadData *pThreadData;
+
+  thisTask = TSK_self();
+
+  pThreadData = getThreadData(thisTask);
+
+  if (pThreadData != NULL)
+    {
+      SEM_post(pThreadData->joinSem);
+    }
+
+  TSK_exit();
+
+}
+
+pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle)
+{
+  dspbiosThreadData *pThreadData;
+  void * pTls;
+
+  pThreadData = getThreadData(handle);
+
+  pTls = (void *) TSK_getenv(handle);
+
+  /* Free the per thread data (join & cancel semaphores, etc) */
+  SEM_delete(pThreadData->joinSem);
+  SEM_delete(pThreadData->cancelSem);
+
+  free(pThreadData);
+
+  /* Free the TLS data structure */
+  pteTlsThreadDestroy(pTls);
+
+  /* Send thread handle to garbage collector task so it can free
+   * resources from a different context */
+  MBX_post(gcMailbox, &handle, SYS_FOREVER);
+
+  TSK_exit();
+  
+  return PTE_OS_OK;
+}
+
+/* Clean up a thread.
+ *
+ * If this is called from the thread itself, instead of actually freeing up
+ * resources, post the thread handle to a mailbox which will be picked
+ * up by the garbage collector thread.  Resources will be freed from there.
+ * This is necessary because DSP/BIOS does not free resources when a
+ * thread exits.
+ */
+pte_osResult pte_osThreadDelete(pte_osThreadHandle handle)
+{
+
+  dspbiosThreadData *pThreadData;
+  void * pTls;
+
+  pThreadData = getThreadData(handle);
+
+  pTls = (void *) TSK_getenv(handle);
+
+  /* Free the per thread data (join & cancel semaphores, etc) */
+  SEM_delete(pThreadData->joinSem);
+  SEM_delete(pThreadData->cancelSem);
+
+  free(pThreadData);
+
+  /* Free the TLS data structure */
+  pteTlsThreadDestroy(pTls);
+
+  TSK_delete(handle);
+
+  return PTE_OS_OK;
+}
+
+/* Wait for a thread to exit.
+ *
+ * Since DSP/BIOS doesn't have a explicit system call for this, we
+ * emulate it using a semaphore that is posted to when the thread
+ * exits.
+ */
+pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle)
+{
+  TSK_Stat taskStats;
+  pte_osResult result;
+
+  /* Prevent context switches to prevent the thread from
+   * changing states */
+  TSK_disable();
+
+  /* First, check if the thread has already terminated. */
+  TSK_stat(threadHandle, &taskStats);
+
+  if (taskStats.mode != TSK_TERMINATED)
+    {
+      dspbiosThreadData *pThreadData;
+      dspbiosThreadData *pSelfThreadData;
+
+      pThreadData = getThreadData(threadHandle);
+      pSelfThreadData = getThreadData(TSK_self());
+
+      TSK_enable();
+
+      /* This needs to be cancellable, so poll instead of block,
+       * similar to what we do for pte_OsSemaphoreCancellablePend. */
+      while (1)
+	{
+	  if (SEM_count(pThreadData->joinSem) > 0)
+	    {
+	      /* The thread has exited. */
+	      result = PTE_OS_OK;
+	      break;
+	    }
+	  else if ((pSelfThreadData != NULL) && SEM_count(pSelfThreadData->cancelSem) > 0)
+	    {
+	      /* The thread was cancelled */
+	      result = PTE_OS_INTERRUPTED;
+	      break;
+	    }
+          else
+            {
+              /* Nothing found and not timed out yet; let's yield so we're not
+               * in busy loop. */
+              TSK_sleep(POLLING_DELAY_IN_ticks);
+            }
+        }
+
+    }
+  else
+    {
+      /* Thread is already terminated, just return OK */
+      TSK_enable();
+      result = PTE_OS_OK;
+    }
+
+  return result;
+}
+
+/* Cancels the specified thread.  This will 1) make pte_osSemaphoreCancellablePend return if it is currently
+ * blocked and will make pte_osThreadCheckCancel return TRUE.
+ *
+ * To accomplish this, we post to the cancellation semaphore for the specified thread.
+ */
+pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle)
+{
+  dspbiosThreadData *pThreadData;
+
+  pThreadData = getThreadData(threadHandle);
+
+  if (pThreadData != NULL)
+    {
+      SEM_post(pThreadData->cancelSem);
+    }
+
+  return PTE_OS_OK;
+}
+
+
+/*
+ * Checks to see if pte_osThreadCancel has been called for the specified thread.  Just check the
+ * value of the cancellation semaphore associated with the thread.
+ */
+pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle)
+{
+
+  dspbiosThreadData *pThreadData;
+
+  pThreadData = getThreadData(threadHandle);
+
+  if (pThreadData != NULL)
+    {
+      if (SEM_count(pThreadData->cancelSem) > 0)
+        {
+          return PTE_OS_INTERRUPTED;
+        }
+      else
+        {
+          return PTE_OS_OK;
+        }
+    }
+  else
+    {
+      /* We're being called from a pure OS thread which can't be cancelled. */
+      return PTE_OS_OK;
+    }
+
+
+}
+
+void pte_osThreadSleep(unsigned int msecs)
+{
+  int ticks = msecsToSysTicks(msecs);
+
+  TSK_sleep(ticks);
+}
+
+pte_osThreadHandle pte_osThreadGetHandle(void)
+{
+  return TSK_self();
+}
+
+int pte_osThreadGetPriority(pte_osThreadHandle threadHandle)
+{
+  return TSK_getpri(threadHandle);
+}
+
+pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority)
+{
+  TSK_setpri(threadHandle, newPriority);
+
+  return PTE_OS_OK;
+}
+
+int pte_osThreadGetMinPriority()
+{
+  return TSK_MINPRI;
+}
+
+int pte_osThreadGetMaxPriority()
+{
+  return TSK_MAXPRI;
+}
+
+int pte_osThreadGetDefaultPriority()
+{
+  /* Pick something in the middle */
+  return ((TSK_MINPRI + TSK_MAXPRI) / 2);
+}
+
+/****************************************************************************
+ *
+ * Mutexes
+ *
+ ***************************************************************************/
+
+pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle)
+{
+
+  *pHandle = LCK_create(NULL);
+
+  if (*pHandle == NULL)
+    {
+      return PTE_OS_NO_RESOURCES;
+    }
+  else
+    {
+      return PTE_OS_OK;
+    }
+}
+
+pte_osResult pte_osMutexDelete(pte_osMutexHandle handle)
+{
+  LCK_delete(handle);
+
+  return PTE_OS_OK;
+}
+
+pte_osResult pte_osMutexLock(pte_osMutexHandle handle)
+{
+  LCK_pend(handle, SYS_FOREVER);
+
+  return PTE_OS_OK;
+}
+
+pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle)
+{
+
+  LCK_post(handle);
+
+  return PTE_OS_OK;
+}
+
+/****************************************************************************
+ *
+ * Semaphores
+ *
+ ***************************************************************************/
+
+pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle)
+{
+
+  *pHandle = SEM_create(initialValue, NULL);
+
+  if (*pHandle == NULL)
+    {
+      return PTE_OS_NO_RESOURCES;
+    }
+  else
+    {
+      return PTE_OS_OK;
+    }
+
+}
+
+pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle)
+{
+  SEM_delete(handle);
+
+  return PTE_OS_OK;
+}
+
+
+pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count)
+{
+  int i;
+
+  for (i=0;i<count;i++)
+    {
+      SEM_post(handle);
+    }
+
+  return PTE_OS_OK;
+}
+
+pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeoutMsecs)
+{
+  Bool status;
+  unsigned int timeoutTicks;
+
+  if (pTimeoutMsecs == NULL)
+    {
+      timeoutTicks = SYS_FOREVER;
+    }
+  else
+    {
+      timeoutTicks = msecsToSysTicks(*pTimeoutMsecs);
+    }
+
+
+  status = SEM_pend(handle, timeoutTicks);
+
+  if (status)
+    {
+      return PTE_OS_OK;
+    }
+  else
+    {
+      return PTE_OS_TIMEOUT;
+    }
+
+}
+
+
+
+/*
+ * Pend on a semaphore- and allow the pend to be cancelled.
+ *
+ * DSP/BIOS provides no functionality to asynchronously interrupt a blocked call.  We simulte
+ * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop.
+ */
+pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout)
+{
+
+
+  clock_t start_time;
+  clock_t current_time;
+  pte_osResult result =  PTE_OS_OK;
+  int timeout;
+
+  dspbiosThreadData *pThreadData;
+
+  pThreadData = getThreadData(TSK_self());
+
+
+  start_time = CLK_getltime();
+
+  if (pTimeout == NULL)
+    {
+      timeout = -1;
+    }
+  else
+    {
+      timeout = msecsToSysTicks(*pTimeout);
+    }
+
+  while (1)
+    {
+      Bool semTimeout;
+      int status;
+
+      /* Poll semaphore */
+      semTimeout = 0;
+
+      current_time = CLK_getltime();
+
+      status = SEM_pend(semHandle, semTimeout);
+
+      if (status == TRUE)
+        {
+          /* The user semaphore was posted to */
+          result = PTE_OS_OK;
+          break;
+        }
+      else if ((timeout != -1) && ((current_time - start_time) > timeout))
+        {
+          /* The timeout expired */
+          result = PTE_OS_TIMEOUT;
+          break;
+        }
+      else
+        {
+          if ((pThreadData != NULL) && SEM_count(pThreadData->cancelSem) > 0)
+            {
+              /* The thread was cancelled */
+              result = PTE_OS_INTERRUPTED;
+              break;
+            }
+          else
+            {
+              /* Nothing found and not timed out yet; let's yield so we're not
+               * in busy loop. */
+              TSK_sleep(POLLING_DELAY_IN_ticks);
+            }
+        }
+
+    }
+
+  return result;
+
+}
+
+
+/****************************************************************************
+ *
+ * Atomic Operations
+ *
+ ***************************************************************************/
+int pte_osAtomicExchange(int *ptarg, int val)
+{
+
+  long origVal;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+  origVal = *ptarg;
+
+  *ptarg = val;
+
+  HWI_restore(oldCSR);
+
+  return origVal;
+
+}
+
+int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp)
+{
+
+  int origVal;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+
+  origVal = *pdest;
+
+  if (*pdest == comp)
+    {
+      *pdest = exchange;
+    }
+
+  HWI_restore(oldCSR);
+
+
+  return origVal;
+
+}
+
+int pte_osAtomicExchangeAddInt(int volatile* pAddend, int value)
+{
+
+  int origVal;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+
+  origVal = *pAddend;
+
+  *pAddend += value;
+
+  HWI_restore(oldCSR);
+
+
+  return origVal;
+
+}
+
+int pte_osAtomicExchangeAdd(int volatile* pAddend, int value)
+{
+
+  int origVal;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+
+  origVal = *pAddend;
+
+  *pAddend += value;
+
+  HWI_restore(oldCSR);
+
+
+  return origVal;
+}
+
+int pte_osAtomicDecrement(int *pdest)
+{
+  int val;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+
+  (*pdest)--;
+  val = *pdest;
+
+  HWI_restore(oldCSR);
+
+  return val;
+
+}
+
+int pte_osAtomicIncrement(int *pdest)
+{
+  int val;
+  Uns oldCSR;
+
+  oldCSR = HWI_disable();
+
+  (*pdest)++;
+
+  val = *pdest;
+
+  HWI_restore(oldCSR);
+
+
+  return val;
+}
+
+/****************************************************************************
+ *
+ * Thread Local Storage
+ *
+ ***************************************************************************/
+
+pte_osResult pte_osTlsSetValue(unsigned int index, void * value)
+{
+  void *pTls;
+
+  pTls = (void *) TSK_getenv(TSK_self());
+
+  if (pTls == NULL)
+    {
+      // Apparently no TLS structure has been allocated for this thread
+      // Probably because this is a native OS thread
+      pTls = pteTlsThreadInit();
+
+
+      TSK_setenv(TSK_self(), pTls);
+    }
+
+  return pteTlsSetValue(pTls, index, value);
+}
+
+
+
+void * pte_osTlsGetValue(unsigned int index)
+{
+  void *pTls;
+
+  pTls = (void *) TSK_getenv(TSK_self());
+
+  return (void *) pteTlsGetValue(pTls, index);
+
+}
+
+
+// Note that key value must be > 0
+pte_osResult pte_osTlsAlloc(unsigned int *pKey)
+{
+  return pteTlsAlloc(pKey);
+}
+
+
+pte_osResult pte_osTlsFree(unsigned int index)
+{
+  return pteTlsFree(index);
+
+}
+
+
+int ftime(struct timeb *tp)
+{
+  int ltime = (CLK_getltime() * CLK_cpuCyclesPerLtime()) / CLK_cpuCyclesPerLtime();
+  int secs = ltime / 1000;
+  int msecs = ltime % 1000;
+
+  tp->dstflag = 0;
+  tp->timezone = 0;
+  tp->time = secs;
+  tp->millitm = msecs;
+
+  return 0;
+}
+
+

+ 102 - 0
platform/dspbios/dspbios-osal.h

@@ -0,0 +1,102 @@
+/*
+ * dspbios-osal.h
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 <std.h>
+#include <tsk.h>
+#include <sem.h>
+#include <lck.h>
+#include <errno.h>
+
+typedef TSK_Handle pte_osThreadHandle;
+
+typedef SEM_Handle pte_osSemaphoreHandle;
+
+typedef LCK_Handle pte_osMutexHandle;
+
+#define OS_DEFAULT_PRIO 11
+
+#define OS_MAX_SIMUL_THREADS 10
+
+
+
+
+#ifndef EPERM
+#define EPERM           1
+#endif // EPERM
+
+#ifndef ESRCH
+#define ESRCH           3
+#endif // ESRCH
+
+#ifndef EINTR
+#define EINTR           4
+#endif // EINTR
+
+#ifndef EIO
+#define EIO             5
+#endif // EIO
+
+#ifndef EAGAIN
+#define EAGAIN          11
+#endif // EAGAIN
+
+#ifndef ENOMEM
+#define ENOMEM          12
+#endif // ENOMEM
+
+#ifndef EBUSY
+#define EBUSY           16
+#endif // EBUSY
+
+#ifndef EINVAL
+#define EINVAL          22
+#endif // EINVAL
+
+#ifndef ENOSPC
+#define ENOSPC          28
+#endif // ENOSPC
+
+#ifndef EDEADLK
+#define EDEADLK         35
+#endif /* EDEADLK */
+
+#ifndef ENOSYS
+#define ENOSYS          38
+#endif /* ENOSYS */
+
+#ifndef ENOTSUP
+#define ENOTSUP         95
+#endif /* ENOTSUP */
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT       116
+#endif // ETIMEDOUT
+
+
+
+

+ 46 - 0
platform/dspbios/main.c

@@ -0,0 +1,46 @@
+/*
+ * psp_osal.h
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 <std.h>
+#include <tsk.h>
+
+extern void pte_test_main();
+
+int main(void)
+{
+
+  // Start tests from a task as most DSP/BIOS API calls cannot
+  // be made from main
+  struct TSK_Attrs attrs;
+
+  attrs = TSK_ATTRS;
+
+  attrs.stacksize = 4*1024;
+
+  TSK_create((Fxn)pte_test_main,&attrs);
+}

+ 36 - 0
platform/dspbios/pte-config.h

@@ -0,0 +1,36 @@
+/* config.h  */
+
+#ifndef PTE_CONFIG_H
+#define PTE_CONFIG_H
+
+#include <time.h>
+
+/*********************************************************************
+ * Defaults: see target specific redefinitions below.
+ *********************************************************************/
+
+/* We're building the pthreads-win32 library */
+#define PTE_BUILD
+
+#undef PTE_SUPPORT_ASYNC_CANCEL
+
+typedef int pid_t;
+
+struct timespec
+{
+  time_t  tv_sec;
+  long    tv_nsec;   
+};
+
+typedef unsigned int mode_t;
+
+
+struct timeb
+{ 
+  time_t time;
+  unsigned short millitm;
+  short timezone;
+  short dstflag;
+};
+
+#endif

+ 156 - 0
platform/dspbios/pte_lib/pte_lib.pjt

@@ -0,0 +1,156 @@
+; Code Composer Project File, Version 2.0 (do not modify or remove this line)
+
+[Project Settings]
+ProjectDir="Z:\pthread\platform\dspbios\pte_lib\"
+ProjectType=Library
+CPUFamily=TMS320C64XX
+Tool="Archiver"
+Tool="Compiler"
+Tool="CustomBuilder"
+Tool="DspBiosBuilder"
+Config="C"
+Config="CPP"
+
+[Source Files]
+Source="..\..\..\cleanup.c"
+Source="..\..\..\create.c"
+Source="..\..\..\global.c"
+Source="..\..\..\pte_callUserDestroyRoutines.c"
+Source="..\..\..\pte_cancellable_wait.c"
+Source="..\..\..\pte_cond_check_need_init.c"
+Source="..\..\..\pte_detach.c"
+Source="..\..\..\pte_getprocessors.c"
+Source="..\..\..\pte_is_attr.c"
+Source="..\..\..\pte_mutex_check_need_init.c"
+Source="..\..\..\pte_new.c"
+Source="..\..\..\pte_relmillisecs.c"
+Source="..\..\..\pte_reuse.c"
+Source="..\..\..\pte_rwlock_cancelwrwait.c"
+Source="..\..\..\pte_rwlock_check_need_init.c"
+Source="..\..\..\pte_spinlock_check_need_init.c"
+Source="..\..\..\pte_threadDestroy.c"
+Source="..\..\..\pte_threadStart.c"
+Source="..\..\..\pte_throw.c"
+Source="..\..\..\pte_tkAssocCreate.c"
+Source="..\..\..\pte_tkAssocDestroy.c"
+Source="..\..\..\pthread_attr_destroy.c"
+Source="..\..\..\pthread_attr_getdetachstate.c"
+Source="..\..\..\pthread_attr_getinheritsched.c"
+Source="..\..\..\pthread_attr_getschedparam.c"
+Source="..\..\..\pthread_attr_getschedpolicy.c"
+Source="..\..\..\pthread_attr_getscope.c"
+Source="..\..\..\pthread_attr_getstackaddr.c"
+Source="..\..\..\pthread_attr_getstacksize.c"
+Source="..\..\..\pthread_attr_init.c"
+Source="..\..\..\pthread_attr_setdetachstate.c"
+Source="..\..\..\pthread_attr_setinheritsched.c"
+Source="..\..\..\pthread_attr_setschedparam.c"
+Source="..\..\..\pthread_attr_setschedpolicy.c"
+Source="..\..\..\pthread_attr_setscope.c"
+Source="..\..\..\pthread_attr_setstackaddr.c"
+Source="..\..\..\pthread_attr_setstacksize.c"
+Source="..\..\..\pthread_barrier_destroy.c"
+Source="..\..\..\pthread_barrier_init.c"
+Source="..\..\..\pthread_barrier_wait.c"
+Source="..\..\..\pthread_barrierattr_destroy.c"
+Source="..\..\..\pthread_barrierattr_getpshared.c"
+Source="..\..\..\pthread_barrierattr_init.c"
+Source="..\..\..\pthread_barrierattr_setpshared.c"
+Source="..\..\..\pthread_cancel.c"
+Source="..\..\..\pthread_cond_destroy.c"
+Source="..\..\..\pthread_cond_init.c"
+Source="..\..\..\pthread_cond_signal.c"
+Source="..\..\..\pthread_cond_wait.c"
+Source="..\..\..\pthread_condattr_destroy.c"
+Source="..\..\..\pthread_condattr_getpshared.c"
+Source="..\..\..\pthread_condattr_init.c"
+Source="..\..\..\pthread_condattr_setpshared.c"
+Source="..\..\..\pthread_delay_np.c"
+Source="..\..\..\pthread_detach.c"
+Source="..\..\..\pthread_equal.c"
+Source="..\..\..\pthread_exit.c"
+Source="..\..\..\pthread_getconcurrency.c"
+Source="..\..\..\pthread_getschedparam.c"
+Source="..\..\..\pthread_getspecific.c"
+Source="..\..\..\pthread_init.c"
+Source="..\..\..\pthread_join.c"
+Source="..\..\..\pthread_key_create.c"
+Source="..\..\..\pthread_key_delete.c"
+Source="..\..\..\pthread_kill.c"
+Source="..\..\..\pthread_mutex_destroy.c"
+Source="..\..\..\pthread_mutex_init.c"
+Source="..\..\..\pthread_mutex_lock.c"
+Source="..\..\..\pthread_mutex_timedlock.c"
+Source="..\..\..\pthread_mutex_trylock.c"
+Source="..\..\..\pthread_mutex_unlock.c"
+Source="..\..\..\pthread_mutexattr_destroy.c"
+Source="..\..\..\pthread_mutexattr_getkind_np.c"
+Source="..\..\..\pthread_mutexattr_getpshared.c"
+Source="..\..\..\pthread_mutexattr_gettype.c"
+Source="..\..\..\pthread_mutexattr_init.c"
+Source="..\..\..\pthread_mutexattr_setkind_np.c"
+Source="..\..\..\pthread_mutexattr_setpshared.c"
+Source="..\..\..\pthread_mutexattr_settype.c"
+Source="..\..\..\pthread_num_processors_np.c"
+Source="..\..\..\pthread_once.c"
+Source="..\..\..\pthread_rwlock_destroy.c"
+Source="..\..\..\pthread_rwlock_init.c"
+Source="..\..\..\pthread_rwlock_rdlock.c"
+Source="..\..\..\pthread_rwlock_timedrdlock.c"
+Source="..\..\..\pthread_rwlock_timedwrlock.c"
+Source="..\..\..\pthread_rwlock_tryrdlock.c"
+Source="..\..\..\pthread_rwlock_trywrlock.c"
+Source="..\..\..\pthread_rwlock_unlock.c"
+Source="..\..\..\pthread_rwlock_wrlock.c"
+Source="..\..\..\pthread_rwlockattr_destroy.c"
+Source="..\..\..\pthread_rwlockattr_getpshared.c"
+Source="..\..\..\pthread_rwlockattr_init.c"
+Source="..\..\..\pthread_rwlockattr_setpshared.c"
+Source="..\..\..\pthread_self.c"
+Source="..\..\..\pthread_setcancelstate.c"
+Source="..\..\..\pthread_setcanceltype.c"
+Source="..\..\..\pthread_setconcurrency.c"
+Source="..\..\..\pthread_setschedparam.c"
+Source="..\..\..\pthread_setspecific.c"
+Source="..\..\..\pthread_spin_destroy.c"
+Source="..\..\..\pthread_spin_init.c"
+Source="..\..\..\pthread_spin_lock.c"
+Source="..\..\..\pthread_spin_trylock.c"
+Source="..\..\..\pthread_spin_unlock.c"
+Source="..\..\..\pthread_terminate.c"
+Source="..\..\..\pthread_testcancel.c"
+Source="..\..\..\pthread_timechange_handler_np.c"
+Source="..\..\..\sched_get_priority_max.c"
+Source="..\..\..\sched_get_priority_min.c"
+Source="..\..\..\sched_setscheduler.c"
+Source="..\..\..\sched_yield.c"
+Source="..\..\..\sem_close.c"
+Source="..\..\..\sem_destroy.c"
+Source="..\..\..\sem_getvalue.c"
+Source="..\..\..\sem_init.c"
+Source="..\..\..\sem_open.c"
+Source="..\..\..\sem_post.c"
+Source="..\..\..\sem_post_multiple.c"
+Source="..\..\..\sem_timedwait.c"
+Source="..\..\..\sem_trywait.c"
+Source="..\..\..\sem_unlink.c"
+Source="..\..\..\sem_wait.c"
+
+["Archiver" Settings: "C"]
+Options=-r -o".\C\pte_lib.lib"
+
+["Archiver" Settings: "CPP"]
+Options=-r -o".\CPP\pte_lib.lib"
+
+["Compiler" Settings: "C"]
+Options=-g -fr"$(Proj_dir)\C" -i".\platform\dspbios" -i"." -d"_DEBUG" -mv6400
+
+["Compiler" Settings: "CPP"]
+Options=-g -fg -fr"$(Proj_dir)\CPP" -i".\platform\dspbios" -i"." -d"_DEBUG" -d"__CLEANUP_CXX" -mv6400 --exceptions
+
+["..\..\..\pte_threadStart.c" Settings: "CPP"]
+Options="Compiler" +{-fg}
+
+["..\..\..\pte_throw.c" Settings: "CPP"]
+Options="Compiler" +{-fg}
+

+ 12 - 0
platform/dspbios/pte_osal.h

@@ -0,0 +1,12 @@
+
+#ifndef _OS_SUPPORT_H_
+#define _OS_SUPPORT_H_
+
+// Platform specific one must be included first
+#include "dspbios-osal.h"
+
+#include "pte_generic_osal.h"
+
+
+
+#endif // _OS_SUPPORT_H

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1322 - 0
platform/dspbios/pte_test/Configuration1.cdb


+ 47 - 0
platform/dspbios/pte_test/Configuration1.tcf

@@ -0,0 +1,47 @@
+utils.loadPlatform("ti.platforms.dsk6416");
+
+/* The following DSP/BIOS Features are enabled.  */
+bios.enableMemoryHeaps(prog);
+bios.enableRealTimeAnalysis(prog);
+bios.enableRtdx(prog);
+bios.enableTskManager(prog);
+
+bios.MEM.NOMEMORYHEAPS = 0;
+bios.MEM.instance("SDRAM").createHeap = 1;
+bios.MEM.BIOSOBJSEG = prog.get("SDRAM");
+bios.MEM.MALLOCSEG = prog.get("SDRAM");
+bios.MEM.instance("IRAM").createHeap = 1;
+bios.MEM.BIOSOBJSEG = prog.get("IRAM");
+bios.MEM.MALLOCSEG = prog.get("IRAM");
+bios.TSK.STACKSEG = prog.get("IRAM");
+bios.CLK.CONFIGURETIMER = 1;
+bios.CLK.CONFIGURETIMER = 1;
+bios.CLK.HIRESTIME = 1;
+bios.CLK.HIRESTIME = 1;
+bios.CLK.CONFIGURETIMER = 0;
+bios.CLK.TIMERSELECT = "Timer 1";
+bios.CLK.CONFIGURETIMER = 1;
+bios.CLK.TIMERSELECT = "Timer 0";
+bios.CLK.CONFIGURETIMER = 0;
+bios.CLK.HIRESTIME = 0;
+bios.CLK.TIMERSELECT = "Timer 1";
+bios.CLK.HIRESTIME = 1;
+bios.CLK.TIMERSELECT = "Timer 0";
+bios.RTDX.MODE = "Simulator";
+bios.CLK.HIRESTIME = 0;
+bios.CLK.MICROSECONDS = 1.0000;
+bios.CLK.MICROSECONDS = 10.0000;
+bios.MEM.instance("IRAM").heapSize = 0x00080000;
+bios.CLK.MICROSECONDS = 1.0000;
+bios.CLK.MICROSECONDS = 10.0000;
+bios.CLK.TIMERSELECT = "Timer 0";
+bios.CLK.HIRESTIME = 1;
+bios.CLK.MICROSECONDS = 100.0000;
+bios.CLK.MICROSECONDS = 10.0000;
+bios.GBL.SPECIFYRTSLIB = 1;
+bios.GBL.RTSLIB = "rts6400_eh";
+bios.GBL.RTSLIB = "rts6400_eh.lib";
+// !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
+
+prog.gen();
+

+ 6 - 0
platform/dspbios/pte_test/Configuration1.tco

@@ -0,0 +1,6 @@
+# GENERATED FILE -- DO NOT EDIT!
+# This file contains tconf options for file "Configuration1.tcf",
+# for use by the Gconf graphical configuration tool.
+# The options are exported from the following CCS project: 
+# Z:\PTHREAD\PLATFORM\DSPBIOS\PTE_TEST\pte_test.pjt, "C" configuration.
+-Dconfig.importPath="C:\CCStudio_v3.3/bios_5_31_02/packages;"

+ 185 - 0
platform/dspbios/pte_test/pte_test.pjt

@@ -0,0 +1,185 @@
+; Code Composer Project File, Version 2.0 (do not modify or remove this line)
+
+[Project Settings]
+ProjectDir="Z:\pthread\platform\dspbios\pte_test\"
+ProjectType=Executable
+CPUFamily=TMS320C64XX
+Tool="Compiler"
+Tool="CustomBuilder"
+Tool="DspBiosBuilder"
+Tool="Linker"
+Config="C"
+Config="CPP"
+
+[Source Files]
+Source="..\..\..\tests\barrier1.c"
+Source="..\..\..\tests\barrier2.c"
+Source="..\..\..\tests\barrier3.c"
+Source="..\..\..\tests\barrier4.c"
+Source="..\..\..\tests\barrier5.c"
+Source="..\..\..\tests\benchlib.c"
+Source="..\..\..\tests\benchtest1.c"
+Source="..\..\..\tests\benchtest2.c"
+Source="..\..\..\tests\benchtest3.c"
+Source="..\..\..\tests\benchtest4.c"
+Source="..\..\..\tests\cancel1.c"
+Source="..\..\..\tests\cancel2.c"
+Source="..\..\..\tests\cancel3.c"
+Source="..\..\..\tests\cancel4.c"
+Source="..\..\..\tests\cancel5.c"
+Source="..\..\..\tests\cancel6a.c"
+Source="..\..\..\tests\cancel6d.c"
+Source="..\..\..\tests\cleanup0.c"
+Source="..\..\..\tests\cleanup1.c"
+Source="..\..\..\tests\cleanup2.c"
+Source="..\..\..\tests\cleanup3.c"
+Source="..\..\..\tests\condvar1.c"
+Source="..\..\..\tests\condvar1_1.c"
+Source="..\..\..\tests\condvar1_2.c"
+Source="..\..\..\tests\condvar2.c"
+Source="..\..\..\tests\condvar2_1.c"
+Source="..\..\..\tests\condvar3.c"
+Source="..\..\..\tests\condvar3_1.c"
+Source="..\..\..\tests\condvar3_2.c"
+Source="..\..\..\tests\condvar3_3.c"
+Source="..\..\..\tests\condvar4.c"
+Source="..\..\..\tests\condvar5.c"
+Source="..\..\..\tests\condvar6.c"
+Source="..\..\..\tests\condvar7.c"
+Source="..\..\..\tests\condvar8.c"
+Source="..\..\..\tests\condvar9.c"
+Source="..\..\..\tests\count1.c"
+Source="..\..\..\tests\create1.c"
+Source="..\..\..\tests\create2.c"
+Source="..\..\..\tests\create3.c"
+Source="..\..\..\tests\delay1.c"
+Source="..\..\..\tests\delay2.c"
+Source="..\..\..\tests\detach1.c"
+Source="..\..\..\tests\equal1.c"
+Source="..\..\..\tests\errno1.c"
+Source="..\..\..\tests\exception1.c"
+Source="..\..\..\tests\exception2.c"
+Source="..\..\..\tests\exception3.c"
+Source="..\..\..\tests\exit1.c"
+Source="..\..\..\tests\exit2.c"
+Source="..\..\..\tests\exit3.c"
+Source="..\..\..\tests\exit4.c"
+Source="..\..\..\tests\exit5.c"
+Source="..\..\..\tests\inherit1.c"
+Source="..\..\..\tests\join0.c"
+Source="..\..\..\tests\join1.c"
+Source="..\..\..\tests\join2.c"
+Source="..\..\..\tests\join3.c"
+Source="..\..\..\tests\kill1.c"
+Source="..\..\..\tests\mutex1.c"
+Source="..\..\..\tests\mutex1e.c"
+Source="..\..\..\tests\mutex1n.c"
+Source="..\..\..\tests\mutex1r.c"
+Source="..\..\..\tests\mutex2.c"
+Source="..\..\..\tests\mutex2e.c"
+Source="..\..\..\tests\mutex2r.c"
+Source="..\..\..\tests\mutex3.c"
+Source="..\..\..\tests\mutex3e.c"
+Source="..\..\..\tests\mutex3r.c"
+Source="..\..\..\tests\mutex4.c"
+Source="..\..\..\tests\mutex5.c"
+Source="..\..\..\tests\mutex6.c"
+Source="..\..\..\tests\mutex6e.c"
+Source="..\..\..\tests\mutex6es.c"
+Source="..\..\..\tests\mutex6n.c"
+Source="..\..\..\tests\mutex6r.c"
+Source="..\..\..\tests\mutex6rs.c"
+Source="..\..\..\tests\mutex6s.c"
+Source="..\..\..\tests\mutex7.c"
+Source="..\..\..\tests\mutex7e.c"
+Source="..\..\..\tests\mutex7n.c"
+Source="..\..\..\tests\mutex7r.c"
+Source="..\..\..\tests\mutex8.c"
+Source="..\..\..\tests\mutex8e.c"
+Source="..\..\..\tests\mutex8n.c"
+Source="..\..\..\tests\mutex8r.c"
+Source="..\..\..\tests\once1.c"
+Source="..\..\..\tests\once2.c"
+Source="..\..\..\tests\once3.c"
+Source="..\..\..\tests\once4.c"
+Source="..\..\..\tests\priority1.c"
+Source="..\..\..\tests\priority2.c"
+Source="..\..\..\tests\reuse1.c"
+Source="..\..\..\tests\reuse2.c"
+Source="..\..\..\tests\rwlock1.c"
+Source="..\..\..\tests\rwlock2.c"
+Source="..\..\..\tests\rwlock2_t.c"
+Source="..\..\..\tests\rwlock3.c"
+Source="..\..\..\tests\rwlock3_t.c"
+Source="..\..\..\tests\rwlock4.c"
+Source="..\..\..\tests\rwlock4_t.c"
+Source="..\..\..\tests\rwlock5.c"
+Source="..\..\..\tests\rwlock5_t.c"
+Source="..\..\..\tests\rwlock6.c"
+Source="..\..\..\tests\rwlock6_t.c"
+Source="..\..\..\tests\rwlock6_t2.c"
+Source="..\..\..\tests\rwlock7.c"
+Source="..\..\..\tests\rwlock8.c"
+Source="..\..\..\tests\self1.c"
+Source="..\..\..\tests\self2.c"
+Source="..\..\..\tests\semaphore1.c"
+Source="..\..\..\tests\semaphore2.c"
+Source="..\..\..\tests\semaphore3.c"
+Source="..\..\..\tests\semaphore4.c"
+Source="..\..\..\tests\semaphore4t.c"
+Source="..\..\..\tests\spin1.c"
+Source="..\..\..\tests\spin2.c"
+Source="..\..\..\tests\spin3.c"
+Source="..\..\..\tests\spin4.c"
+Source="..\..\..\tests\stress1.c"
+Source="..\..\..\tests\test_main.c"
+Source="..\..\..\tests\tsd1.c"
+Source="..\..\..\tests\tsd2.c"
+Source="..\..\..\tests\valid1.c"
+Source="..\..\..\tests\valid2.c"
+Source="..\..\helper\tls-helper.c"
+Source="..\dspbios-osal.c"
+Source="..\main.c"
+Source="Configuration1.tcf"
+Source="Configuration1cfg.cmd"
+
+[Generated Files]
+Source="Configuration1cfg.s62"
+Source="Configuration1cfg_c.c"
+
+["Compiler" Settings: "C"]
+Options=-g -fr"$(Proj_dir)\C" -i"..\platform\dspbios" -i".." -i"..\.." -i"." -i"..\dspbios" -i"..\helper" -d"_DEBUG" -mv6400
+
+["Compiler" Settings: "CPP"]
+Options=-g -fg -fr"$(Proj_dir)\CPP" -i"..\platform\dspbios" -i".." -i"..\.." -i"." -i"..\dspbios" -i"..\helper" -d"_DEBUG" -mv6400 --exceptions
+
+["DspBiosBuilder" Settings: "C"]
+Options=-Dconfig.importPath="$(Install_dir)/bios_5_31_02/packages;"
+
+["DspBiosBuilder" Settings: "CPP"]
+Options=-Dconfig.importPath="$(Install_dir)/bios_5_31_02/packages;"
+
+["Linker" Settings: "C"]
+Options=-c -m".\C\pte_test.map" -o".\C\pte_test.out" -w -x -i"..\pte_lib\C" -l"pte_lib.lib"
+
+["Linker" Settings: "CPP"]
+Options=-c -m".\CPP\pte_test.map" -o".\CPP\pte_test.out" -w -x -i"..\pte_lib\CPP" -l"pte_lib.lib"
+
+["..\..\..\tests\exception2.c" Settings: "CPP"]
+Options="Compiler" +{-fg --exceptions}
+
+["..\..\..\tests\exception3.c" Settings: "CPP"]
+Options="Compiler" +{-fg --exceptions}
+
+["..\..\..\tests\test_main.c" Settings: "CPP"]
+Options="Compiler" +{-fg}
+
+["..\main.c" Settings: "CPP"]
+Options="Compiler" +{-fg}
+
+["Configuration1cfg.cmd" Settings: "C"]
+LinkOrder=1
+
+["Configuration1cfg.cmd" Settings: "CPP"]
+LinkOrder=1
+

+ 185 - 0
platform/helper/tls-helper.c

@@ -0,0 +1,185 @@
+/*
+ * tls-helper.c
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 <stdio.h>
+#include <stdlib.h>
+
+#include "tls-helper.h"
+
+static int *keysUsed;
+
+/* We don't protect this - it's only written on startup */
+static int maxTlsValues;
+
+pte_osMutexHandle globalTlsLock;
+
+pte_osResult pteTlsGlobalInit(int maxEntries)
+{
+  int i;
+  pte_osResult result;
+
+  pte_osMutexCreate(&globalTlsLock);
+
+  keysUsed = (int *) malloc(maxEntries * sizeof(int));
+
+  if (keysUsed != NULL)
+    {
+      for (i=0;i<maxEntries;i++)
+        {
+          keysUsed[i] = 0;
+        }
+
+      maxTlsValues = maxEntries;
+
+      result = PTE_OS_OK;
+    }
+  else
+    {
+      result = PTE_OS_NO_RESOURCES;
+    }
+
+  return result;
+}
+
+
+void * pteTlsThreadInit(void)
+{
+  void ** pTlsStruct;
+  int i;
+
+  pTlsStruct = (void **) malloc(maxTlsValues * sizeof(void*));
+
+  // PTE library assumes that keys are initialized to zero
+  for (i=0; i<maxTlsValues;i++)
+    {
+      pTlsStruct[i] = 0;
+    }
+
+  return (void *) pTlsStruct;
+}
+
+
+pte_osResult pteTlsAlloc(unsigned int *pKey)
+{
+  int i;
+  pte_osResult result = PTE_OS_NO_RESOURCES;
+
+  
+  pte_osMutexLock(globalTlsLock);
+
+  for (i=0;i<maxTlsValues;i++)
+    {
+      if (keysUsed[i] == 0)
+        {
+          keysUsed[i] = 1;
+
+          *pKey = i+1;
+          result = PTE_OS_OK;
+          break;
+        }
+    }
+
+  pte_osMutexUnlock(globalTlsLock);
+
+  return result;
+}
+
+
+void * pteTlsGetValue(void *pTlsThreadStruct, unsigned int index)
+{
+  void **pTls = (void **) pTlsThreadStruct;
+
+  if (keysUsed[index-1])
+    {
+      if (pTls != NULL)
+        {
+          return pTls[index-1];
+        }
+      else
+        {
+          return NULL;
+        }
+    }
+  else
+    {
+      return NULL;
+    }
+}
+
+
+pte_osResult pteTlsSetValue(void *pTlsThreadStruct, unsigned int index, void * value)
+{
+  pte_osResult result;
+  void ** pTls = (void **) pTlsThreadStruct;
+
+  if (pTls != NULL)
+    {
+      pTls[index-1] = value;
+      result = PTE_OS_OK;
+    }
+  else
+    {
+      result = PTE_OS_INVALID_PARAM;
+    }
+
+  return result;
+
+}
+
+pte_osResult pteTlsFree(unsigned int index)
+{
+  pte_osResult result;
+
+  if (keysUsed != NULL)
+    {
+      pte_osMutexLock(globalTlsLock);
+
+      keysUsed[index-1] = 0;
+
+      pte_osMutexUnlock(globalTlsLock);
+
+      result = PTE_OS_OK;
+    }
+  else
+    {
+      result = PTE_OS_GENERAL_FAILURE;
+    }
+
+  return result;
+}
+
+void pteTlsThreadDestroy(void * pTlsThreadStruct)
+{
+  free(pTlsThreadStruct);
+}
+
+void pteTlsGlobalDestroy(void)
+{
+  pte_osMutexDelete(globalTlsLock);
+  free(keysUsed);
+}

+ 47 - 0
platform/helper/tls-helper.h

@@ -0,0 +1,47 @@
+/*
+ * tls-helper.h
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 _TLS_HELPER_H_
+#define _TLS_HELPER_H_
+
+#include "pte_osal.h"
+
+/// @todo document..
+
+pte_osResult pteTlsGlobalInit(int maxEntries);
+void * pteTlsThreadInit(void);
+
+pte_osResult pteTlsAlloc(unsigned int *pKey);
+void * pteTlsGetValue(void *pTlsThreadStruct, unsigned int index);
+pte_osResult pteTlsSetValue(void *pTlsThreadStruct, unsigned int index, void * value);
+pte_osResult pteTlsFree(unsigned int index);
+
+void pteTlsThreadDestroy(void * pTlsThreadStruct);
+void pteTlsGlobalDestroy(void);
+
+#endif // _TLS_HELPER_H_

+ 194 - 0
platform/psp/Makefile

@@ -0,0 +1,194 @@
+
+CLEANUP_TYPE=C
+#CLEANUP_TYPE=CPP
+
+VPATH = ../..:../helper
+
+TARGET_LIB = libpthread-psp.a
+
+
+MUTEX_OBJS = \
+  pthread_mutex_unlock.o \
+  pthread_mutex_init.o \
+  pthread_mutex_destroy.o \
+  pthread_mutex_lock.o \
+  pthread_mutex_timedlock.o \
+  pthread_mutex_trylock.o 
+
+MUTEXATTR_OBJS = \
+  pthread_mutexattr_destroy.o \
+  pthread_mutexattr_getkind_np.o \
+  pthread_mutexattr_getpshared.o \
+  pthread_mutexattr_gettype.o \
+  pthread_mutexattr_init.o \
+  pthread_mutexattr_setkind_np.o \
+  pthread_mutexattr_setpshared.o \
+  pthread_mutexattr_settype.o
+
+SUPPORT_OBJS = \
+  pte_relmillisecs.o \
+  pte_mutex_check_need_init.o \
+  pte_threadDestroy.o \
+  pte_new.o \
+  pte_threadStart.o \
+  global.o \
+  pte_reuse.o \
+  pthread_init.o \
+  pthread_terminate.o
+
+THREAD_OBJS = \
+  create.o \
+  pthread_self.o \
+  pthread_equal.o \
+  pthread_join.o \
+  pthread_detach.o \
+  pte_detach.o \
+  pte_callUserDestroyRoutines.o \
+  pte_tkAssocDestroy.o \
+  pthread_kill.o \
+  pthread_attr_destroy.o \
+  pthread_attr_getdetachstate.o \
+  pthread_attr_getinheritsched.o \
+  pthread_attr_getschedparam.o \
+  pthread_attr_getschedpolicy.o \
+  pthread_attr_getscope.o \
+  pthread_attr_getstackaddr.o \
+  pthread_attr_getstacksize.o \
+  pthread_attr_init.o \
+  pthread_attr_setdetachstate.o \
+  pthread_attr_setinheritsched.o \
+  pthread_attr_setschedparam.o \
+  pthread_attr_setschedpolicy.o \
+  pthread_attr_setscope.o \
+  pthread_attr_setstackaddr.o \
+  pthread_attr_setstacksize.o \
+  pte_is_attr.o \
+  pthread_exit.o \
+  pthread_getschedparam.o \
+  pthread_setschedparam.o \
+  sched_get_priority_max.o \
+  sched_get_priority_min.o
+
+
+TLS_OBJS = \
+  pthread_key_create.o \
+  pthread_key_delete.o \
+  pthread_getspecific.o \
+  pthread_setspecific.o \
+  pte_tkAssocCreate.o
+
+MISC_OBJS = \
+  sched_yield.o \
+  pthread_delay_np.o \
+  pthread_testcancel.o \
+  pte_throw.o \
+  cleanup.o \
+  pthread_once.o \
+  pthread_num_processors_np.o \
+  pte_getprocessors.o \
+  pte_spinlock_check_need_init.o \
+  global.o \
+  pthread_timechange_handler_np.o \
+  pte_cond_check_need_init.o \
+	pthread_getconcurrency.o \
+	pthread_setconcurrency.o \
+  pte_cancellable_wait.o
+
+SEM_OBJS = \
+  sem_close.o \
+  sem_destroy.o \
+  sem_getvalue.o \
+  sem_init.o \
+  sem_open.o  \
+  sem_post.o \
+  sem_post_multiple.o \
+  sem_timedwait.o \
+  sem_trywait.o \
+  sem_unlink.o \
+  sem_wait.o
+
+BARRIER_OBJS = \
+  pthread_barrier_init.o \
+  pthread_barrier_destroy.o \
+  pthread_barrier_wait.o \
+  pthread_barrierattr_init.o \
+  pthread_barrierattr_destroy.o \
+  pthread_barrierattr_getpshared.o \
+  pthread_barrierattr_setpshared.o \
+  
+SPIN_OBJS = \
+  pthread_spin_destroy.o \
+  pthread_spin_init.o \
+  pthread_spin_lock.o \
+  pthread_spin_trylock.o \
+  pthread_spin_unlock.o
+
+CONDVAR_OBJS = \
+  pthread_cond_destroy.o \
+  pthread_cond_init.o \
+  pthread_cond_signal.o \
+  pthread_cond_wait.o \
+  pthread_condattr_destroy.o \
+  pthread_condattr_getpshared.o \
+  pthread_condattr_init.o \
+  pthread_condattr_setpshared.o
+
+RWLOCK_OBJS = \
+  pthread_rwlock_init.o \
+  pthread_rwlock_destroy.o \
+  pthread_rwlock_rdlock.o \
+  pthread_rwlock_timedrdlock.o \
+  pthread_rwlock_timedwrlock.o \
+  pthread_rwlock_tryrdlock.o \
+  pthread_rwlock_trywrlock.o \
+  pthread_rwlock_unlock.o \
+  pthread_rwlock_wrlock.o \
+  pthread_rwlockattr_init.o \
+  pthread_rwlockattr_destroy.o \
+  pthread_rwlockattr_getpshared.o \
+  pthread_rwlockattr_setpshared.o \
+  pte_rwlock_check_need_init.o \
+  pte_rwlock_cancelwrwait.o 
+
+CANCEL_OBJS = \
+  pthread_cancel.o \
+  pthread_setcanceltype.o \
+  pthread_setcancelstate.o
+
+OS_OBJS = \
+  psp_osal.o \
+  tls-helper.o
+
+OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS)
+
+INCDIR = 
+CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -Werror -I../.. -I../helper 
+CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX
+ASFLAGS = $(CFLAGS)
+
+LDFLAGS = 
+LIBS = 
+
+PSPSDK=$(shell psp-config --pspsdk-path)
+include $(PSPSDK)/lib/build.mak
+
+
+ifeq ($(CLEANUP_TYPE),CPPXX)
+
+CC=psp-g++
+
+pte_throw.o: pte_throw.c
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \
+	  -c ../../pte_throw.c -o pte_throw.o
+
+pte_threadStart.o: pte_threadStart.c
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \
+	  -c ../../pte_threadStart.c -o pte_threadStart.o
+
+endif
+
+install: $(TARGET_LIB)
+	@cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib
+	@cp -v *.h `psp-config --psp-prefix`/include
+	@echo "Done."
+

+ 212 - 0
platform/psp/Makefile.tests

@@ -0,0 +1,212 @@
+
+CLEANUP_TYPE=C
+#CLEANUP_TYPE=CPP
+
+VPATH = ../../tests
+
+TARGET = pthread-psp-test
+
+MUTEX_TEST_OBJS = \
+  mutex1.o \
+  mutex1e.o \
+  mutex1n.o \
+  mutex1r.o \
+  mutex2.o \
+  mutex2e.o \
+  mutex2r.o \
+  mutex3.o \
+  mutex3e.o \
+  mutex3r.o \
+  mutex4.o \
+  mutex5.o \
+  mutex6.o \
+  mutex6e.o \
+  mutex6es.o \
+  mutex6n.o \
+  mutex6r.o \
+  mutex6rs.o \
+  mutex6s.o \
+  mutex7.o \
+  mutex7e.o \
+  mutex7n.o \
+  mutex7r.o \
+  mutex8.o \
+  mutex8e.o \
+  mutex8n.o \
+  mutex8r.o
+
+MISC_OBJS = \
+  main.o \
+  test_main.o
+
+
+MISC_TEST_OBJS = \
+  valid1.o \
+  valid2.o \
+  self1.o \
+  self2.o \
+  equal1.o \
+  count1.o \
+  delay1.o \
+  delay2.o \
+  errno1.o \
+  tsd1.o \
+  tsd2.o \
+  stress1.o \
+  detach1.o
+
+SEM_TEST_OBJS = \
+  semaphore1.o \
+  semaphore2.o \
+  semaphore3.o \
+  semaphore4.o \
+  semaphore4t.o \
+  semaphore5.o \
+  semaphore6.o
+
+BARRIER_TEST_OBJS = \
+  barrier1.o \
+  barrier2.o \
+  barrier3.o \
+  barrier4.o \
+  barrier5.o 
+
+# Tests excluded because cancellation is not implemented
+#  semaphore4.o 
+#  semaphore4t.o 
+
+THREAD_TEST_OBJS = \
+  create1.o \
+  create2.o \
+  create3.o \
+  join0.o \
+  join1.o \
+  join2.o \
+  join3.o \
+  join4.o \
+  kill1.o \
+  once1.o \
+  once2.o \
+  once3.o \
+  once4.o \
+  exit1.o \
+  exit2.o \
+  exit3.o \
+  exit4.o \
+  exit5.o \
+  reuse1.o \
+  reuse2.o \
+  priority1.o \
+  priority2.o \
+  inherit1.o
+
+
+SPIN_TEST_OBJS = \
+  spin1.o \
+  spin2.o \
+  spin3.o \
+  spin4.o
+
+CONDVAR_TEST_OBJS = \
+  condvar1.o \
+  condvar1_1.o \
+  condvar1_2.o \
+  condvar2.o \
+  condvar2_1.o \
+  condvar3.o \
+  condvar3_1.o \
+  condvar3_2.o \
+  condvar3_3.o \
+  condvar4.o \
+  condvar5.o \
+  condvar6.o \
+  condvar8.o \
+  condvar7.o \
+  condvar9.o 
+
+RWLOCK_TEST_OBJS = \
+  rwlock1.o \
+  rwlock2.o \
+  rwlock2_t.o \
+  rwlock3.o \
+  rwlock3_t.o \
+  rwlock4.o \
+  rwlock4_t.o \
+  rwlock5.o \
+  rwlock5_t.o \
+  rwlock6.o \
+  rwlock6_t.o \
+  rwlock6_t2.o \
+  rwlock7.o \
+  rwlock8.o
+
+CANCEL_TEST_OBJS = \
+  cancel1.o \
+  cancel2.o \
+  cancel3.o \
+  cancel4.o \
+  cancel5.o \
+  cancel6a.o \
+  cancel6d.o \
+  cleanup0.o \
+  cleanup1.o \
+  cleanup2.o \
+  cleanup3.o
+
+BENCH_TEST_OBJS = \
+  benchlib.o \
+  benchtest1.o \
+  benchtest2.o \
+  benchtest3.o \
+  benchtest4.o 
+
+EXCEPTION_TEST_OBJS = \
+  exception1.o \
+  exception2.o \
+  exception3.o
+
+
+
+OBJS = $(MUTEX_TEST_OBJS) $(MISC_OBJS) $(MISC_TEST_OBJS) $(THREAD_TEST_OBJS) $(SEM_TEST_OBJS) $(BARRIER_TEST_OBJS) $(SPIN_TEST_OBJS) $(CONDVAR_TEST_OBJS) $(RWLOCK_TEST_OBJS) $(CANCEL_TEST_OBJS) $(BENCH_TEST_OBJS) $(EXCEPTION_TEST_OBJS)
+
+
+INCDIR = 
+CFLAGS = $(GLOBAL_CFLAGS) -O2 -Wall -g -I..  -fno-strict-aliasing  -I../.. -G0
+CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti
+ASFLAGS = $(CFLAGS)
+
+LDFLAGS = -L../..
+LIBS = -lc -lpthread-psp -lstdc++
+
+ifeq ($(CLEANUP_TYPE),CPPXX)
+
+LIBS += -lstdc++
+
+endif
+
+PSPSDK=$(shell psp-config --pspsdk-path)
+include $(PSPSDK)/lib/build.mak
+
+ifeq ($(CLEANUP_TYPE),CPPXXX)
+
+CC=psp-g++
+
+exception1.o: exception1.c
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \
+	  -c ../../tests/exception1.c -o exception1.o
+
+exception2.o: exception2.c
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \
+	  -c ../../tests/exception2.c -o exception2.o
+
+exception3.o: exception3.c
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \
+	  -c ../../tests/exception3.c -o exception3.o
+endif
+
+
+install: $(TARGET_LIB)
+	@cp -v $(TARGET_LIB) `psp-config --psp-prefix`/lib
+	@cp -v *.h `psp-config --psp-prefix`/include
+	@echo "Done."
+

+ 76 - 0
platform/psp/main.c

@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pspkernel.h>
+#include <pspdebug.h>
+#include <pspsdk.h>
+#include <pspctrl.h>
+
+
+PSP_MODULE_INFO("Pthread Test", 0, 1, 1);
+
+extern void pte_test_main();
+
+#ifdef JNS
+#define printf pspDebugScreenPrintf
+#endif
+
+/* Exit callback */
+int exit_callback(int arg1, int arg2, void *common)
+{
+  sceKernelExitGame();
+  return 0;
+}
+
+/* Callback thread */
+int CallbackThread(SceSize args, void *argp)
+{
+
+  int cbid;
+
+  cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
+  sceKernelRegisterExitCallback(cbid);
+
+  sceKernelSleepThreadCB();
+
+  return 0;
+}
+
+/* Sets up the callback thread and returns its thread id */
+int SetupCallbacks(void)
+{
+  int thid = 0;
+
+  thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
+  if (thid >= 0)
+    {
+      sceKernelStartThread(thid, 0, 0);
+    }
+
+  return thid;
+}
+
+
+
+int main()
+{
+  SceCtrlData pad;
+
+  pspDebugScreenInit();
+  SetupCallbacks();
+
+  pte_test_main();
+
+  while (1)
+    {
+      sceCtrlReadBufferPositive(&pad, 1);
+      if (pad.Buttons & PSP_CTRL_UP)
+        {
+          printf("Exiting...\n");
+          return 0;
+        }
+
+    }
+  return 0;
+}
+
+

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
platform/psp/psp_osal.c


+ 66 - 0
platform/psp/psp_osal.h

@@ -0,0 +1,66 @@
+/*
+ * psp_osal.h
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 <pspsdk.h>
+
+typedef SceUID pte_osThreadHandle;
+
+typedef SceUID pte_osSemaphoreHandle;
+
+typedef SceUID pte_osMutexHandle;
+
+
+#define OS_IS_HANDLE_VALID(x) ((x) > 0)
+
+
+
+
+#define OS_MAX_SIMUL_THREADS 10
+
+#define OS_DEFAULT_PRIO 11
+
+#define OS_MIN_PRIO 17
+#define OS_MAX_PRIO 32
+
+//#define HAVE_THREAD_SAFE_ERRNO
+
+#define POLLING_DELAY_IN_us 100
+
+
+
+#define OS_MAX_SEM_VALUE 254
+
+int PspInterlockedExchange(int *ptarg, int val);
+int PspInterlockedCompareExchange(int *pdest, int exchange, int comp);
+int  PspInterlockedExchangeAdd(int volatile* pAddend, int value);
+int PspInterlockedDecrement(int *pdest);
+int PspInterlockedIncrement(int *pdest);
+
+
+
+

+ 34 - 0
platform/psp/pte-config.h

@@ -0,0 +1,34 @@
+/* config.h  */
+
+#ifndef PTE_CONFIG_H
+#define PTE_CONFIG_H
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+
+#define PTE_STATIC_LIB
+
+/*********************************************************************
+ * Defaults: see target specific redefinitions below.
+ *********************************************************************/
+
+/* We're building the pthreads-win32 library */
+#define PTE_BUILD
+
+typedef int pid_t;
+
+/* Define if you don't have Win32 errno. (eg. WinCE) */
+//#undef NEED_ERRNO
+
+/* Do we know about type mode_t? */
+//#undef HAVE_MODE_T
+
+//#undef HAVE_TIMEB
+//#define HAVE_TIMEB
+
+/* Define if you have the timespec struct */
+//#undef HAVE_STRUCT_TIMESPEC
+//#define HAVE_STRUCT_TIMESPEC
+
+#endif

+ 12 - 0
platform/psp/pte_osal.h

@@ -0,0 +1,12 @@
+
+#ifndef _OS_SUPPORT_H_
+#define _OS_SUPPORT_H_
+
+// Platform specific one must be included first
+#include "psp_osal.h"
+
+#include "pte_generic_osal.h"
+
+
+
+#endif // _OS_SUPPORT_H

+ 229 - 0
pte_callUserDestroyRoutines.c

@@ -0,0 +1,229 @@
+/*
+ * pte_callUserDestroyRoutines.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+#include <pte_osal.h>
+
+#ifdef __cplusplus
+#include <exception>
+using std::terminate;
+#endif
+
+void
+pte_callUserDestroyRoutines (pthread_t thread)
+/*
+ * -------------------------------------------------------------------
+ * DOCPRIVATE
+ *
+ * This the routine runs through all thread keys and calls
+ * the destroy routines on the user's data for the current thread.
+ * It simulates the behaviour of POSIX Threads.
+ *
+ * PARAMETERS
+ *              thread
+ *                      an instance of pthread_t
+ *
+ * RETURNS
+ *              N/A
+ * -------------------------------------------------------------------
+ */
+{
+  ThreadKeyAssoc * assoc;
+
+  if (thread.p != NULL)
+    {
+      int assocsRemaining;
+      int iterations = 0;
+      pte_thread_t * sp = (pte_thread_t *) thread.p;
+
+      /*
+       * Run through all Thread<-->Key associations
+       * for the current thread.
+       *
+       * Do this process at most PTHREAD_DESTRUCTOR_ITERATIONS times.
+       */
+      do
+        {
+          assocsRemaining = 0;
+          iterations++;
+
+          (void) pthread_mutex_lock(&(sp->threadLock));
+          /*
+           * The pointer to the next assoc is stored in the thread struct so that
+           * the assoc destructor in pthread_key_delete can adjust it
+           * if it deletes this assoc. This can happen if we fail to acquire
+           * both locks below, and are forced to release all of our locks,
+           * leaving open the opportunity for pthread_key_delete to get in
+           * before us.
+           */
+          sp->nextAssoc = sp->keys;
+          (void) pthread_mutex_unlock(&(sp->threadLock));
+
+          for (;;)
+            {
+              void * value;
+              pthread_key_t k;
+              void (*destructor) (void *);
+
+              /*
+               * First we need to serialise with pthread_key_delete by locking
+               * both assoc guards, but in the reverse order to our convention,
+               * so we must be careful to avoid deadlock.
+               */
+              (void) pthread_mutex_lock(&(sp->threadLock));
+
+              if ((assoc = (ThreadKeyAssoc *)sp->nextAssoc) == NULL)
+                {
+                  /* Finished */
+                  pthread_mutex_unlock(&(sp->threadLock));
+                  break;
+                }
+              else
+                {
+                  /*
+                   * assoc->key must be valid because assoc can't change or be
+                   * removed from our chain while we hold at least one lock. If
+                   * the assoc was on our key chain then the key has not been
+                   * deleted yet.
+                   *
+                   * Now try to acquire the second lock without deadlocking.
+                   * If we fail, we need to relinquish the first lock and the
+                   * processor and then try to acquire them all again.
+                   */
+                  if (pthread_mutex_trylock(&(assoc->key->keyLock)) == EBUSY)
+                    {
+                      pthread_mutex_unlock(&(sp->threadLock));
+                      pte_osThreadSleep(1); // Ugly but necessary to avoid priority effects.
+                      /*
+                       * Go around again.
+                       * If pthread_key_delete has removed this assoc in the meantime,
+                       * sp->nextAssoc will point to a new assoc.
+                       */
+                      continue;
+                    }
+                }
+
+              /* We now hold both locks */
+
+              sp->nextAssoc = assoc->nextKey;
+
+              /*
+               * Key still active; pthread_key_delete
+               * will block on these same mutexes before
+               * it can release actual key; therefore,
+               * key is valid and we can call the destroy
+               * routine;
+               */
+              k = assoc->key;
+              destructor = k->destructor;
+              value = pte_osTlsGetValue(k->key);
+              pte_osTlsSetValue (k->key, NULL);
+
+              // Every assoc->key exists and has a destructor
+              if (value != NULL && iterations <= PTHREAD_DESTRUCTOR_ITERATIONS)
+                {
+                  /*
+                   * Unlock both locks before the destructor runs.
+                   * POSIX says pthread_key_delete can be run from destructors,
+                   * and that probably includes with this key as target.
+                   * pthread_setspecific can also be run from destructors and
+                   * also needs to be able to access the assocs.
+                   */
+                  (void) pthread_mutex_unlock(&(sp->threadLock));
+                  (void) pthread_mutex_unlock(&(k->keyLock));
+
+                  assocsRemaining++;
+
+#ifdef __cplusplus
+
+                  try
+                    {
+                      /*
+                       * Run the caller's cleanup routine.
+                       */
+                      destructor (value);
+                    }
+                  catch (...)
+                    {
+                      /*
+                       * A system unexpected exception has occurred
+                       * running the user's destructor.
+                       * We get control back within this block in case
+                       * the application has set up it's own terminate
+                       * handler. Since we are leaving the thread we
+                       * should not get any internal pthreads
+                       * exceptions.
+                       */
+                      terminate ();
+                    }
+
+#else /* __cplusplus */
+
+                  /*
+                  * Run the caller's cleanup routine.
+                  */
+                  destructor (value);
+
+#endif /* __cplusplus */
+
+                }
+              else
+                {
+                  /*
+                   * Remove association from both the key and thread chains
+                   * and reclaim it's memory resources.
+                   */
+                  pte_tkAssocDestroy (assoc);
+                  (void) pthread_mutex_unlock(&(sp->threadLock));
+                  (void) pthread_mutex_unlock(&(k->keyLock));
+                }
+            }
+        }
+      while (assocsRemaining);
+    }
+}				/* pte_callUserDestroyRoutines */

+ 130 - 0
pte_cancellable_wait.c

@@ -0,0 +1,130 @@
+/*
+ * pte_cancellable_wait.c
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+
+int pte_cancellable_wait (pte_osSemaphoreHandle semHandle, unsigned int* timeout)
+{
+  int result = EINVAL;
+  pte_osResult osResult;
+  int cancelEnabled = 0;
+  pthread_t self;
+  pte_thread_t * sp;
+
+  self = pthread_self();
+  sp = (pte_thread_t *) self.p;
+
+  if (sp != NULL)
+    {
+      /*
+       * Get cancelEvent handle
+       */
+      if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+        {
+          cancelEnabled = 1;
+        }
+    }
+
+
+  if (cancelEnabled)
+    {
+      osResult = pte_osSemaphoreCancellablePend(semHandle, timeout);
+    }
+  else
+    {
+      osResult = pte_osSemaphorePend(semHandle, timeout);
+    }
+
+  switch (osResult)
+    {
+    case PTE_OS_OK:
+    {
+      result = 0;
+      break;
+    }
+
+    case PTE_OS_TIMEOUT:
+    {
+      result = ETIMEDOUT;
+      break;
+    }
+
+    case PTE_OS_INTERRUPTED:
+    {
+      if (sp != NULL)
+        {
+          /*
+           * Should handle POSIX and implicit POSIX threads..
+           * Make sure we haven't been async-canceled in the meantime.
+           */
+          (void) pthread_mutex_lock (&sp->cancelLock);
+          if (sp->state < PThreadStateCanceling)
+            {
+              sp->state = PThreadStateCanceling;
+              sp->cancelState = PTHREAD_CANCEL_DISABLE;
+              (void) pthread_mutex_unlock (&sp->cancelLock);
+              pte_throw (PTE_EPS_CANCEL);
+
+              /* Never reached */
+            }
+          (void) pthread_mutex_unlock (&sp->cancelLock);
+        }
+      break;
+    }
+
+    default:
+    {
+      result = EINVAL;
+    }
+
+    }
+
+
+  return (result);
+
+}                               /* CancelableWait */
+

+ 103 - 0
pte_cond_check_need_init.c

@@ -0,0 +1,103 @@
+/*
+ * pte_cond_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pte_cond_check_need_init (pthread_cond_t * cond)
+{
+  int result = 0;
+
+  /*
+   * The following guarded test is specifically for statically
+   * initialised condition variables (via PTHREAD_OBJECT_INITIALIZER).
+   *
+   * Note that by not providing this synchronisation we risk
+   * introducing race conditions into applications which are
+   * correctly written.
+   *
+   * Approach
+   * --------
+   * We know that static condition variables will not be PROCESS_SHARED
+   * so we can serialise access to internal state using
+   * Win32 Critical Sections rather than Win32 Mutexes.
+   *
+   * If using a single global lock slows applications down too much,
+   * multiple global locks could be created and hashed on some random
+   * value associated with each mutex, the pointer perhaps. At a guess,
+   * a good value for the optimal number of global locks might be
+   * the number of processors + 1.
+   *
+   */
+
+
+  pte_osMutexLock (pte_cond_test_init_lock);
+
+  /*
+   * We got here possibly under race
+   * conditions. Check again inside the critical section.
+   * If a static cv has been destroyed, the application can
+   * re-initialise it only by calling pthread_cond_init()
+   * explicitly.
+   */
+  if (*cond == PTHREAD_COND_INITIALIZER)
+    {
+      result = pthread_cond_init (cond, NULL);
+    }
+  else if (*cond == NULL)
+    {
+      /*
+       * The cv has been destroyed while we were waiting to
+       * initialise it, so the operation that caused the
+       * auto-initialisation should fail.
+       */
+      result = EINVAL;
+    }
+
+
+  pte_osMutexUnlock(pte_cond_test_init_lock);
+
+  return result;
+}

+ 106 - 0
pte_detach.c

@@ -0,0 +1,106 @@
+/*
+ * pthread_win32_attach_detach_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static int
+pte_thread_detach_common (unsigned char threadShouldExit)
+{
+  if (pte_processInitialized)
+    {
+      /*
+       * Don't use pthread_self() - to avoid creating an implicit POSIX thread handle
+       * unnecessarily.
+       */
+      pte_thread_t * sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey);
+
+      if (sp != NULL) // otherwise OS thread with no implicit POSIX handle.
+        {
+
+          pte_callUserDestroyRoutines (sp->ptHandle);
+
+          (void) pthread_mutex_lock (&sp->cancelLock);
+          sp->state = PThreadStateLast;
+
+          /*
+           * If the thread is joinable at this point then it MUST be joined
+           * or detached explicitly by the application.
+           */
+          (void) pthread_mutex_unlock (&sp->cancelLock);
+
+          if (sp->detachState == PTHREAD_CREATE_DETACHED)
+            {
+              if (threadShouldExit)
+                {
+                  pte_threadExitAndDestroy (sp->ptHandle);
+                }
+              else
+                {
+                  pte_threadDestroy (sp->ptHandle);
+                }
+
+              // pte_osTlsSetValue (pte_selfThreadKey->key, NULL);
+            }
+          else
+            {
+              if (threadShouldExit)
+                {
+                  pte_osThreadExit();
+                }
+            }
+        }
+    }
+
+  return 1;
+}
+
+int pte_thread_detach_and_exit_np()
+{
+  return pte_thread_detach_common(1);
+}
+
+int pte_thread_detach_np()
+{
+  return pte_thread_detach_common(0);
+}
+

+ 449 - 0
pte_generic_osal.h

@@ -0,0 +1,449 @@
+/*
+ * pte_cancellable_wait.c
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *      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 _GENERIC_OS_SUPPORT_H_
+#define _GENERIC_OS_SUPPORT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/** @name Misc */
+//@{
+typedef enum pte_osResult
+{
+
+  /** Operation completed successfully */
+  PTE_OS_OK = 0,
+
+  /** Operation failed because there insufficient resources */
+  PTE_OS_NO_RESOURCES,
+
+  /** Operation failed due to a general failure */
+  PTE_OS_GENERAL_FAILURE,
+
+  /** Operation did not complete because a user specified timeout expired. */
+  PTE_OS_TIMEOUT,
+
+  /** The operation was interrupted before it could complete. */
+  PTE_OS_INTERRUPTED,
+
+  /** An invalid parameter was specified */
+  PTE_OS_INVALID_PARAM
+
+
+} pte_osResult;
+
+/**
+ * Provides a hook for the OSAL to implement any OS specific initialization.  This is guaranteed to be
+ * called before any other OSAL function.
+ */
+pte_osResult pte_osInit(void);
+//@}
+
+/** @name Mutexes */
+//@{
+
+/**
+ * Creates a mutex
+ *
+ * @param pHandle  Set to the handle of the newly created mutex.
+ *
+ * @return PTE_OS_OK - Mutex successfully created
+ * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create mutex
+ */
+pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle);
+
+/**
+ * Deletes a mutex and frees any associated resources.
+ *
+ * @param handle Handle of mutex to delete.
+ *
+ * @return PTE_OS_OK - Mutex successfully deleted.
+ */
+pte_osResult pte_osMutexDelete(pte_osMutexHandle handle);
+
+/**
+ * Locks the mutex
+ *
+ * @param handle Handle of mutex to lock.
+ *
+ * @return PTE_OS_OK - Mutex successfully locked.
+ */
+pte_osResult pte_osMutexLock(pte_osMutexHandle handle);
+
+/**
+ * Locks the mutex, returning after @p timeoutMsecs if the resources is not
+ * available.  Can be used for polling mutex by using @p timeoutMsecs of zero.
+ *
+ * @param handle Handle of mutex to lock.
+ * @param timeoutMsecs Number of milliseconds to wait for resource before returning.
+ *
+ * @return PTE_OS_OK - Mutex successfully locked.
+ * @return PTE_OS_TIMEOUT - Timeout expired before lock was obtained.
+ */
+pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle, unsigned int timeoutMsecs);
+
+/**
+ * Unlocks the mutex
+ *
+ * @param handle Handle of mutex to unlock
+ *
+ * @return PTE_OS_OK - Mutex successfully unlocked.
+ */
+pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle);
+//@}
+
+/** @name Threads */
+//@{
+typedef int (*pte_osThreadEntryPoint)(void *params);
+
+
+/**
+ * Creates a new thread.  The thread must be started in a suspended state - it will be
+ * explicitly started when pte_osThreadStart() is called.
+ *
+ * @param entryPoint Entry point to the new thread.
+ * @param stackSize The initial stack size, in bytes.  Note that this can be considered a minimum -
+ *                  for instance if the OS requires a larger stack space than what the caller specified.
+ * @param initialPriority The priority that the new thread should be initially set to.
+ * @param argv Parameter to pass to the new thread.
+ * @param ppte_osThreadHandle set to the handle of the new thread.
+ *
+ * @return PTE_OS_OK - New thread successfully created.
+ * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create thread
+ */
+pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint,
+                                int stackSize,
+                                int initialPriority,
+                                void *argv,
+                                pte_osThreadHandle* ppte_osThreadHandle);
+
+/**
+ * Starts executing the specified thread.
+ *
+ * @param osThreadHandle handle of the thread to start.
+ *
+ * @return PTE_OS_OK - thread successfully started.
+ */
+pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle);
+
+/**
+ * Causes the current thread to stop executing.
+ *
+ * @return Never returns (thread terminated)
+ */
+void pte_osThreadExit();
+
+/**
+ * Waits for the specified thread to end.  If the thread has already terminated, this returns
+ * immediately.
+ *
+ * @param threadHandle Handle fo thread to wait for.
+ *
+ * @return PTE_OS_OK - specified thread terminated.
+ */
+pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle);
+
+/**
+ * Returns the handle of the currently executing thread.
+ */
+pte_osThreadHandle pte_osThreadGetHandle(void);
+
+/**
+ * Returns the priority of the specified thread.
+ */
+int pte_osThreadGetPriority(pte_osThreadHandle threadHandle);
+
+/**
+ * Sets the priority of the specified thread.
+ *
+ * @return PTE_OS_OK - thread priority successfully set
+ */
+pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle, int newPriority);
+
+/**
+ * Frees resources associated with the specified thread.  This is called after the thread has terminated
+ * and is no longer needed (e.g. after pthread_join returns).  This call will always be made
+ * from a different context than that of the target thread.
+ */
+pte_osResult pte_osThreadDelete(pte_osThreadHandle handle);
+
+/**
+ * Frees resources associated with the specified thread and then causes the thread to exit.
+ * This is called after the thread has terminated and is no longer needed (e.g. after
+ * pthread_join returns).  This call will always be made from the context of the target thread.
+ */
+pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle);
+
+/**
+ * Cancels the specified thread.  This should cause pte_osSemaphoreCancellablePend() and for pte_osThreadCheckCancel()
+ * to return @p PTE_OS_INTERRUPTED.
+ *
+ * @param threadHandle handle to the thread to cancel.
+ *
+ * @return Thread successfully canceled.
+ */
+pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle);
+
+/**
+ * Check if pte_osThreadCancel() has been called on the specified thread.
+ *
+ * @param threadHandle handle of thread to check the state of.
+ *
+ * @return PTE_OS_OK - Thread has not been cancelled
+ * @return PTE_OS_INTERRUPTED - Thread has been cancelled.
+ */
+pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle);
+
+/**
+ * Causes the current thread to sleep for the specified number of milliseconds.
+ */
+void pte_osThreadSleep(unsigned int msecs);
+
+/**
+ * Returns the maximum allowable priority
+ */
+int pte_osThreadGetMaxPriority();
+
+/**
+ * Returns the minimum allowable priority
+ */
+int pte_osThreadGetMinPriority();
+
+/**
+ * Returns the priority that should be used if the caller to pthread_create doesn't
+ * explicitly set one.
+ */
+int pte_osThreadGetDefaultPriority();
+
+//@}
+
+
+/** @name Semaphores */
+//@{
+
+/**
+ * Creates a semaphore
+ *
+ * @param initialValue Initial value of the semaphore
+ * @param pHandle  Set to the handle of the newly created semaphore.
+ *
+ * @return PTE_OS_OK - Semaphore successfully created
+ * @return PTE_OS_NO_RESOURCESs - Insufficient resources to create semaphore
+ */
+pte_osResult pte_osSemaphoreCreate(int initialValue, pte_osSemaphoreHandle *pHandle);
+
+/**
+ * Deletes a semaphore and frees any associated resources.
+ *
+ * @param handle Handle of semaphore to delete.
+ *
+ * @return PTE_OS_OK - Semaphore successfully deleted.
+ */
+pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle);
+
+/**
+ * Posts to the semaphore
+ *
+ * @param handle Semaphore to release
+ * @param count  Amount to increment the semaphore by.
+ *
+ * @return PTE_OS_OK - semaphore successfully released.
+ */
+pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle, int count);
+
+/**
+ * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not
+ * available.  Can be used for polling a semaphore by using @p timeoutMsecs of zero.
+ *
+ * @param handle Handle of semaphore to acquire.
+ * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore
+ *                 before returning.  If set to NULL, wait forever.
+ *
+ * @return PTE_OS_OK - Semaphore successfully acquired.
+ * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained.
+ */
+pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout);
+
+/**
+ * Acquire a semaphore, returning after @p timeoutMsecs if the semaphore is not
+ * available.  Can be used for polling a semaphore by using @p timeoutMsecs of zero.
+ * Call must return immediately if pte_osThreadCancel() is called on the thread waiting for
+ * the semaphore.
+ *
+ * @param handle Handle of semaphore to acquire.
+ * @param pTimeout Pointer to the number of milliseconds to wait to acquire the semaphore
+ *                 before returning.  If set to NULL, wait forever.
+ *
+ * @return PTE_OS_OK - Semaphore successfully acquired.
+ * @return PTE_OS_TIMEOUT - Timeout expired before semaphore was obtained.
+ */
+pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle handle, unsigned int *pTimeout);
+//@}
+
+
+/** @name Thread Local Storage */
+//@{
+/**
+ * Sets the thread specific value for the specified key for the
+ * currently executing thread.
+ *
+ * @param index The TLS key for the value.
+ * @param value The value to save
+ */
+pte_osResult pte_osTlsSetValue(unsigned int key, void * value);
+
+/**
+ * Retrieves the thread specific value for the specified key for
+ * the currently executing thread.  If a value has not been set
+ * for this key, NULL should be returned (i.e. TLS values default
+ * to NULL).
+ *
+ * @param index The TLS key for the value.
+ *
+ * @return The value associated with @p key for the current thread.
+ */
+void * pte_osTlsGetValue(unsigned int key);
+
+/**
+ * Initializes the OS TLS support.  This is called by the PTE library
+ * prior to performing ANY TLS operation.
+ */
+void pte_osTlsInit(void);
+
+/**
+ * Allocates a new TLS key.
+ *
+ * @param pKey On success will be set to the newly allocated key.
+ *
+ * @return PTE_OS_OK - TLS key successfully allocated.
+ * @return PTE_OS_NO_RESOURCESs - Insufficient resources to allocate key (e.g.
+ *                         maximum number of keys reached).
+ */
+pte_osResult pte_osTlsAlloc(unsigned int *pKey);
+
+/**
+ * Frees the specified TLS key.
+ *
+ * @param index TLS key to free
+ *
+ * @return PTE_OS_OK - TLS key was successfully freed.
+ */
+pte_osResult pte_osTlsFree(unsigned int key);
+//@}
+
+/** @name Atomic operations */
+//@{
+
+/**
+ * Sets the target to the specified value as an atomic operation.
+ *
+ * \code
+ * origVal = *ptarg
+ * *ptarg = val
+ * return origVal
+ * \endcode
+ *
+ * @param pTarg Pointer to the value to be exchanged.
+ * @param val Value to be exchanged
+ *
+ * @return original value of destination
+ */
+int pte_osAtomicExchange(int *pTarg, int val);
+
+/**
+ * Performs an atomic compare-and-exchange oepration on the specified
+ * value.  That is:
+ *
+ * \code
+ * origVal = *pdest
+ * if (*pdest == comp)
+ *   then *pdest = exchange
+ * return origVal
+ * \endcode
+ *
+ * @param pdest Pointer to the destination value.
+ * @param exchange Exchange value (value to set destination to if destination == comparand)
+ * @param comp The value to compare to destination.
+ *
+ * @return Original value of destination
+ */
+int pte_osAtomicCompareExchange(int *pdest, int exchange, int comp);
+
+/**
+ * Adds the value to target as an atomic operation
+ *
+ * \code
+ * origVal = *pdest
+ * *pAddend += value
+ * return origVal
+ * \endcode
+ *
+ * @param pdest Pointer to the variable to be updated.
+ * @param value Value to be added to the variable.
+ *
+ * @return Original value of destination
+ */
+int  pte_osAtomicExchangeAdd(int volatile* pdest, int value);
+
+/**
+ * Decrements the destination.
+ *
+ * \code
+ * origVal = *pdest
+ * *pdest++
+ * return origVal
+ * \endcode
+ *
+ * @param pdest Destination value to decrement
+ *
+ * @return Original destination value
+ */
+int pte_osAtomicDecrement(int *pdest);
+
+/**
+ * Increments the destination value
+ *
+ * \code
+ * origVal = *pdest;
+ * *pdest++;
+ * return origVal;
+ */
+int pte_osAtomicIncrement(int *pdest);
+//@}
+
+struct timeb;
+
+int ftime(struct timeb *tb);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _OS_SUPPORT_H_

+ 69 - 0
pte_getprocessors.c

@@ -0,0 +1,69 @@
+/*
+ * pte_getprocessors.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * pte_getprocessors()
+ *
+ * Get the number of CPUs available to the process.
+ *
+ * If the available number of CPUs is 1 then pthread_spin_lock()
+ * will block rather than spin if the lock is already owned.
+ *
+ * pthread_spin_init() calls this routine when initialising
+ * a spinlock. If the number of available processors changes
+ * (after a call to SetProcessAffinityMask()) then only
+ * newly initialised spinlocks will notice.
+ */
+int
+pte_getprocessors (int *count)
+{
+  int result = 0;
+
+  *count = 1;
+
+  return (result);
+}

+ 53 - 0
pte_is_attr.c

@@ -0,0 +1,53 @@
+/*
+ * pte_is_attr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pte_is_attr (const pthread_attr_t * attr)
+{
+  /* Return 0 if the attr object is valid, non-zero otherwise. */
+
+  return (attr == NULL ||
+          *attr == NULL || (*attr)->valid != PTE_ATTR_VALID);
+}

+ 129 - 0
pte_mutex_check_need_init.c

@@ -0,0 +1,129 @@
+/*
+ * pte_mutex_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "pthread.h"
+#include "implement.h"
+
+
+static struct pthread_mutexattr_t_ pte_recursive_mutexattr_s =
+  {
+    PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_RECURSIVE
+  };
+static struct pthread_mutexattr_t_ pte_errorcheck_mutexattr_s =
+  {
+    PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK
+  };
+static pthread_mutexattr_t pte_recursive_mutexattr = &pte_recursive_mutexattr_s;
+static pthread_mutexattr_t pte_errorcheck_mutexattr = &pte_errorcheck_mutexattr_s;
+
+
+int
+pte_mutex_check_need_init (pthread_mutex_t * mutex)
+{
+  register int result = 0;
+  register pthread_mutex_t mtx;
+
+  /*
+   * The following guarded test is specifically for statically
+   * initialised mutexes (via PTHREAD_MUTEX_INITIALIZER).
+   *
+   * Note that by not providing this synchronisation we risk
+   * introducing race conditions into applications which are
+   * correctly written.
+   *
+   * Approach
+   * --------
+   * We know that static mutexes will not be PROCESS_SHARED
+   * so we can serialise access to internal state using
+   * critical sections rather than mutexes.
+   *
+   * If using a single global lock slows applications down too much,
+   * multiple global locks could be created and hashed on some random
+   * value associated with each mutex, the pointer perhaps. At a guess,
+   * a good value for the optimal number of global locks might be
+   * the number of processors + 1.
+   *
+   */
+
+
+  pte_osMutexLock (pte_mutex_test_init_lock);
+
+  /*
+   * We got here possibly under race
+   * conditions. Check again inside the critical section
+   * and only initialise if the mutex is valid (not been destroyed).
+   * If a static mutex has been destroyed, the application can
+   * re-initialise it only by calling pthread_mutex_init()
+   * explicitly.
+   */
+  mtx = *mutex;
+
+  if (mtx == PTHREAD_MUTEX_INITIALIZER)
+    {
+      result = pthread_mutex_init (mutex, NULL);
+    }
+  else if (mtx == PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
+    {
+      result = pthread_mutex_init (mutex, &pte_recursive_mutexattr);
+    }
+  else if (mtx == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      result = pthread_mutex_init (mutex, &pte_errorcheck_mutexattr);
+    }
+  else if (mtx == NULL)
+    {
+      /*
+       * The mutex has been destroyed while we were waiting to
+       * initialise it, so the operation that caused the
+       * auto-initialisation should fail.
+       */
+      result = EINVAL;
+    }
+
+  pte_osMutexUnlock(pte_mutex_test_init_lock);
+
+  return (result);
+}
+
+
+

+ 93 - 0
pte_new.c

@@ -0,0 +1,93 @@
+/*
+ * pte_new.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+
+#include "pthread.h"
+#include "implement.h"
+
+
+pthread_t
+pte_new (void)
+{
+  pthread_t t;
+  pthread_t nil = {NULL, 0};
+  pte_thread_t * tp;
+
+  /*
+   * If there's a reusable pthread_t then use it.
+   */
+  t = pte_threadReusePop ();
+
+  if (NULL != t.p)
+    {
+      tp = (pte_thread_t *) t.p;
+    }
+  else
+    {
+      /* No reuse threads available */
+      tp = (pte_thread_t *) calloc (1, sizeof(pte_thread_t));
+
+      if (tp == NULL)
+        {
+          return nil;
+        }
+
+      /* ptHandle.p needs to point to it's parent pte_thread_t. */
+      t.p = tp->ptHandle.p = tp;
+      t.x = tp->ptHandle.x = 0;
+    }
+
+  /* Set default state. */
+  tp->sched_priority = pte_osThreadGetMinPriority();
+
+  tp->detachState = PTHREAD_CREATE_JOINABLE;
+  tp->cancelState = PTHREAD_CANCEL_ENABLE;
+  tp->cancelType = PTHREAD_CANCEL_DEFERRED;
+  tp->cancelLock = PTHREAD_MUTEX_INITIALIZER;
+  tp->threadLock = PTHREAD_MUTEX_INITIALIZER;
+
+  return t;
+
+}

+ 97 - 0
pte_relmillisecs.c

@@ -0,0 +1,97 @@
+/*
+ * pte_relmillisecs.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <pte_osal.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+typedef long long int64_t;
+
+unsigned int
+pte_relmillisecs (const struct timespec * abstime)
+{
+  const long long NANOSEC_PER_MILLISEC = 1000000;
+  const long long MILLISEC_PER_SEC = 1000;
+  unsigned int milliseconds;
+  long long tmpAbsMilliseconds;
+  long  tmpCurrMilliseconds;
+  struct timeb currSysTime;
+
+  /*
+   * Calculate timeout as milliseconds from current system time.
+   */
+
+  /*
+   * subtract current system time from abstime in a way that checks
+   * that abstime is never in the past, or is never equivalent to the
+   * defined INFINITE value (0xFFFFFFFF).
+   *
+   * Assume all integers are unsigned, i.e. cannot test if less than 0.
+   */
+  tmpAbsMilliseconds =  (int64_t)abstime->tv_sec * MILLISEC_PER_SEC;
+  tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC;
+
+  /* get current system time */
+
+  _ftime(&currSysTime);
+
+  tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC;
+  tmpCurrMilliseconds += (int64_t) currSysTime.millitm;
+
+  if (tmpAbsMilliseconds > tmpCurrMilliseconds)
+    {
+      milliseconds = (unsigned int) (tmpAbsMilliseconds - tmpCurrMilliseconds);
+      if (milliseconds == 0xFFFFFFFF)
+        {
+          /* Timeouts must be finite */
+          milliseconds--;
+        }
+    }
+  else
+    {
+      /* The abstime given is in the past */
+      milliseconds = 0;
+    }
+
+  return milliseconds;
+}

+ 158 - 0
pte_reuse.c

@@ -0,0 +1,158 @@
+/*
+ * pte_threadReuse.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * How it works:
+ * A pthread_t is a struct which is normally passed/returned by
+ * value to/from pthreads routines.  Applications are therefore storing
+ * a copy of the struct as it is at that time.
+ *
+ * The original pthread_t struct plus all copies of it contain the address of
+ * the thread state struct pte_thread_t_ (p), plus a reuse counter (x). Each
+ * pte_thread_t contains the original copy of it's pthread_t.
+ * Once malloced, a pte_thread_t_ struct is not freed until the process exits.
+ *
+ * The thread reuse stack is a simple LILO stack managed through a singly
+ * linked list element in the pte_thread_t.
+ *
+ * Each time a thread is destroyed, the pte_thread_t address is pushed onto the
+ * reuse stack after it's ptHandle's reuse counter has been incremented.
+ *
+ * The following can now be said from this:
+ * - two pthread_t's are identical if their pte_thread_t reference pointers
+ * are equal and their reuse counters are equal. That is,
+ *
+ *   equal = (a.p == b.p && a.x == b.x)
+ *
+ * - a pthread_t copy refers to a destroyed thread if the reuse counter in
+ * the copy is not equal to the reuse counter in the original.
+ *
+ *   threadDestroyed = (copy.x != ((pte_thread_t *)copy.p)->ptHandle.x)
+ *
+ */
+
+/*
+ * Pop a clean pthread_t struct off the reuse stack.
+ */
+pthread_t
+pte_threadReusePop (void)
+{
+  pthread_t t = {NULL, 0};
+
+
+  pte_osMutexLock (pte_thread_reuse_lock);
+
+  if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseTop)
+    {
+      pte_thread_t * tp;
+
+      tp = pte_threadReuseTop;
+
+      pte_threadReuseTop = tp->prevReuse;
+
+      if (PTE_THREAD_REUSE_EMPTY == pte_threadReuseTop)
+        {
+          pte_threadReuseBottom = PTE_THREAD_REUSE_EMPTY;
+        }
+
+      tp->prevReuse = NULL;
+
+      t = tp->ptHandle;
+    }
+
+  pte_osMutexUnlock(pte_thread_reuse_lock);
+
+  return t;
+
+}
+
+/*
+ * Push a clean pthread_t struct onto the reuse stack.
+ * Must be re-initialised when reused.
+ * All object elements (mutexes, events etc) must have been either
+ * detroyed before this, or never initialised.
+ */
+void
+pte_threadReusePush (pthread_t thread)
+{
+  pte_thread_t * tp = (pte_thread_t *) thread.p;
+  pthread_t t;
+
+
+  pte_osMutexLock (pte_thread_reuse_lock);
+
+  t = tp->ptHandle;
+  memset(tp, 0, sizeof(pte_thread_t));
+
+  /* Must restore the original POSIX handle that we just wiped. */
+  tp->ptHandle = t;
+
+  /* Bump the reuse counter now */
+#ifdef PTE_THREAD_ID_REUSE_INCREMENT
+  tp->ptHandle.x += PTE_THREAD_ID_REUSE_INCREMENT;
+#else
+  tp->ptHandle.x++;
+#endif
+
+  tp->prevReuse = PTE_THREAD_REUSE_EMPTY;
+
+  if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseBottom)
+    {
+      pte_threadReuseBottom->prevReuse = tp;
+    }
+  else
+    {
+      pte_threadReuseTop = tp;
+    }
+
+  pte_threadReuseBottom = tp;
+
+  pte_osMutexUnlock(pte_thread_reuse_lock);
+}

+ 56 - 0
pte_rwlock_cancelwrwait.c

@@ -0,0 +1,56 @@
+/*
+ * pte_rwlock_cancelwrwait.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+void
+pte_rwlock_cancelwrwait (void *arg)
+{
+  pthread_rwlock_t rwl = (pthread_rwlock_t) arg;
+
+  rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount;
+  rwl->nCompletedSharedAccessCount = 0;
+
+  (void) pthread_mutex_unlock (&(rwl->mtxSharedAccessCompleted));
+  (void) pthread_mutex_unlock (&(rwl->mtxExclusiveAccess));
+}

+ 102 - 0
pte_rwlock_check_need_init.c

@@ -0,0 +1,102 @@
+/*
+ * pthread_rwlock_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements read/write lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pte_rwlock_check_need_init (pthread_rwlock_t * rwlock)
+{
+  int result = 0;
+
+  /*
+   * The following guarded test is specifically for statically
+   * initialised rwlocks (via PTHREAD_RWLOCK_INITIALIZER).
+   *
+   * Note that by not providing this synchronisation we risk
+   * introducing race conditions into applications which are
+   * correctly written.
+   *
+   * Approach
+   * --------
+   * We know that static rwlocks will not be PROCESS_SHARED
+   * so we can serialise access to internal state using
+   * critical sections rather than mutexes.
+   *
+   * If using a single global lock slows applications down too much,
+   * multiple global locks could be created and hashed on some random
+   * value associated with each mutex, the pointer perhaps. At a guess,
+   * a good value for the optimal number of global locks might be
+   * the number of processors + 1.
+   *
+   */
+
+
+  pte_osMutexLock (pte_rwlock_test_init_lock);
+
+  /*
+   * We got here possibly under race
+   * conditions. Check again inside the critical section
+   * and only initialise if the rwlock is valid (not been destroyed).
+   * If a static rwlock has been destroyed, the application can
+   * re-initialise it only by calling pthread_rwlock_init()
+   * explicitly.
+   */
+  if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
+    {
+      result = pthread_rwlock_init (rwlock, NULL);
+    }
+  else if (*rwlock == NULL)
+    {
+      /*
+       * The rwlock has been destroyed while we were waiting to
+       * initialise it, so the operation that caused the
+       * auto-initialisation should fail.
+       */
+      result = EINVAL;
+    }
+
+  pte_osMutexUnlock(pte_rwlock_test_init_lock);
+
+  return result;
+}

+ 89 - 0
pte_spinlock_check_need_init.c

@@ -0,0 +1,89 @@
+/*
+ * pte_spinlock_check_need_init.c
+ *
+ * Description:
+ * This translation unit implements spin lock primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pte_spinlock_check_need_init (pthread_spinlock_t * lock)
+{
+  int result = 0;
+
+  /*
+   * The following guarded test is specifically for statically
+   * initialised spinlocks (via PTHREAD_SPINLOCK_INITIALIZER).
+   *
+   * Note that by not providing this synchronisation we risk
+   * introducing race conditions into applications which are
+   * correctly written.
+   */
+
+
+  pte_osMutexLock (pte_spinlock_test_init_lock);
+
+  /*
+   * We got here possibly under race
+   * conditions. Check again inside the critical section
+   * and only initialise if the spinlock is valid (not been destroyed).
+   * If a static spinlock has been destroyed, the application can
+   * re-initialise it only by calling pthread_spin_init()
+   * explicitly.
+   */
+  if (*lock == PTHREAD_SPINLOCK_INITIALIZER)
+    {
+      result = pthread_spin_init (lock, PTHREAD_PROCESS_PRIVATE);
+    }
+  else if (*lock == NULL)
+    {
+      /*
+       * The spinlock has been destroyed while we were waiting to
+       * initialise it, so the operation that caused the
+       * auto-initialisation should fail.
+       */
+      result = EINVAL;
+    }
+
+  pte_osMutexUnlock(pte_spinlock_test_init_lock);
+
+  return (result);
+}

+ 101 - 0
pte_threadDestroy.c

@@ -0,0 +1,101 @@
+/*
+ * pte_threadDestroy.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+
+static void
+pte_threadDestroyCommon (pthread_t thread, unsigned char shouldThreadExit)
+{
+  pte_thread_t * tp = (pte_thread_t *) thread.p;
+  pte_thread_t threadCopy;
+
+  if (tp != NULL)
+    {
+      /*
+       * Copy thread state so that the thread can be atomically NULLed.
+       */
+      memcpy (&threadCopy, tp, sizeof (threadCopy));
+
+      /*
+       * Thread ID structs are never freed. They're NULLed and reused.
+       * This also sets the thread to PThreadStateInitial (invalid).
+       */
+      pte_threadReusePush (thread);
+
+      (void) pthread_mutex_destroy(&threadCopy.cancelLock);
+      (void) pthread_mutex_destroy(&threadCopy.threadLock);
+
+      if (threadCopy.threadId != 0)
+        {
+          if (shouldThreadExit)
+            {
+              pte_osThreadExitAndDelete(threadCopy.threadId);
+            }
+          else
+            {
+              pte_osThreadDelete(threadCopy.threadId);
+            }
+        }
+
+
+
+    }
+}				/* pte_threadDestroy */
+
+void pte_threadDestroy (pthread_t thread)
+{
+  pte_threadDestroyCommon(thread,0);
+}
+
+void pte_threadExitAndDestroy (pthread_t thread)
+{
+  pte_threadDestroyCommon(thread,1);
+}
+

+ 248 - 0
pte_threadStart.c

@@ -0,0 +1,248 @@
+/*
+ * pte_threadStart.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+#if defined(PTE_CLEANUP_CXX)
+
+# if defined(__GNUC__) && __GNUC__ < 3
+#   include <new>
+# else
+#   include <new>
+using
+std::terminate_handler;
+using
+std::terminate;
+using
+std::set_terminate;
+# endif
+
+typedef terminate_handler terminate_function;
+
+static terminate_function pte_oldTerminate;
+
+void
+pte_terminate ()
+{
+  set_terminate (pte_oldTerminate);
+  (void) pte_thread_detach_np();
+//  terminate ();
+}
+
+#endif
+
+int pte_threadStart (void *vthreadParms)
+{
+  ThreadParms * threadParms = (ThreadParms *) vthreadParms;
+  pthread_t self;
+  pte_thread_t * sp;
+  void *(*start) (void *);
+  void * arg;
+
+#ifdef PTE_CLEANUP_C
+#include <setjmp.h>
+
+  int setjmp_rc;
+#endif
+
+  void * status = (void *) 0;
+
+  self = threadParms->tid;
+  sp = (pte_thread_t *) self.p;
+  start = threadParms->start;
+  arg = threadParms->arg;
+//  free (threadParms);
+
+  pthread_setspecific (pte_selfThreadKey, sp);
+
+  sp->state = PThreadStateRunning;
+
+#ifdef PTE_CLEANUP_C
+
+
+  setjmp_rc = setjmp (sp->start_mark);
+
+
+  if (0 == setjmp_rc)
+    {
+
+      /*
+       * Run the caller's routine;
+       */
+      sp->exitStatus = status = (*start) (arg);
+    }
+  else
+    {
+      switch (setjmp_rc)
+        {
+        case PTE_EPS_CANCEL:
+          status = sp->exitStatus = PTHREAD_CANCELED;
+          break;
+        case PTE_EPS_EXIT:
+          status = sp->exitStatus;
+          break;
+        default:
+          status = sp->exitStatus = PTHREAD_CANCELED;
+          break;
+        }
+    }
+
+#else /* PTE_CLEANUP_C */
+
+#ifdef PTE_CLEANUP_CXX
+
+  pte_oldTerminate = set_terminate (&pte_terminate);
+
+  try
+    {
+      /*
+      * Run the caller's routine in a nested try block so that we
+      * can run the user's terminate function, which may call
+      * pthread_exit() or be canceled.
+      */
+      try
+        {
+          status = sp->exitStatus = (*start) (arg);
+        }
+      catch (pte_exception &)
+        {
+          /*
+          * Pass these through to the outer block.
+          */
+          throw;
+        }
+      catch (...)
+        {
+          /*
+          * We want to run the user's terminate function if supplied.
+          * That function may call pthread_exit() or be canceled, which will
+          * be handled by the outer try block.
+          *
+          * pte_terminate() will be called if there is no user
+          * supplied function.
+          */
+
+          terminate_function
+          term_func = set_terminate (0);
+          set_terminate (term_func);
+
+          if (term_func != 0)
+            {
+              term_func ();
+            }
+
+          throw;
+        }
+    }
+  catch (pte_exception_cancel &)
+    {
+      /*
+      * Thread was canceled.
+      */
+      status = sp->exitStatus = PTHREAD_CANCELED;
+    }
+  catch (pte_exception_exit &)
+    {
+      /*
+      * Thread was exited via pthread_exit().
+      */
+      status = sp->exitStatus;
+    }
+  catch (...)
+    {
+      /*
+      * A system unexpected exception has occurred running the user's
+      * terminate routine. We get control back within this block - cleanup
+      * and release the exception out of thread scope.
+      */
+      status = sp->exitStatus = PTHREAD_CANCELED;
+      (void) pthread_mutex_lock (&sp->cancelLock);
+      sp->state = PThreadStateException;
+      (void) pthread_mutex_unlock (&sp->cancelLock);
+      (void) pte_thread_detach_np();
+      (void) set_terminate (pte_oldTerminate);
+      throw;
+
+      /*
+      * Never reached.
+      */
+    }
+
+  (void) set_terminate (pte_oldTerminate);
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* PTE_CLEANUP_CXX */
+#endif /* PTE_CLEANUP_C */
+
+  /*
+   * We need to cleanup the pthread now if we have
+   * been statically linked, in which case the cleanup
+   * in dllMain won't get done. Joinable threads will
+   * only be partially cleaned up and must be fully cleaned
+   * up by pthread_join() or pthread_detach().
+   *
+   * Note: if this library has been statically linked,
+   * implicitly created pthreads (those created
+   * for OS threads which have called pthreads routines)
+   * must be cleaned up explicitly by the application
+   * (by calling pte_thread_detach_np()).
+   */
+  (void) pte_thread_detach_and_exit_np ();
+
+  //pte_osThreadExit(status);
+
+  /*
+   * Never reached.
+   */
+
+  return (unsigned) status;
+
+}				/* pte_threadStart */
+

+ 142 - 0
pte_throw.c

@@ -0,0 +1,142 @@
+/*
+ * pte_throw.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * pte_throw
+ *
+ * All canceled and explicitly exited POSIX threads go through
+ * here. This routine knows how to exit both POSIX initiated threads and
+ * 'implicit' POSIX threads for each of the possible language modes (C,
+ * C++).
+ */
+void
+pte_throw (unsigned int exception)
+{
+  /*
+   * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
+   * unnecessarily.
+   */
+  pte_thread_t * sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey);
+
+
+  if (exception != PTE_EPS_CANCEL && exception != PTE_EPS_EXIT)
+    {
+      /* Should never enter here */
+      exit (1);
+    }
+
+  if (NULL == sp || sp->implicit)
+    {
+      /*
+       * We're inside a non-POSIX initialised OS thread
+       * so there is no point to jump or throw back to. Just do an
+       * explicit thread exit here after cleaning up POSIX
+       * residue (i.e. cleanup handlers, POSIX thread handle etc).
+       */
+      unsigned exitCode = 0;
+
+      switch (exception)
+        {
+        case PTE_EPS_CANCEL:
+          exitCode = (unsigned) PTHREAD_CANCELED;
+          break;
+        case PTE_EPS_EXIT:
+          exitCode = (unsigned) sp->exitStatus;;
+          break;
+        }
+
+      pte_thread_detach_and_exit_np ();
+
+//      pte_osThreadExit((void*)exitCode);
+
+    }
+
+#ifdef PTE_CLEANUP_C
+
+  pte_pop_cleanup_all (1);
+  longjmp (sp->start_mark, exception);
+
+#else /* PTE_CLEANUP_C */
+
+#ifdef PTE_CLEANUP_CXX
+
+  switch (exception)
+    {
+    case PTE_EPS_CANCEL:
+      throw pte_exception_cancel ();
+      break;
+    case PTE_EPS_EXIT:
+      throw pte_exception_exit ();
+      break;
+    }
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* PTE_CLEANUP_CXX */
+
+#endif /* PTE_CLEANUP_C */
+
+  /* Never reached */
+}
+
+
+void
+pte_pop_cleanup_all (int execute)
+{
+  while (NULL != pte_pop_cleanup (execute))
+    {
+    }
+}
+
+
+unsigned int
+pte_get_exception_services_code (void)
+{
+  return (unsigned int) NULL;
+}

+ 126 - 0
pte_tkAssocCreate.c

@@ -0,0 +1,126 @@
+/*
+ * pte_tkAssocCreate.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pte_tkAssocCreate (pte_thread_t * sp, pthread_key_t key)
+/*
+ * -------------------------------------------------------------------
+ * This routine creates an association that
+ * is unique for the given (thread,key) combination.The association
+ * is referenced by both the thread and the key.
+ * This association allows us to determine what keys the
+ * current thread references and what threads a given key
+ * references.
+ * See the detailed description
+ * at the beginning of this file for further details.
+ *
+ * Notes:
+ *      1)      New associations are pushed to the beginning of the
+ *              chain so that the internal pte_selfThreadKey association
+ *              is always last, thus allowing selfThreadExit to
+ *              be implicitly called last by pthread_exit.
+ *      2)
+ *
+ * Parameters:
+ *              thread
+ *                      current running thread.
+ *              key
+ *                      key on which to create an association.
+ * Returns:
+ *       0              - if successful,
+ *       ENOMEM         - not enough memory to create assoc or other object
+ *       EINVAL         - an internal error occurred
+ *       ENOSYS         - an internal error occurred
+ * -------------------------------------------------------------------
+ */
+{
+  ThreadKeyAssoc *assoc;
+
+  /*
+   * Have to create an association and add it
+   * to both the key and the thread.
+   *
+   * Both key->keyLock and thread->threadLock are locked on
+   * entry to this routine.
+   */
+  assoc = (ThreadKeyAssoc *) calloc (1, sizeof (*assoc));
+
+  if (assoc == NULL)
+    {
+      return ENOMEM;
+    }
+
+  assoc->thread = sp;
+  assoc->key = key;
+
+  /*
+   * Register assoc with key
+   */
+  assoc->prevThread = NULL;
+  assoc->nextThread = (ThreadKeyAssoc *) key->threads;
+  if (assoc->nextThread != NULL)
+    {
+      assoc->nextThread->prevThread = assoc;
+    }
+  key->threads = (void *) assoc;
+
+  /*
+   * Register assoc with thread
+   */
+  assoc->prevKey = NULL;
+  assoc->nextKey = (ThreadKeyAssoc *) sp->keys;
+  if (assoc->nextKey != NULL)
+    {
+      assoc->nextKey->prevKey = assoc;
+    }
+  sp->keys = (void *) assoc;
+
+  return (0);
+
+}				/* pte_tkAssocCreate */

+ 122 - 0
pte_tkAssocDestroy.c

@@ -0,0 +1,122 @@
+/*
+ * pte_tkAssocDestroy.c
+ *
+ * Description:
+ * This translation unit implements routines which are private to
+ * the implementation and may be used throughout it.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void
+pte_tkAssocDestroy (ThreadKeyAssoc * assoc)
+/*
+ * -------------------------------------------------------------------
+ * This routine releases all resources for the given ThreadKeyAssoc
+ * once it is no longer being referenced
+ * ie) either the key or thread has stopped referencing it.
+ *
+ * Parameters:
+ *              assoc
+ *                      an instance of ThreadKeyAssoc.
+ * Returns:
+ *      N/A
+ * -------------------------------------------------------------------
+ */
+{
+
+  /*
+   * Both key->keyLock and thread->threadLock are locked on
+   * entry to this routine.
+   */
+  if (assoc != NULL)
+    {
+      ThreadKeyAssoc * prev, * next;
+
+      /* Remove assoc from thread's keys chain */
+      prev = assoc->prevKey;
+      next = assoc->nextKey;
+      if (prev != NULL)
+        {
+          prev->nextKey = next;
+        }
+      if (next != NULL)
+        {
+          next->prevKey = prev;
+        }
+
+      if (assoc->thread->keys == assoc)
+        {
+          /* We're at the head of the thread's keys chain */
+          assoc->thread->keys = next;
+        }
+      if (assoc->thread->nextAssoc == assoc)
+        {
+          /*
+           * Thread is exiting and we're deleting the assoc to be processed next.
+           * Hand thread the assoc after this one.
+           */
+          assoc->thread->nextAssoc = next;
+        }
+
+      /* Remove assoc from key's threads chain */
+      prev = assoc->prevThread;
+      next = assoc->nextThread;
+      if (prev != NULL)
+        {
+          prev->nextThread = next;
+        }
+      if (next != NULL)
+        {
+          next->prevThread = prev;
+        }
+
+      if (assoc->key->threads == assoc)
+        {
+          /* We're at the head of the key's threads chain */
+          assoc->key->threads = next;
+        }
+
+      free (assoc);
+    }
+
+}				/* pte_tkAssocDestroy */

+ 1006 - 0
pthread.h

@@ -0,0 +1,1006 @@
+/* This is an implementation of the threads API of POSIX 1003.1-2001.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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
+ */
+#if !defined( PTHREAD_H )
+#define PTHREAD_H
+
+#include <pte-config.h>
+
+#include <sched.h>
+
+#define PTE_VERSION 2,8,0,0
+#define PTE_VERSION_STRING "2, 8, 0, 0\0"
+
+/* There are two implementations of cancel cleanup.
+ * Note that pthread.h is included in both application
+ * compilation units and also internally for the library.
+ * The code here and within the library aims to work
+ * for all reasonable combinations of environments.
+ *
+ * The two implementations are:
+ *
+ *   C
+ *   C++
+ *
+ */
+
+/*
+ * Define defaults for cleanup code.
+ * Note: Unless the build explicitly defines one of the following, then
+ * we default to standard C style cleanup. This style uses setjmp/longjmp
+ * in the cancelation and thread exit implementations and therefore won't
+ * do stack unwinding if linked to applications that have it (e.g.
+ * C++ apps). This is currently consistent with most/all commercial Unix
+ * POSIX threads implementations.
+ */
+#if !defined( PTE_CLEANUP_CXX ) && !defined( PTE_CLEANUP_C )
+# define PTE_CLEANUP_C
+#endif
+
+#undef PTE_LEVEL
+
+#if defined(_POSIX_SOURCE)
+#define PTE_LEVEL 0
+/* Early POSIX */
+#endif
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
+#undef PTE_LEVEL
+#define PTE_LEVEL 1
+/* Include 1b, 1c and 1d */
+#endif
+
+#if defined(INCLUDE_NP)
+#undef PTE_LEVEL
+#define PTE_LEVEL 2
+/* Include Non-Portable extensions */
+#endif
+
+#define PTE_LEVEL_MAX 3
+
+#if !defined(PTE_LEVEL)
+#define PTE_LEVEL PTE_LEVEL_MAX
+/* Include everything */
+#endif
+
+/*
+ * -------------------------------------------------------------
+ *
+ *
+ * Module: pthread.h
+ *
+ * Purpose:
+ *      Provides an implementation of PThreads based upon the
+ *      standard:
+ *
+ *              POSIX 1003.1-2001
+ *  and
+ *    The Single Unix Specification version 3
+ *
+ *    (these two are equivalent)
+ *
+ *      in order to enhance code portability between Windows,
+ *  various commercial Unix implementations, and Linux.
+ *
+ *      See the ANNOUNCE file for a full list of conforming
+ *      routines and defined constants, and a list of missing
+ *      routines and constants not defined in this implementation.
+ *
+ * Authors:
+ *      There have been many contributors to this library.
+ *      The initial implementation was contributed by
+ *      John Bossom, and several others have provided major
+ *      sections or revisions of parts of the implementation.
+ *      Often significant effort has been contributed to
+ *      find and fix important bugs and other problems to
+ *      improve the reliability of the library, which sometimes
+ *      is not reflected in the amount of code which changed as
+ *      result.
+ *      As much as possible, the contributors are acknowledged
+ *      in the ChangeLog file in the source code distribution
+ *      where their changes are noted in detail.
+ *
+ *      Contributors are listed in the CONTRIBUTORS file.
+ *
+ *      As usual, all bouquets go to the contributors, and all
+ *      brickbats go to the project maintainer.
+ *
+ * Maintainer:
+ *      The code base for this project is coordinated and
+ *      eventually pre-tested, packaged, and made available by
+ *
+ *              Ross Johnson <[email protected]>
+ *
+ * QA Testers:
+ *      Ultimately, the library is tested in the real world by
+ *      a host of competent and demanding scientists and
+ *      engineers who report bugs and/or provide solutions
+ *      which are then fixed or incorporated into subsequent
+ *      versions of the library. Each time a bug is fixed, a
+ *      test case is written to prove the fix and ensure
+ *      that later changes to the code don't reintroduce the
+ *      same error. The number of test cases is slowly growing
+ *      and therefore so is the code reliability.
+ *
+ * Compliance:
+ *      See the file ANNOUNCE for the list of implemented
+ *      and not-implemented routines and defined options.
+ *      Of course, these are all defined is this file as well.
+ *
+ * Web site:
+ *      The source code and other information about this library
+ *      are available from
+ *
+ *              http://sources.redhat.com/pthreads-win32/
+ *
+ * -------------------------------------------------------------
+ */
+
+#include <time.h>
+
+#include <setjmp.h>
+#include <limits.h>
+
+/*
+ * Boolean values to make us independent of system includes.
+ */
+enum
+{
+  PTE_FALSE = 0,
+  PTE_TRUE = (! PTE_FALSE)
+};
+
+
+    /*
+     * -------------------------------------------------------------
+     *
+     * POSIX 1003.1-2001 Options
+     * =========================
+     *
+     * Options are normally set in <unistd.h>, which is not provided
+     * with pthreads-embedded.
+     *
+     * For conformance with the Single Unix Specification (version 3), all of the
+     * options below are defined, and have a value of either -1 (not supported)
+     * or 200112L (supported).
+     *
+     * These options can neither be left undefined nor have a value of 0, because
+     * either indicates that sysconf(), which is not implemented, may be used at
+     * runtime to check the status of the option.
+     *
+     * _POSIX_THREADS (== 200112L)
+     *                      If == 200112L, you can use threads
+     *
+     * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
+     *                      If == 200112L, you can control the size of a thread's
+     *                      stack
+     *                              pthread_attr_getstacksize
+     *                              pthread_attr_setstacksize
+     *
+     * _POSIX_THREAD_ATTR_STACKADDR (== -1)
+     *                      If == 200112L, you can allocate and control a thread's
+     *                      stack. If not supported, the following functions
+     *                      will return ENOSYS, indicating they are not
+     *                      supported:
+     *                              pthread_attr_getstackaddr
+     *                              pthread_attr_setstackaddr
+     *
+     * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
+     *                      If == 200112L, you can use realtime scheduling.
+     *                      This option indicates that the behaviour of some
+     *                      implemented functions conforms to the additional TPS
+     *                      requirements in the standard. E.g. rwlocks favour
+     *                      writers over readers when threads have equal priority.
+     *
+     * _POSIX_THREAD_PRIO_INHERIT (== -1)
+     *                      If == 200112L, you can create priority inheritance
+     *                      mutexes.
+     *                              pthread_mutexattr_getprotocol +
+     *                              pthread_mutexattr_setprotocol +
+     *
+     * _POSIX_THREAD_PRIO_PROTECT (== -1)
+     *                      If == 200112L, you can create priority ceiling mutexes
+     *                      Indicates the availability of:
+     *                              pthread_mutex_getprioceiling
+     *                              pthread_mutex_setprioceiling
+     *                              pthread_mutexattr_getprioceiling
+     *                              pthread_mutexattr_getprotocol     +
+     *                              pthread_mutexattr_setprioceiling
+     *                              pthread_mutexattr_setprotocol     +
+     *
+     * _POSIX_THREAD_PROCESS_SHARED (== -1)
+     *                      If set, you can create mutexes and condition
+     *                      variables that can be shared with another
+     *                      process.If set, indicates the availability
+     *                      of:
+     *                              pthread_mutexattr_getpshared
+     *                              pthread_mutexattr_setpshared
+     *                              pthread_condattr_getpshared
+     *                              pthread_condattr_setpshared
+     *
+     * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
+     *                      If == 200112L you can use the special *_r library
+     *                      functions that provide thread-safe behaviour
+     *
+     * _POSIX_READER_WRITER_LOCKS (== 200112L)
+     *                      If == 200112L, you can use read/write locks
+     *
+     * _POSIX_SPIN_LOCKS (== 200112L)
+     *                      If == 200112L, you can use spin locks
+     *
+     * _POSIX_BARRIERS (== 200112L)
+     *                      If == 200112L, you can use barriers
+     *
+     *      + These functions provide both 'inherit' and/or
+     *        'protect' protocol, based upon these macro
+     *        settings.
+     *
+     * -------------------------------------------------------------
+     */
+
+    /*
+     * POSIX Options
+     */
+#undef _POSIX_THREADS
+#define _POSIX_THREADS 200112L
+
+#undef _POSIX_READER_WRITER_LOCKS
+#define _POSIX_READER_WRITER_LOCKS 200112L
+
+#undef _POSIX_SPIN_LOCKS
+#define _POSIX_SPIN_LOCKS 200112L
+
+#undef _POSIX_BARRIERS
+#define _POSIX_BARRIERS 200112L
+
+#undef _POSIX_THREAD_SAFE_FUNCTIONS
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
+
+#undef _POSIX_THREAD_ATTR_STACKSIZE
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L
+
+    /*
+     * The following options are not supported
+     */
+#undef _POSIX_THREAD_ATTR_STACKADDR
+#define _POSIX_THREAD_ATTR_STACKADDR -1
+
+#undef _POSIX_THREAD_PRIO_INHERIT
+#define _POSIX_THREAD_PRIO_INHERIT -1
+
+#undef _POSIX_THREAD_PRIO_PROTECT
+#define _POSIX_THREAD_PRIO_PROTECT -1
+
+    /* TPS is not fully supported.  */
+#undef _POSIX_THREAD_PRIORITY_SCHEDULING
+#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
+
+#undef _POSIX_THREAD_PROCESS_SHARED
+#define _POSIX_THREAD_PROCESS_SHARED -1
+
+
+    /*
+     * POSIX 1003.1-2001 Limits
+     * ===========================
+     *
+     * These limits are normally set in <limits.h>, which is not provided with
+     * pthreads-embedded.
+     *
+     * PTHREAD_DESTRUCTOR_ITERATIONS
+     *                      Maximum number of attempts to destroy
+     *                      a thread's thread-specific data on
+     *                      termination (must be at least 4)
+     *
+     * PTHREAD_KEYS_MAX
+     *                      Maximum number of thread-specific data keys
+     *                      available per process (must be at least 128)
+     *
+     * PTHREAD_STACK_MIN
+     *                      Minimum supported stack size for a thread
+     *
+     * PTHREAD_THREADS_MAX
+     *                      Maximum number of threads supported per
+     *                      process (must be at least 64).
+     *
+     * SEM_NSEMS_MAX
+     *                      The maximum number of semaphores a process can have.
+     *                      (must be at least 256)
+     *
+     * SEM_VALUE_MAX
+     *                      The maximum value a semaphore can have.
+     *                      (must be at least 32767)
+     *
+     */
+#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS     4
+
+#undef PTHREAD_DESTRUCTOR_ITERATIONS
+#define PTHREAD_DESTRUCTOR_ITERATIONS           _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+#undef _POSIX_THREAD_KEYS_MAX
+#define _POSIX_THREAD_KEYS_MAX                  128
+
+#undef PTHREAD_KEYS_MAX
+#define PTHREAD_KEYS_MAX                        _POSIX_THREAD_KEYS_MAX
+
+#undef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN                       0
+
+#undef _POSIX_THREAD_THREADS_MAX
+#define _POSIX_THREAD_THREADS_MAX               64
+
+    /* Arbitrary value */
+#undef PTHREAD_THREADS_MAX
+#define PTHREAD_THREADS_MAX                     2019
+
+#undef _POSIX_SEM_NSEMS_MAX
+#define _POSIX_SEM_NSEMS_MAX                    256
+
+    /* Arbitrary value */
+#undef SEM_NSEMS_MAX
+#define SEM_NSEMS_MAX                           1024
+
+#undef _POSIX_SEM_VALUE_MAX
+#define _POSIX_SEM_VALUE_MAX                    32767
+
+#undef SEM_VALUE_MAX
+#define SEM_VALUE_MAX                           INT_MAX
+
+
+    /*
+     * Generic handle type - intended to extend uniqueness beyond
+     * that available with a simple pointer. It should scale for either
+     * IA-32 or IA-64.
+     */
+    typedef struct
+      {
+        void * p;                   /* Pointer to actual object */
+        unsigned int x;             /* Extra information - reuse count etc */
+      } pte_handle_t;
+
+    typedef pte_handle_t pthread_t;
+    typedef struct pthread_attr_t_ * pthread_attr_t;
+    typedef struct pthread_once_t_ pthread_once_t;
+    typedef struct pthread_key_t_ * pthread_key_t;
+    typedef struct pthread_mutex_t_ * pthread_mutex_t;
+    typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
+    typedef struct pthread_cond_t_ * pthread_cond_t;
+    typedef struct pthread_condattr_t_ * pthread_condattr_t;
+    typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
+    typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
+    typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
+    typedef struct pthread_barrier_t_ * pthread_barrier_t;
+    typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
+
+    /*
+     * ====================
+     * ====================
+     * POSIX Threads
+     * ====================
+     * ====================
+     */
+
+    enum
+    {
+      /*
+       * pthread_attr_{get,set}detachstate
+       */
+      PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
+      PTHREAD_CREATE_DETACHED       = 1,
+
+      /*
+       * pthread_attr_{get,set}inheritsched
+       */
+      PTHREAD_INHERIT_SCHED         = 0,
+      PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
+
+      /*
+       * pthread_{get,set}scope
+       */
+      PTHREAD_SCOPE_PROCESS         = 0,
+      PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
+      PTHREAD_SCOPE_PROCESS_VFPU    = 2,  /* PSP specific */
+
+      /*
+       * pthread_setcancelstate paramters
+       */
+      PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
+      PTHREAD_CANCEL_DISABLE        = 1,
+
+      /*
+       * pthread_setcanceltype parameters
+       */
+      PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
+      PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
+
+      /*
+       * pthread_mutexattr_{get,set}pshared
+       * pthread_condattr_{get,set}pshared
+       */
+      PTHREAD_PROCESS_PRIVATE       = 0,
+      PTHREAD_PROCESS_SHARED        = 1,
+
+      /*
+       * pthread_barrier_wait
+       */
+      PTHREAD_BARRIER_SERIAL_THREAD = -1
+    };
+
+    /*
+     * ====================
+     * ====================
+     * Cancelation
+     * ====================
+     * ====================
+     */
+#define PTHREAD_CANCELED       ((void *) -1)
+
+
+    /*
+     * ====================
+     * ====================
+     * Once Key
+     * ====================
+     * ====================
+     */
+#define PTHREAD_ONCE_INIT       { PTE_FALSE, 0, 0, 0}
+
+    struct pthread_once_t_
+      {
+        int          state;
+        void *       semaphore;
+        int 		   numSemaphoreUsers;
+        int          done;        /* indicates if user function has been executed */
+//  void *       lock;
+//  int          reserved1;
+//  int          reserved2;
+      };
+
+
+    /*
+     * ====================
+     * ====================
+     * Object initialisers
+     * ====================
+     * ====================
+     */
+#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
+
+    /*
+     * Compatibility with LinuxThreads
+     */
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
+
+#define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
+
+#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
+
+#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
+
+
+    /*
+     * Mutex types.
+     */
+    enum
+    {
+      /* Compatibility with LinuxThreads */
+      PTHREAD_MUTEX_FAST_NP,
+      PTHREAD_MUTEX_RECURSIVE_NP,
+      PTHREAD_MUTEX_ERRORCHECK_NP,
+      PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
+      PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
+      /* For compatibility with POSIX */
+      PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
+      PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+      PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+      PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+    };
+
+
+    typedef struct pte_cleanup_t pte_cleanup_t;
+
+    typedef void (*  pte_cleanup_callback_t)(void *);
+
+    struct pte_cleanup_t
+      {
+        pte_cleanup_callback_t routine;
+        void *arg;
+        struct pte_cleanup_t *prev;
+      };
+
+#ifdef PTE_CLEANUP_C
+
+    /*
+     * C implementation of PThreads cancel cleanup
+     */
+
+#define pthread_cleanup_push( _rout, _arg ) \
+        { \
+            pte_cleanup_t     _cleanup; \
+            \
+            pte_push_cleanup( &_cleanup, (pte_cleanup_callback_t) (_rout), (_arg) ); \
+ 
+#define pthread_cleanup_pop( _execute ) \
+            (void) pte_pop_cleanup( _execute ); \
+        }
+
+#else /* PTE_CLEANUP_C */
+
+#ifdef PTE_CLEANUP_CXX
+
+    /*
+    * C++ version of cancel cleanup.
+    * - John E. Bossom.
+    */
+
+    class PThreadCleanup
+      {
+        /*
+        * PThreadCleanup
+        *
+        * Purpose
+        *      This class is a C++ helper class that is
+        *      used to implement pthread_cleanup_push/
+        *      pthread_cleanup_pop.
+        *      The destructor of this class automatically
+        *      pops the pushed cleanup routine regardless
+        *      of how the code exits the scope
+        *      (i.e. such as by an exception)
+        */
+        pte_cleanup_callback_t cleanUpRout;
+        void    *       obj;
+        int             executeIt;
+
+      public:
+        PThreadCleanup() :
+            cleanUpRout( 0 ),
+            obj( 0 ),
+            executeIt( 0 )
+            /*
+            * No cleanup performed
+            */
+        {
+        }
+
+        PThreadCleanup(
+          pte_cleanup_callback_t routine,
+          void    *       arg ) :
+            cleanUpRout( routine ),
+            obj( arg ),
+            executeIt( 1 )
+            /*
+            * Registers a cleanup routine for 'arg'
+            */
+        {
+        }
+
+        ~PThreadCleanup()
+        {
+          if ( executeIt )
+            {
+              (void) (*cleanUpRout)( obj );
+            }
+        }
+
+        void execute( int exec )
+        {
+          executeIt = exec;
+        }
+      };
+
+    /*
+    * C++ implementation of PThreads cancel cleanup;
+    * This implementation takes advantage of a helper
+    * class who's destructor automatically calls the
+    * cleanup routine if we exit our scope weirdly
+    */
+#define pthread_cleanup_push( _rout, _arg ) \
+        { \
+            PThreadCleanup  cleanup((pte_cleanup_callback_t)(_rout), \
+                                    (void *) (_arg) );
+
+#define pthread_cleanup_pop( _execute ) \
+            cleanup.execute( _execute ); \
+        }
+
+#else
+
+#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
+
+#endif /* PTE_CLEANUP_CXX */
+
+#endif /* PTE_CLEANUP_C */
+
+    /*
+     * ===============
+     * ===============
+     * Methods
+     * ===============
+     * ===============
+     */
+
+    int  pthread_init (void);
+    void  pthread_terminate (void);
+
+    /*
+     * PThread Attribute Functions
+     */
+    int  pthread_attr_init (pthread_attr_t * attr);
+
+    int  pthread_attr_destroy (pthread_attr_t * attr);
+
+    int  pthread_attr_getdetachstate (const pthread_attr_t * attr,
+                                      int *detachstate);
+
+    int  pthread_attr_getstackaddr (const pthread_attr_t * attr,
+                                    void **stackaddr);
+
+    int  pthread_attr_getstacksize (const pthread_attr_t * attr,
+                                    size_t * stacksize);
+
+    int  pthread_attr_setdetachstate (pthread_attr_t * attr,
+                                      int detachstate);
+
+    int  pthread_attr_setstackaddr (pthread_attr_t * attr,
+                                    void *stackaddr);
+
+    int  pthread_attr_setstacksize (pthread_attr_t * attr,
+                                    size_t stacksize);
+
+    int  pthread_attr_getschedparam (const pthread_attr_t *attr,
+                                     struct sched_param *param);
+
+    int  pthread_attr_setschedparam (pthread_attr_t *attr,
+                                     const struct sched_param *param);
+
+    int  pthread_attr_setschedpolicy (pthread_attr_t *,
+                                      int);
+
+    int  pthread_attr_getschedpolicy (pthread_attr_t *,
+                                      int *);
+
+    int  pthread_attr_setinheritsched(pthread_attr_t * attr,
+                                      int inheritsched);
+
+    int  pthread_attr_getinheritsched(pthread_attr_t * attr,
+                                      int * inheritsched);
+
+    int  pthread_attr_setscope (pthread_attr_t *,
+                                int);
+
+    int  pthread_attr_getscope (const pthread_attr_t *,
+                                int *);
+
+    /*
+     * PThread Functions
+     */
+    int  pthread_create (pthread_t * tid,
+                         const pthread_attr_t * attr,
+                         void *(*start) (void *),
+                         void *arg);
+
+    int  pthread_detach (pthread_t tid);
+
+    int  pthread_equal (pthread_t t1,
+                        pthread_t t2);
+
+    void  pthread_exit (void *value_ptr);
+
+    int  pthread_join (pthread_t thread,
+                       void **value_ptr);
+
+    pthread_t  pthread_self (void);
+
+    int  pthread_cancel (pthread_t thread);
+
+    int  pthread_setcancelstate (int state,
+                                 int *oldstate);
+
+    int  pthread_setcanceltype (int type,
+                                int *oldtype);
+
+    void  pthread_testcancel (void);
+
+    int  pthread_once (pthread_once_t * once_control,
+                       void (*init_routine) (void));
+
+#if PTE_LEVEL >= PTE_LEVEL_MAX
+    pte_cleanup_t *  pte_pop_cleanup (int execute);
+
+    void  pte_push_cleanup (pte_cleanup_t * cleanup,
+                            void (*routine) (void *),
+                            void *arg);
+#endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
+
+    /*
+     * Thread Specific Data Functions
+     */
+    int  pthread_key_create (pthread_key_t * key,
+                             void (*destructor) (void *));
+
+    int  pthread_key_delete (pthread_key_t key);
+
+    int  pthread_setspecific (pthread_key_t key,
+                              const void *value);
+
+    void *  pthread_getspecific (pthread_key_t key);
+
+
+    /*
+     * Mutex Attribute Functions
+     */
+    int  pthread_mutexattr_init (pthread_mutexattr_t * attr);
+
+    int  pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
+
+    int  pthread_mutexattr_getpshared (const pthread_mutexattr_t
+                                       * attr,
+                                       int *pshared);
+
+    int  pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
+                                       int pshared);
+
+    int  pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
+    int  pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
+
+    /*
+     * Barrier Attribute Functions
+     */
+    int  pthread_barrierattr_init (pthread_barrierattr_t * attr);
+
+    int  pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
+
+    int  pthread_barrierattr_getpshared (const pthread_barrierattr_t
+                                         * attr,
+                                         int *pshared);
+
+    int  pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
+                                         int pshared);
+
+    /*
+     * Mutex Functions
+     */
+    int  pthread_mutex_init (pthread_mutex_t * mutex,
+                             const pthread_mutexattr_t * attr);
+
+    int  pthread_mutex_destroy (pthread_mutex_t * mutex);
+
+    int  pthread_mutex_lock (pthread_mutex_t * mutex);
+
+    int  pthread_mutex_timedlock(pthread_mutex_t *mutex,
+                                 const struct timespec *abstime);
+
+    int  pthread_mutex_trylock (pthread_mutex_t * mutex);
+
+    int  pthread_mutex_unlock (pthread_mutex_t * mutex);
+
+    /*
+     * Spinlock Functions
+     */
+    int  pthread_spin_init (pthread_spinlock_t * lock, int pshared);
+
+    int  pthread_spin_destroy (pthread_spinlock_t * lock);
+
+    int  pthread_spin_lock (pthread_spinlock_t * lock);
+
+    int  pthread_spin_trylock (pthread_spinlock_t * lock);
+
+    int  pthread_spin_unlock (pthread_spinlock_t * lock);
+
+    /*
+     * Barrier Functions
+     */
+    int  pthread_barrier_init (pthread_barrier_t * barrier,
+                               const pthread_barrierattr_t * attr,
+                               unsigned int count);
+
+    int  pthread_barrier_destroy (pthread_barrier_t * barrier);
+
+    int  pthread_barrier_wait (pthread_barrier_t * barrier);
+
+    /*
+     * Condition Variable Attribute Functions
+     */
+    int  pthread_condattr_init (pthread_condattr_t * attr);
+
+    int  pthread_condattr_destroy (pthread_condattr_t * attr);
+
+    int  pthread_condattr_getpshared (const pthread_condattr_t * attr,
+                                      int *pshared);
+
+    int  pthread_condattr_setpshared (pthread_condattr_t * attr,
+                                      int pshared);
+
+    /*
+     * Condition Variable Functions
+     */
+    int  pthread_cond_init (pthread_cond_t * cond,
+                            const pthread_condattr_t * attr);
+
+    int  pthread_cond_destroy (pthread_cond_t * cond);
+
+    int  pthread_cond_wait (pthread_cond_t * cond,
+                            pthread_mutex_t * mutex);
+
+    int  pthread_cond_timedwait (pthread_cond_t * cond,
+                                 pthread_mutex_t * mutex,
+                                 const struct timespec *abstime);
+
+    int  pthread_cond_signal (pthread_cond_t * cond);
+
+    int  pthread_cond_broadcast (pthread_cond_t * cond);
+
+    /*
+     * Scheduling
+     */
+    int  pthread_setschedparam (pthread_t thread,
+                                int policy,
+                                const struct sched_param *param);
+
+    int  pthread_getschedparam (pthread_t thread,
+                                int *policy,
+                                struct sched_param *param);
+
+    int  pthread_setconcurrency (int);
+
+    int  pthread_getconcurrency (void);
+
+    /*
+     * Read-Write Lock Functions
+     */
+    int  pthread_rwlock_init(pthread_rwlock_t *lock,
+                             const pthread_rwlockattr_t *attr);
+
+    int  pthread_rwlock_destroy(pthread_rwlock_t *lock);
+
+    int  pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+
+    int  pthread_rwlock_trywrlock(pthread_rwlock_t *);
+
+    int  pthread_rwlock_rdlock(pthread_rwlock_t *lock);
+
+    int  pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
+                                    const struct timespec *abstime);
+
+    int  pthread_rwlock_wrlock(pthread_rwlock_t *lock);
+
+    int  pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
+                                    const struct timespec *abstime);
+
+    int  pthread_rwlock_unlock(pthread_rwlock_t *lock);
+
+    int  pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
+
+    int  pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
+
+    int  pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+                                        int *pshared);
+
+    int  pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
+                                        int pshared);
+
+#if PTE_LEVEL >= PTE_LEVEL_MAX - 1
+
+    /*
+     * Signal Functions. Should be defined in <signal.h> but we might
+     * already have signal.h that don't define these.
+     */
+    int  pthread_kill(pthread_t thread, int sig);
+
+    /*
+     * Non-portable functions
+     */
+
+    /*
+     * Compatibility with Linux.
+     */
+    int  pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
+                                      int kind);
+    int  pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
+                                      int *kind);
+
+    /*
+     * Possibly supported by other POSIX threads implementations
+     */
+    int  pthread_delay_np (struct timespec * interval);
+    int  pthread_num_processors_np(void);
+
+    /*
+     * Register a system time change with the library.
+     * Causes the library to perform various functions
+     * in response to the change. Should be called whenever
+     * the application's top level window receives a
+     * WM_TIMECHANGE message. It can be passed directly to
+     * pthread_create() as a new thread if desired.
+     */
+    void *  pthread_timechange_handler_np(void *);
+
+#endif /*PTE_LEVEL >= PTE_LEVEL_MAX - 1 */
+
+#if PTE_LEVEL >= PTE_LEVEL_MAX
+
+
+
+#endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
+
+    /*
+     * Some compiler environments don't define some things.
+     */
+#  define _ftime ftime
+#  define _timeb timeb
+
+#ifdef __cplusplus
+
+    /*
+     * Internal exceptions
+     */
+    class pte_exception {};
+    class pte_exception_cancel : public pte_exception {};
+    class pte_exception_exit   : public pte_exception {};
+
+#endif
+
+
+#ifndef PTE_BUILD
+
+#ifdef PTE_CLEANUP_CXX
+
+    /*
+     * Redefine the C++ catch keyword to ensure that applications
+     * propagate our internal exceptions up to the library's internal handlers.
+     */
+#define catch( E ) \
+        catch( pte_exception & ) { throw; } \
+        catch( E )
+
+#endif /* PTE_CLEANUP_CXX */
+
+#endif /* ! PTE_BUILD */
+
+#undef PTE_LEVEL
+#undef PTE_LEVEL_MAX
+
+#endif /* PTHREAD_H */

+ 87 - 0
pthread_attr_destroy.c

@@ -0,0 +1,87 @@
+/*
+ * pthread_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_destroy (pthread_attr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Destroys a thread attributes object.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ *      Destroys a thread attributes object.
+ *
+ *      NOTES:
+ *              1)      Does not affect threads created with 'attr'.
+ *
+ * RESULTS
+ *              0               successfully destroyed attr,
+ *              EINVAL          'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  /*
+   * Set the attribute object to a specific invalid value.
+   */
+  (*attr)->valid = 0;
+  free (*attr);
+  *attr = NULL;
+
+  return 0;
+}

+ 93 - 0
pthread_attr_getdetachstate.c

@@ -0,0 +1,93 @@
+/*
+ * pthread_attr_getdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_getdetachstate (const pthread_attr_t * attr, int *detachstate)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function determines whether threads created with
+ *      'attr' will run detached.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      detachstate
+ *              pointer to an integer into which is returned one
+ *              of:
+ *
+ *              PTHREAD_CREATE_JOINABLE
+ *                              Thread ID is valid, must be joined
+ *
+ *              PTHREAD_CREATE_DETACHED
+ *                              Thread ID is invalid, cannot be joined,
+ *                              canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ *      This function determines whether threads created with
+ *      'attr' will run detached.
+ *
+ *      NOTES:
+ *              1)      You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ *              0               successfully retrieved detach state,
+ *              EINVAL          'attr' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+  if (pte_is_attr (attr) != 0 || detachstate == NULL)
+    {
+      *detachstate = PTHREAD_CREATE_DETACHED;
+      return EINVAL;
+    }
+
+  *detachstate = (*attr)->detachstate;
+  return 0;
+}

+ 57 - 0
pthread_attr_getinheritsched.c

@@ -0,0 +1,57 @@
+/*
+ * pthread_attr_getinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getinheritsched (pthread_attr_t * attr, int *inheritsched)
+{
+  if (pte_is_attr (attr) != 0 || inheritsched == NULL)
+    {
+      return EINVAL;
+    }
+
+  *inheritsched = (*attr)->inheritsched;
+  return 0;
+}

+ 61 - 0
pthread_attr_getschedparam.c

@@ -0,0 +1,61 @@
+/*
+ * pthread_attr_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getschedparam (const pthread_attr_t * attr,
+                            struct sched_param *param)
+{
+  if (pte_is_attr (attr) != 0 || param == NULL)
+    {
+      return EINVAL;
+    }
+
+  memcpy (param, &(*attr)->param, sizeof (*param));
+  return 0;
+}

+ 67 - 0
pthread_attr_getschedpolicy.c

@@ -0,0 +1,67 @@
+/*
+ * pthread_attr_getschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_getschedpolicy (pthread_attr_t * attr, int *policy)
+{
+  if (pte_is_attr (attr) != 0 || policy == NULL)
+    {
+      return EINVAL;
+    }
+
+  /*
+   * Validate the policy arg.
+   * Check that a policy constant wasn't passed rather than &policy.
+   */
+  if (policy <= (int *) SCHED_MAX)
+    {
+      return EINVAL;
+    }
+
+  *policy = SCHED_OTHER;
+
+  return 0;
+}

+ 56 - 0
pthread_attr_getscope.c

@@ -0,0 +1,56 @@
+/*
+ * pthread_attr_getscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_getscope (const pthread_attr_t * attr, int *contentionscope)
+{
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+  *contentionscope = (*attr)->contentionscope;
+  return 0;
+#else
+  return ENOSYS;
+#endif
+}

+ 99 - 0
pthread_attr_getstackaddr.c

@@ -0,0 +1,99 @@
+/*
+ * pthread_attr_getstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_getstackaddr (const pthread_attr_t * attr, void **stackaddr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function determines the address of the stack
+ *      on which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      stackaddr
+ *              pointer into which is returned the stack address.
+ *
+ *
+ * DESCRIPTION
+ *      This function determines the address of the stack
+ *      on which threads created with 'attr' will run.
+ *
+ *      NOTES:
+ *              1)      Function supported only if this macro is
+ *                      defined:
+ *
+ *                              _POSIX_THREAD_ATTR_STACKADDR
+ *
+ *              2)      Create only one thread for each stack
+ *                      address..
+ *
+ * RESULTS
+ *              0               successfully retreived stack address,
+ *              EINVAL          'attr' is invalid
+ *              ENOSYS          function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  *stackaddr = (*attr)->stackaddr;
+  return 0;
+
+#else
+
+  return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}

+ 102 - 0
pthread_attr_getstacksize.c

@@ -0,0 +1,102 @@
+/*
+ * pthread_attr_getstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * stacksize)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function determines the size of the stack on
+ *      which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      stacksize
+ *              pointer to size_t into which is returned the
+ *              stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ *      This function determines the size of the stack on
+ *      which threads created with 'attr' will run.
+ *
+ *      NOTES:
+ *              1)      Function supported only if this macro is
+ *                      defined:
+ *
+ *                              _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ *              2)      Use on newly created attributes object to
+ *                      find the default stack size.
+ *
+ * RESULTS
+ *              0               successfully retrieved stack size,
+ *              EINVAL          'attr' is invalid
+ *              ENOSYS          function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  /* Everything is okay. */
+  *stacksize = (*attr)->stacksize;
+  return 0;
+
+#else
+
+  return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}

+ 119 - 0
pthread_attr_init.c

@@ -0,0 +1,119 @@
+/*
+ * pthread_attr_init.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_init (pthread_attr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Initializes a thread attributes object with default
+ *      attributes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *
+ * DESCRIPTION
+ *      Initializes a thread attributes object with default
+ *      attributes.
+ *
+ *      NOTES:
+ *              1)      Used to define thread attributes
+ *
+ * RESULTS
+ *              0               successfully initialized attr,
+ *              ENOMEM          insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+  pthread_attr_t attr_result;
+
+  if (attr == NULL)
+    {
+      /* This is disallowed. */
+      return EINVAL;
+    }
+
+  attr_result = (pthread_attr_t) malloc (sizeof (*attr_result));
+
+  if (attr_result == NULL)
+    {
+      return ENOMEM;
+    }
+
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+  /*
+   * Default to zero size?
+   */
+  attr_result->stacksize = 0;
+#endif
+
+#ifdef _POSIX_THREAD_ATTR_STACKADDR
+  /* FIXME: Set this to something sensible when we support it. */
+  attr_result->stackaddr = NULL;
+#endif
+
+  attr_result->detachstate = PTHREAD_CREATE_JOINABLE;
+
+  /*
+   * Win32 sets new threads to THREAD_PRIORITY_NORMAL and
+   * not to that of the parent thread. We choose to default to
+   * this arrangement.
+   */
+  attr_result->param.sched_priority = pte_osThreadGetDefaultPriority();
+  attr_result->inheritsched = PTHREAD_EXPLICIT_SCHED;
+  attr_result->contentionscope = PTHREAD_SCOPE_SYSTEM;
+
+  attr_result->valid = PTE_ATTR_VALID;
+
+  *attr = attr_result;
+
+  return 0;
+}

+ 97 - 0
pthread_attr_setdetachstate.c

@@ -0,0 +1,97 @@
+/*
+ * pthread_attr_setdetachstate.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function specifies whether threads created with
+ *      'attr' will run detached.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      detachstate
+ *              an integer containing one of:
+ *
+ *              PTHREAD_CREATE_JOINABLE
+ *                              Thread ID is valid, must be joined
+ *
+ *              PTHREAD_CREATE_DETACHED
+ *                              Thread ID is invalid, cannot be joined,
+ *                              canceled, or modified
+ *
+ *
+ * DESCRIPTION
+ *      This function specifies whether threads created with
+ *      'attr' will run detached.
+ *
+ *      NOTES:
+ *              1)      You cannot join or cancel detached threads.
+ *
+ * RESULTS
+ *              0               successfully set detach state,
+ *              EINVAL          'attr' or 'detachstate' is invalid
+ *
+ * ------------------------------------------------------
+ */
+{
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  if (detachstate != PTHREAD_CREATE_JOINABLE &&
+      detachstate != PTHREAD_CREATE_DETACHED)
+    {
+      return EINVAL;
+    }
+
+  (*attr)->detachstate = detachstate;
+  return 0;
+}

+ 63 - 0
pthread_attr_setinheritsched.c

@@ -0,0 +1,63 @@
+/*
+ * pthread_attr_setinheritsched.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setinheritsched (pthread_attr_t * attr, int inheritsched)
+{
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  if (PTHREAD_INHERIT_SCHED != inheritsched
+      && PTHREAD_EXPLICIT_SCHED != inheritsched)
+    {
+      return EINVAL;
+    }
+
+  (*attr)->inheritsched = inheritsched;
+  return 0;
+}

+ 72 - 0
pthread_attr_setschedparam.c

@@ -0,0 +1,72 @@
+/*
+ * pthread_attr_setschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setschedparam (pthread_attr_t * attr,
+                            const struct sched_param *param)
+{
+  int priority;
+
+  if (pte_is_attr (attr) != 0 || param == NULL)
+    {
+      return EINVAL;
+    }
+
+  priority = param->sched_priority;
+
+  /* Validate priority level. */
+  if (priority < sched_get_priority_min (SCHED_OTHER) ||
+      priority > sched_get_priority_max (SCHED_OTHER))
+    {
+      return EINVAL;
+    }
+
+  memcpy (&(*attr)->param, param, sizeof (*param));
+  return 0;
+}

+ 61 - 0
pthread_attr_setschedpolicy.c

@@ -0,0 +1,61 @@
+/*
+ * pthread_attr_setschedpolicy.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_attr_setschedpolicy (pthread_attr_t * attr, int policy)
+{
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  if (policy != SCHED_OTHER)
+    {
+      return ENOTSUP;
+    }
+
+  return 0;
+}

+ 64 - 0
pthread_attr_setscope.c

@@ -0,0 +1,64 @@
+/*
+ * pthread_attr_setscope.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setscope (pthread_attr_t * attr, int contentionscope)
+{
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+  switch (contentionscope)
+    {
+    case PTHREAD_SCOPE_SYSTEM:
+      (*attr)->contentionscope = contentionscope;
+      return 0;
+    case PTHREAD_SCOPE_PROCESS:
+      return ENOTSUP;
+    default:
+      return EINVAL;
+    }
+#else
+  return ENOSYS;
+#endif
+}

+ 103 - 0
pthread_attr_setstackaddr.c

@@ -0,0 +1,103 @@
+/*
+ * pthread_attr_setstackaddr.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setstackaddr (pthread_attr_t * attr, void *stackaddr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Threads created with 'attr' will run on the stack
+ *      starting at 'stackaddr'.
+ *      Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      stacksize
+ *              stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ *      Threads created with 'attr' will run on the stack
+ *      starting at 'stackaddr'.
+ *      Stack must be at least PTHREAD_STACK_MIN bytes.
+ *
+ *      NOTES:
+ *              1)      Function supported only if this macro is
+ *                      defined:
+ *
+ *                              _POSIX_THREAD_ATTR_STACKADDR
+ *
+ *              2)      Create only one thread for each stack
+ *                      address..
+ *
+ *              3)      Ensure that stackaddr is aligned.
+ *
+ * RESULTS
+ *              0               successfully set stack address,
+ *              EINVAL          'attr' is invalid
+ *              ENOSYS          function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#if defined( _POSIX_THREAD_ATTR_STACKADDR )
+
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  (*attr)->stackaddr = stackaddr;
+  return 0;
+
+#else
+
+  return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKADDR */
+}

+ 116 - 0
pthread_attr_setstacksize.c

@@ -0,0 +1,116 @@
+/*
+ * pthread_attr_setstacksize.c
+ *
+ * Description:
+ * This translation unit implements operations on thread attribute objects.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_attr_setstacksize (pthread_attr_t * attr, size_t stacksize)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function specifies the size of the stack on
+ *      which threads created with 'attr' will run.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_attr_t
+ *
+ *      stacksize
+ *              stack size, in bytes.
+ *
+ *
+ * DESCRIPTION
+ *      This function specifies the size of the stack on
+ *      which threads created with 'attr' will run.
+ *
+ *      NOTES:
+ *              1)      Function supported only if this macro is
+ *                      defined:
+ *
+ *                              _POSIX_THREAD_ATTR_STACKSIZE
+ *
+ *              2)      Find the default first (using
+ *                      pthread_attr_getstacksize), then increase
+ *                      by multiplying.
+ *
+ *              3)      Only use if thread needs more than the
+ *                      default.
+ *
+ * RESULTS
+ *              0               successfully set stack size,
+ *              EINVAL          'attr' is invalid or stacksize too
+ *                              small or too big.
+ *              ENOSYS          function not supported
+ *
+ * ------------------------------------------------------
+ */
+{
+#ifdef _POSIX_THREAD_ATTR_STACKSIZE
+
+#if PTHREAD_STACK_MIN > 0
+
+  /*  Verify that the stack size is within range. */
+  if (stacksize < PTHREAD_STACK_MIN)
+    {
+      return EINVAL;
+    }
+
+#endif
+
+  if (pte_is_attr (attr) != 0)
+    {
+      return EINVAL;
+    }
+
+  /* Everything is okay. */
+  (*attr)->stacksize = stacksize;
+  return 0;
+
+#else
+
+  return ENOSYS;
+
+#endif /* _POSIX_THREAD_ATTR_STACKSIZE */
+
+}

+ 75 - 0
pthread_barrier_destroy.c

@@ -0,0 +1,75 @@
+/*
+ * pthread_barrier_destroy.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrier_destroy (pthread_barrier_t * barrier)
+{
+  int result = 0;
+  pthread_barrier_t b;
+
+  if (barrier == NULL || *barrier == (pthread_barrier_t) PTE_OBJECT_INVALID)
+    {
+      return EINVAL;
+    }
+
+  b = *barrier;
+  *barrier = NULL;
+
+  if (0 == (result = sem_destroy (&(b->semBarrierBreeched[0]))))
+    {
+      if (0 == (result = sem_destroy (&(b->semBarrierBreeched[1]))))
+        {
+          (void) free (b);
+          return 0;
+        }
+      (void) sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0);
+    }
+
+  *barrier = b;
+  return (result);
+}

+ 89 - 0
pthread_barrier_init.c

@@ -0,0 +1,89 @@
+/*
+ * pthread_barrier_init.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrier_init (pthread_barrier_t * barrier,
+                      const pthread_barrierattr_t * attr, unsigned int count)
+{
+  pthread_barrier_t b;
+
+  if (barrier == NULL || count == 0)
+    {
+      return EINVAL;
+    }
+
+  if (NULL != (b = (pthread_barrier_t) calloc (1, sizeof (*b))))
+    {
+      b->pshared = (attr != NULL && *attr != NULL
+                    ? (*attr)->pshared : PTHREAD_PROCESS_PRIVATE);
+
+      b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count;
+      b->iStep = 0;
+
+      /*
+       * Two semaphores are used in the same way as two stepping
+       * stones might be used in crossing a stream. Once all
+       * threads are safely on one stone, the other stone can
+       * be moved ahead, and the threads can start moving to it.
+       * If some threads decide to eat their lunch before moving
+       * then the other threads have to wait.
+       */
+      if (0 == sem_init (&(b->semBarrierBreeched[0]), b->pshared, 0))
+        {
+          if (0 == sem_init (&(b->semBarrierBreeched[1]), b->pshared, 0))
+            {
+              *barrier = b;
+              return 0;
+            }
+          (void) sem_destroy (&(b->semBarrierBreeched[0]));
+        }
+      (void) free (b);
+    }
+
+  return ENOMEM;
+}

+ 101 - 0
pthread_barrier_wait.c

@@ -0,0 +1,101 @@
+/*
+ * pthread_barrier_wait.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrier_wait (pthread_barrier_t * barrier)
+{
+  int result;
+  int step;
+  pthread_barrier_t b;
+
+  if (barrier == NULL || *barrier == (pthread_barrier_t) PTE_OBJECT_INVALID)
+    {
+      return EINVAL;
+    }
+
+  b = *barrier;
+  step = b->iStep;
+
+  if (0 == PTE_ATOMIC_DECREMENT ((int *) &(b->nCurrentBarrierHeight)))
+    {
+      /* Must be done before posting the semaphore. */
+      b->nCurrentBarrierHeight = b->nInitialBarrierHeight;
+
+      /*
+       * There is no race condition between the semaphore wait and post
+       * because we are using two alternating semas and all threads have
+       * entered barrier_wait and checked nCurrentBarrierHeight before this
+       * barrier's sema can be posted. Any threads that have not quite
+       * entered sem_wait below when the multiple_post has completed
+       * will nevertheless continue through the semaphore (barrier)
+       * and will not be left stranded.
+       */
+      result = (b->nInitialBarrierHeight > 1
+                ? sem_post_multiple (&(b->semBarrierBreeched[step]),
+                                     b->nInitialBarrierHeight - 1) : 0);
+    }
+  else
+    {
+      /*
+       * Use the non-cancelable version of sem_wait().
+       */
+      result = sem_wait (&(b->semBarrierBreeched[step]));
+//      result = sem_wait_nocancel (&(b->semBarrierBreeched[step]));
+    }
+
+  /*
+   * The first thread across will be the PTHREAD_BARRIER_SERIAL_THREAD.
+   * This also sets up the alternate semaphore as the next barrier.
+   */
+  if (0 == result)
+    {
+      result = (step ==
+                PTE_ATOMIC_COMPARE_EXCHANGE (& (b->iStep),(1L - step),step) ?
+                PTHREAD_BARRIER_SERIAL_THREAD : 0);
+    }
+
+  return (result);
+}

+ 91 - 0
pthread_barrierattr_destroy.c

@@ -0,0 +1,91 @@
+/*
+ * pthread_barrier_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_destroy (pthread_barrierattr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Destroys a barrier attributes object. The object can
+ *      no longer be used.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ *      Destroys a barrier attributes object. The object can
+ *      no longer be used.
+ *
+ *      NOTES:
+ *              1)      Does not affect barrieres created using 'attr'
+ *
+ * RESULTS
+ *              0               successfully released attr,
+ *              EINVAL          'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result = 0;
+
+  if (attr == NULL || *attr == NULL)
+    {
+      result = EINVAL;
+    }
+  else
+    {
+      pthread_barrierattr_t ba = *attr;
+
+      *attr = NULL;
+      free (ba);
+    }
+
+  return (result);
+}				/* pthread_barrierattr_destroy */

+ 101 - 0
pthread_barrierattr_getpshared.c

@@ -0,0 +1,101 @@
+/*
+ * pthread_barrier_attr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_getpshared (const pthread_barrierattr_t * attr,
+                                int *pshared)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Determine whether barriers created with 'attr' can be
+ *      shared between processes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_barrierattr_t
+ *
+ *      pshared
+ *              will be set to one of:
+ *
+ *                      PTHREAD_PROCESS_SHARED
+ *                              May be shared if in shared memory
+ *
+ *                      PTHREAD_PROCESS_PRIVATE
+ *                              Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ *      Mutexes creatd with 'attr' can be shared between
+ *      processes if pthread_barrier_t variable is allocated
+ *      in memory shared by these processes.
+ *      NOTES:
+ *              1)      pshared barriers MUST be allocated in shared
+ *                      memory.
+ *              2)      The following macro is defined if shared barriers
+ *                      are supported:
+ *                              _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ *              0               successfully retrieved attribute,
+ *              EINVAL          'attr' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+
+  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+    {
+      *pshared = (*attr)->pshared;
+      result = 0;
+    }
+  else
+    {
+      result = EINVAL;
+    }
+
+  return (result);
+}				/* pthread_barrierattr_getpshared */

+ 93 - 0
pthread_barrierattr_init.c

@@ -0,0 +1,93 @@
+/*
+ * pthread_barrier_attr_init.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_init (pthread_barrierattr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Initializes a barrier attributes object with default
+ *      attributes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_barrierattr_t
+ *
+ *
+ * DESCRIPTION
+ *      Initializes a barrier attributes object with default
+ *      attributes.
+ *
+ *      NOTES:
+ *              1)      Used to define barrier types
+ *
+ * RESULTS
+ *              0               successfully initialized attr,
+ *              ENOMEM          insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+  pthread_barrierattr_t ba;
+  int result = 0;
+
+  ba = (pthread_barrierattr_t) calloc (1, sizeof (*ba));
+
+  if (ba == NULL)
+    {
+      result = ENOMEM;
+    }
+  else
+    {
+      ba->pshared = PTHREAD_PROCESS_PRIVATE;
+    }
+
+  *attr = ba;
+
+  return (result);
+}				/* pthread_barrierattr_init */

+ 125 - 0
pthread_barrierattr_setpshared.c

@@ -0,0 +1,125 @@
+/*
+ * pthread_barrier_attr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements barrier primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, int pshared)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Barriers created with 'attr' can be shared between
+ *      processes if pthread_barrier_t variable is allocated
+ *      in memory shared by these processes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_barrierattr_t
+ *
+ *      pshared
+ *              must be one of:
+ *
+ *                      PTHREAD_PROCESS_SHARED
+ *                              May be shared if in shared memory
+ *
+ *                      PTHREAD_PROCESS_PRIVATE
+ *                              Cannot be shared.
+ *
+ * DESCRIPTION
+ *      Mutexes creatd with 'attr' can be shared between
+ *      processes if pthread_barrier_t variable is allocated
+ *      in memory shared by these processes.
+ *
+ *      NOTES:
+ *              1)      pshared barriers MUST be allocated in shared
+ *                      memory.
+ *
+ *              2)      The following macro is defined if shared barriers
+ *                      are supported:
+ *                              _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ *              0               successfully set attribute,
+ *              EINVAL          'attr' or pshared is invalid,
+ *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+
+  if ((attr != NULL && *attr != NULL) &&
+      ((pshared == PTHREAD_PROCESS_SHARED) ||
+       (pshared == PTHREAD_PROCESS_PRIVATE)))
+    {
+      if (pshared == PTHREAD_PROCESS_SHARED)
+        {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+
+          result = ENOSYS;
+          pshared = PTHREAD_PROCESS_PRIVATE;
+
+#else
+
+          result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+        }
+      else
+        {
+          result = 0;
+        }
+
+      (*attr)->pshared = pshared;
+    }
+  else
+    {
+      result = EINVAL;
+    }
+
+  return (result);
+
+}				/* pthread_barrierattr_setpshared */

+ 173 - 0
pthread_cancel.c

@@ -0,0 +1,173 @@
+/*
+ * pthread_cancel.c
+ *
+ * Description:
+ * POSIX thread functions related to thread cancellation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include <stdio.h>
+
+int
+pthread_cancel (pthread_t thread)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function requests cancellation of 'thread'.
+ *
+ * PARAMETERS
+ *      thread
+ *              reference to an instance of pthread_t
+ *
+ *
+ * DESCRIPTION
+ *      This function requests cancellation of 'thread'.
+ *      NOTE: cancellation is asynchronous; use pthread_join to
+ *                wait for termination of 'thread' if necessary.
+ *
+ * RESULTS
+ *              0               successfully requested cancellation,
+ *              ESRCH           no thread found corresponding to 'thread',
+ *              ENOMEM          implicit self thread create failed.
+ * ------------------------------------------------------
+ */
+{
+  int result;
+  int cancel_self;
+  pthread_t self;
+  pte_thread_t * tp;
+
+  result = pthread_kill (thread, 0);
+
+  if (0 != result)
+    {
+      return result;
+    }
+
+  if ((self = pthread_self ()).p == NULL)
+    {
+      return ENOMEM;
+    };
+
+  /*
+   * FIXME!!
+   *
+   * Can a thread cancel itself?
+   *
+   * The standard doesn't
+   * specify an error to be returned if the target
+   * thread is itself.
+   *
+   * If it may, then we need to ensure that a thread can't
+   * deadlock itself trying to cancel itself asyncronously
+   * (pthread_cancel is required to be an async-cancel
+   * safe function).
+   */
+  cancel_self = pthread_equal (thread, self);
+
+  tp = (pte_thread_t *) thread.p;
+
+  /*
+   * Lock for async-cancel safety.
+   */
+  (void) pthread_mutex_lock (&tp->cancelLock);
+
+  if (tp->cancelType == PTHREAD_CANCEL_ASYNCHRONOUS
+      && tp->cancelState == PTHREAD_CANCEL_ENABLE
+      && tp->state < PThreadStateCanceling)
+    {
+      if (cancel_self)
+        {
+          tp->state = PThreadStateCanceling;
+          tp->cancelState = PTHREAD_CANCEL_DISABLE;
+
+          (void) pthread_mutex_unlock (&tp->cancelLock);
+          pte_throw (PTE_EPS_CANCEL);
+
+          /* Never reached */
+        }
+      else
+        {
+          /*
+           * We don't support asynchronous cancellation for thread other than ourselves.
+           * as it requires significant platform and OS specific functionality (see below).
+           *
+           * We should never get here, as we don't allow the cancellability type to be
+           * sent to async.
+           *
+           * If you really wanted to implement async cancellation, you would probably need to
+           * do something like the Win32 implement did, which is:
+           *   1. Suspend the target thread.
+           *   2. Replace the PC for the target thread to a routine that throws an exception
+           *      or does a longjmp, depending on cleanup method.
+           *   3. Resume the target thread.
+           *
+           * Note that most of the async cancellation code is still in here if anyone
+           * wanted to add the OS/platform specific stuff.
+           */
+          (void) pthread_mutex_unlock (&tp->cancelLock);
+
+          result = EPERM;
+
+        }
+    }
+  else
+    {
+      /*
+       * Set for deferred cancellation.
+       */
+      if (tp->state < PThreadStateCancelPending)
+        {
+          tp->state = PThreadStateCancelPending;
+
+          if (pte_osThreadCancel(tp->threadId) != PTE_OS_OK)
+            {
+              result = ESRCH;
+            }
+        }
+      else if (tp->state >= PThreadStateCanceling)
+        {
+          result = ESRCH;
+        }
+
+      (void) pthread_mutex_unlock (&tp->cancelLock);
+    }
+
+  return (result);
+}

+ 256 - 0
pthread_cond_destroy.c

@@ -0,0 +1,256 @@
+/*
+ * pthread_cond_destroy.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_cond_destroy (pthread_cond_t * cond)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function destroys a condition variable
+ *
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ *      This function destroys a condition variable.
+ *
+ *      NOTES:
+ *              1)      A condition variable can be destroyed
+ *                      immediately after all the threads that
+ *                      are blocked on it are awakened. e.g.
+ *
+ *                      struct list {
+ *                        pthread_mutex_t lm;
+ *                        ...
+ *                      }
+ *
+ *                      struct elt {
+ *                        key k;
+ *                        int busy;
+ *                        pthread_cond_t notbusy;
+ *                        ...
+ *                      }
+ *
+ *
+ *                      struct elt *
+ *                      list_find(struct list *lp, key k)
+ *                      {
+ *                        struct elt *ep;
+ *
+ *                        pthread_mutex_lock(&lp->lm);
+ *                        while ((ep = find_elt(l,k) != NULL) && ep->busy)
+ *                          pthread_cond_wait(&ep->notbusy, &lp->lm);
+ *                        if (ep != NULL)
+ *                          ep->busy = 1;
+ *                        pthread_mutex_unlock(&lp->lm);
+ *                        return(ep);
+ *                      }
+ *
+ *                      delete_elt(struct list *lp, struct elt *ep)
+ *                      {
+ *                        pthread_mutex_lock(&lp->lm);
+ *                        assert(ep->busy);
+ *                        ... remove ep from list ...
+ *                        ep->busy = 0;
+ *                    (A) pthread_cond_broadcast(&ep->notbusy);
+ *                        pthread_mutex_unlock(&lp->lm);
+ *                    (B) pthread_cond_destroy(&rp->notbusy);
+ *                        free(ep);
+ *                      }
+ *
+ *                      In this example, the condition variable
+ *                      and its list element may be freed (line B)
+ *                      immediately after all threads waiting for
+ *                      it are awakened (line A), since the mutex
+ *                      and the code ensure that no other thread
+ *                      can touch the element to be deleted.
+ *
+ * RESULTS
+ *              0               successfully released condition variable,
+ *              EINVAL          'cond' is invalid,
+ *              EBUSY           'cond' is in use,
+ *
+ * ------------------------------------------------------
+ */
+{
+  pthread_cond_t cv;
+  int result = 0, result1 = 0, result2 = 0;
+
+  /*
+   * Assuming any race condition here is harmless.
+   */
+  if (cond == NULL || *cond == NULL)
+    {
+      return EINVAL;
+    }
+
+  if (*cond != PTHREAD_COND_INITIALIZER)
+    {
+
+      pte_osMutexLock (pte_cond_list_lock);
+
+      cv = *cond;
+
+      /*
+       * Close the gate; this will synchronize this thread with
+       * all already signaled waiters to let them retract their
+       * waiter status - SEE NOTE 1 ABOVE!!!
+       */
+      if (sem_wait (&(cv->semBlockLock)) != 0)
+        {
+          return errno;
+        }
+
+      /*
+       * !TRY! lock mtxUnblockLock; try will detect busy condition
+       * and will not cause a deadlock with respect to concurrent
+       * signal/broadcast.
+       */
+      if ((result = pthread_mutex_trylock (&(cv->mtxUnblockLock))) != 0)
+        {
+          (void) sem_post (&(cv->semBlockLock));
+          return result;
+        }
+
+      /*
+       * Check whether cv is still busy (still has waiters)
+       */
+      if (cv->nWaitersBlocked > cv->nWaitersGone)
+        {
+          if (sem_post (&(cv->semBlockLock)) != 0)
+            {
+              result = errno;
+            }
+          result1 = pthread_mutex_unlock (&(cv->mtxUnblockLock));
+          result2 = EBUSY;
+        }
+      else
+        {
+          /*
+           * Now it is safe to destroy
+           */
+          *cond = NULL;
+
+          if (sem_destroy (&(cv->semBlockLock)) != 0)
+            {
+              result = errno;
+            }
+          if (sem_destroy (&(cv->semBlockQueue)) != 0)
+            {
+              result1 = errno;
+            }
+          if ((result2 = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
+            {
+              result2 = pthread_mutex_destroy (&(cv->mtxUnblockLock));
+            }
+
+          /* Unlink the CV from the list */
+
+          if (pte_cond_list_head == cv)
+            {
+              pte_cond_list_head = cv->next;
+            }
+          else
+            {
+              cv->prev->next = cv->next;
+            }
+
+          if (pte_cond_list_tail == cv)
+            {
+              pte_cond_list_tail = cv->prev;
+            }
+          else
+            {
+              cv->next->prev = cv->prev;
+            }
+
+          (void) free (cv);
+        }
+
+      pte_osMutexUnlock(pte_cond_list_lock);
+
+    }
+  else
+    {
+      /*
+       * See notes in pte_cond_check_need_init() above also.
+       */
+
+      pte_osMutexLock (pte_cond_test_init_lock);
+
+      /*
+       * Check again.
+       */
+      if (*cond == PTHREAD_COND_INITIALIZER)
+        {
+          /*
+           * This is all we need to do to destroy a statically
+           * initialised cond that has not yet been used (initialised).
+           * If we get to here, another thread waiting to initialise
+           * this cond will get an EINVAL. That's OK.
+           */
+          *cond = NULL;
+        }
+      else
+        {
+          /*
+           * The cv has been initialised while we were waiting
+           * so assume it's in use.
+           */
+          result = EBUSY;
+        }
+
+      pte_osMutexUnlock(pte_cond_test_init_lock);
+    }
+
+  return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));
+}

+ 174 - 0
pthread_cond_init.c

@@ -0,0 +1,174 @@
+/*
+ * pthread_cond_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function initializes a condition variable.
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *      attr
+ *              specifies optional creation attributes.
+ *
+ *
+ * DESCRIPTION
+ *      This function initializes a condition variable.
+ *
+ * RESULTS
+ *              0               successfully created condition variable,
+ *              EINVAL          'attr' is invalid,
+ *              EAGAIN          insufficient resources (other than
+ *                              memory,
+ *              ENOMEM          insufficient memory,
+ *              EBUSY           'cond' is already initialized,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+  pthread_cond_t cv = NULL;
+
+  if (cond == NULL)
+    {
+      return EINVAL;
+    }
+
+  if ((attr != NULL && *attr != NULL) &&
+      ((*attr)->pshared == PTHREAD_PROCESS_SHARED))
+    {
+      /*
+       * Creating condition variable that can be shared between
+       * processes.
+       */
+      result = ENOSYS;
+      goto DONE;
+    }
+
+  cv = (pthread_cond_t) calloc (1, sizeof (*cv));
+
+  if (cv == NULL)
+    {
+      result = ENOMEM;
+      goto DONE;
+    }
+
+  cv->nWaitersBlocked = 0;
+  cv->nWaitersToUnblock = 0;
+  cv->nWaitersGone = 0;
+
+  if (sem_init (&(cv->semBlockLock), 0, 1) != 0)
+    {
+      result = errno;
+      goto FAIL0;
+    }
+
+  if (sem_init (&(cv->semBlockQueue), 0, 0) != 0)
+    {
+      result = errno;
+      goto FAIL1;
+    }
+
+  if ((result = pthread_mutex_init (&(cv->mtxUnblockLock), 0)) != 0)
+    {
+      goto FAIL2;
+    }
+
+  result = 0;
+
+  goto DONE;
+
+  /*
+   * -------------
+   * Failed...
+   * -------------
+   */
+FAIL2:
+  (void) sem_destroy (&(cv->semBlockQueue));
+
+FAIL1:
+  (void) sem_destroy (&(cv->semBlockLock));
+
+FAIL0:
+  (void) free (cv);
+  cv = NULL;
+
+DONE:
+  if (0 == result)
+    {
+
+      pte_osMutexLock (pte_cond_list_lock);
+
+      cv->next = NULL;
+      cv->prev = pte_cond_list_tail;
+
+      if (pte_cond_list_tail != NULL)
+        {
+          pte_cond_list_tail->next = cv;
+        }
+
+      pte_cond_list_tail = cv;
+
+      if (pte_cond_list_head == NULL)
+        {
+          pte_cond_list_head = cv;
+        }
+
+      pte_osMutexUnlock(pte_cond_list_lock);
+    }
+
+  *cond = cv;
+
+  return result;
+
+}				/* pthread_cond_init */

+ 238 - 0
pthread_cond_signal.c

@@ -0,0 +1,238 @@
+/*
+ * pthread_cond_signal.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * See the comments at the top of pthread_cond_wait.c.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+static int
+pte_cond_unblock (pthread_cond_t * cond, int unblockAll)
+/*
+ * Notes.
+ *
+ * Does not use the external mutex for synchronisation,
+ * therefore semBlockLock is needed.
+ * mtxUnblockLock is for LEVEL-2 synch. LEVEL-2 is the
+ * state where the external mutex is not necessarily locked by
+ * any thread, ie. between cond_wait unlocking and re-acquiring
+ * the lock after having been signaled or a timeout or
+ * cancellation.
+ *
+ * Uses the following CV elements:
+ *   nWaitersBlocked
+ *   nWaitersToUnblock
+ *   nWaitersGone
+ *   mtxUnblockLock
+ *   semBlockLock
+ *   semBlockQueue
+ */
+{
+  int result;
+  pthread_cond_t cv;
+  int nSignalsToIssue;
+
+  if (cond == NULL || *cond == NULL)
+    {
+      return EINVAL;
+    }
+
+  cv = *cond;
+
+  /*
+   * No-op if the CV is static and hasn't been initialised yet.
+   * Assuming that any race condition is harmless.
+   */
+  if (cv == PTHREAD_COND_INITIALIZER)
+    {
+      return 0;
+    }
+
+  if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+    {
+      return result;
+    }
+
+  if (0 != cv->nWaitersToUnblock)
+    {
+      if (0 == cv->nWaitersBlocked)
+        {
+          return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+        }
+      if (unblockAll)
+        {
+          cv->nWaitersToUnblock += (nSignalsToIssue = cv->nWaitersBlocked);
+          cv->nWaitersBlocked = 0;
+        }
+      else
+        {
+          nSignalsToIssue = 1;
+          cv->nWaitersToUnblock++;
+          cv->nWaitersBlocked--;
+        }
+    }
+  else if (cv->nWaitersBlocked > cv->nWaitersGone)
+    {
+      /* Use the non-cancellable version of sem_wait() */
+//      if (sem_wait_nocancel (&(cv->semBlockLock)) != 0)
+      if (sem_wait (&(cv->semBlockLock)) != 0)
+        {
+          result = errno;
+          (void) pthread_mutex_unlock (&(cv->mtxUnblockLock));
+          return result;
+        }
+      if (0 != cv->nWaitersGone)
+        {
+          cv->nWaitersBlocked -= cv->nWaitersGone;
+          cv->nWaitersGone = 0;
+        }
+      if (unblockAll)
+        {
+          nSignalsToIssue = cv->nWaitersToUnblock = cv->nWaitersBlocked;
+          cv->nWaitersBlocked = 0;
+        }
+      else
+        {
+          nSignalsToIssue = cv->nWaitersToUnblock = 1;
+          cv->nWaitersBlocked--;
+        }
+    }
+  else
+    {
+      return pthread_mutex_unlock (&(cv->mtxUnblockLock));
+    }
+
+  if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) == 0)
+    {
+      if (sem_post_multiple (&(cv->semBlockQueue), nSignalsToIssue) != 0)
+        {
+          result = errno;
+        }
+    }
+
+  return result;
+
+}				/* pte_cond_unblock */
+
+int
+pthread_cond_signal (pthread_cond_t * cond)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function signals a condition variable, waking
+ *      one waiting thread.
+ *      If SCHED_FIFO or SCHED_RR policy threads are waiting
+ *      the highest priority waiter is awakened; otherwise,
+ *      an unspecified waiter is awakened.
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ *      This function signals a condition variable, waking
+ *      one waiting thread.
+ *      If SCHED_FIFO or SCHED_RR policy threads are waiting
+ *      the highest priority waiter is awakened; otherwise,
+ *      an unspecified waiter is awakened.
+ *
+ *      NOTES:
+ *
+ *      1)      Use when any waiter can respond and only one need
+ *              respond (all waiters being equal).
+ *
+ * RESULTS
+ *              0               successfully signaled condition,
+ *              EINVAL          'cond' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+  /*
+   * The '0'(FALSE) unblockAll arg means unblock ONE waiter.
+   */
+  return (pte_cond_unblock (cond, 0));
+
+}				/* pthread_cond_signal */
+
+int
+pthread_cond_broadcast (pthread_cond_t * cond)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function broadcasts the condition variable,
+ *      waking all current waiters.
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *
+ * DESCRIPTION
+ *      This function signals a condition variable, waking
+ *      all waiting threads.
+ *
+ *      NOTES:
+ *
+ *      1)      Use when more than one waiter may respond to
+ *              predicate change or if any waiting thread may
+ *              not be able to respond
+ *
+ * RESULTS
+ *              0               successfully signalled condition to all
+ *                              waiting threads,
+ *              EINVAL          'cond' is invalid
+ *              ENOSPC          a required resource has been exhausted,
+ *
+ * ------------------------------------------------------
+ */
+{
+  /*
+   * The TRUE unblockAll arg means unblock ALL waiters.
+   */
+  return (pte_cond_unblock (cond, PTE_TRUE));
+
+}				/* pthread_cond_broadcast */

+ 568 - 0
pthread_cond_wait.c

@@ -0,0 +1,568 @@
+/*
+ * pthread_cond_wait.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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
+ *
+ * -------------------------------------------------------------
+ * Algorithm:
+ * The algorithm used in this implementation is that developed by
+ * Alexander Terekhov in colaboration with Louis Thomas. The bulk
+ * of the discussion is recorded in the file README.CV, which contains
+ * several generations of both colaborators original algorithms. The final
+ * algorithm used here is the one referred to as
+ *
+ *     Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code as it appeared:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ *   [auto: register int result          ]     // error checking omitted
+ *   [auto: register int nSignalsWasLeft ]
+ *   [auto: register int nWaitersWasGone ]
+ *
+ *   sem_wait( semBlockLock );
+ *   nWaitersBlocked++;
+ *   sem_post( semBlockLock );
+ *
+ *   unlock( mtxExternal );
+ *   bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ *   lock( mtxUnblockLock );
+ *   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ *     if ( bTimeout ) {                       // timeout (or canceled)
+ *       if ( 0 != nWaitersBlocked ) {
+ *         nWaitersBlocked--;
+ *       }
+ *       else {
+ *         nWaitersGone++;                     // count spurious wakeups.
+ *       }
+ *     }
+ *     if ( 0 == --nWaitersToUnblock ) {
+ *       if ( 0 != nWaitersBlocked ) {
+ *         sem_post( semBlockLock );           // open the gate.
+ *         nSignalsWasLeft = 0;                // do not open the gate
+ *                                             // below again.
+ *       }
+ *       else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+ *         nWaitersGone = 0;
+ *       }
+ *     }
+ *   }
+ *   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ *                                             // spurious semaphore :-)
+ *     sem_wait( semBlockLock );
+ *     nWaitersBlocked -= nWaitersGone;     // something is going on here
+ *                                          //  - test of timeouts? :-)
+ *     sem_post( semBlockLock );
+ *     nWaitersGone = 0;
+ *   }
+ *   unlock( mtxUnblockLock );
+ *
+ *   if ( 1 == nSignalsWasLeft ) {
+ *     if ( 0 != nWaitersWasGone ) {
+ *       // sem_adjust( semBlockQueue,-nWaitersWasGone );
+ *       while ( nWaitersWasGone-- ) {
+ *         sem_wait( semBlockQueue );       // better now than spurious later
+ *       }
+ *     } sem_post( semBlockLock );          // open the gate
+ *   }
+ *
+ *   lock( mtxExternal );
+ *
+ *   return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ *   [auto: register int result         ]
+ *   [auto: register int nSignalsToIssue]
+ *
+ *   lock( mtxUnblockLock );
+ *
+ *   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
+ *     if ( 0 == nWaitersBlocked ) {        // NO-OP
+ *       return unlock( mtxUnblockLock );
+ *     }
+ *     if (bAll) {
+ *       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ *       nWaitersBlocked = 0;
+ *     }
+ *     else {
+ *       nSignalsToIssue = 1;
+ *       nWaitersToUnblock++;
+ *       nWaitersBlocked--;
+ *     }
+ *   }
+ *   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ *     sem_wait( semBlockLock );                  // close the gate
+ *     if ( 0 != nWaitersGone ) {
+ *       nWaitersBlocked -= nWaitersGone;
+ *       nWaitersGone = 0;
+ *     }
+ *     if (bAll) {
+ *       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ *       nWaitersBlocked = 0;
+ *     }
+ *     else {
+ *       nSignalsToIssue = nWaitersToUnblock = 1;
+ *       nWaitersBlocked--;
+ *     }
+ *   }
+ *   else { // NO-OP
+ *     return unlock( mtxUnblockLock );
+ *   }
+ *
+ *   unlock( mtxUnblockLock );
+ *   sem_post( semBlockQueue,nSignalsToIssue );
+ *   return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ *     Algorithm 9 / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+ *
+ * presented below in pseudo-code; basically 8a...
+ *                                      ...BUT W/O "spurious wakes" prevention:
+ *
+ *
+ * given:
+ * semBlockLock - bin.semaphore
+ * semBlockQueue - semaphore
+ * mtxExternal - mutex or CS
+ * mtxUnblockLock - mutex or CS
+ * nWaitersGone - int
+ * nWaitersBlocked - int
+ * nWaitersToUnblock - int
+ *
+ * wait( timeout ) {
+ *
+ *   [auto: register int result          ]     // error checking omitted
+ *   [auto: register int nSignalsWasLeft ]
+ *
+ *   sem_wait( semBlockLock );
+ *   ++nWaitersBlocked;
+ *   sem_post( semBlockLock );
+ *
+ *   unlock( mtxExternal );
+ *   bTimedOut = sem_wait( semBlockQueue,timeout );
+ *
+ *   lock( mtxUnblockLock );
+ *   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+ *     --nWaitersToUnblock;
+ *   }
+ *   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+ *                                             // spurious semaphore :-)
+ *     sem_wait( semBlockLock );
+ *     nWaitersBlocked -= nWaitersGone;        // something is going on here
+ *                                             //  - test of timeouts? :-)
+ *     sem_post( semBlockLock );
+ *     nWaitersGone = 0;
+ *   }
+ *   unlock( mtxUnblockLock );
+ *
+ *   if ( 1 == nSignalsWasLeft ) {
+ *     sem_post( semBlockLock );               // open the gate
+ *   }
+ *
+ *   lock( mtxExternal );
+ *
+ *   return ( bTimedOut ) ? ETIMEOUT : 0;
+ * }
+ *
+ * signal(bAll) {
+ *
+ *   [auto: register int result         ]
+ *   [auto: register int nSignalsToIssue]
+ *
+ *   lock( mtxUnblockLock );
+ *
+ *   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
+ *     if ( 0 == nWaitersBlocked ) {        // NO-OP
+ *       return unlock( mtxUnblockLock );
+ *     }
+ *     if (bAll) {
+ *       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+ *       nWaitersBlocked = 0;
+ *     }
+ *     else {
+ *       nSignalsToIssue = 1;
+ *       ++nWaitersToUnblock;
+ *       --nWaitersBlocked;
+ *     }
+ *   }
+ *   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+ *     sem_wait( semBlockLock );                  // close the gate
+ *     if ( 0 != nWaitersGone ) {
+ *       nWaitersBlocked -= nWaitersGone;
+ *       nWaitersGone = 0;
+ *     }
+ *     if (bAll) {
+ *       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+ *       nWaitersBlocked = 0;
+ *     }
+ *     else {
+ *       nSignalsToIssue = nWaitersToUnblock = 1;
+ *       --nWaitersBlocked;
+ *     }
+ *   }
+ *   else { // NO-OP
+ *     return unlock( mtxUnblockLock );
+ *   }
+ *
+ *   unlock( mtxUnblockLock );
+ *   sem_post( semBlockQueue,nSignalsToIssue );
+ *   return result;
+ * }
+ * -------------------------------------------------------------
+ *
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+/*
+ * Arguments for cond_wait_cleanup, since we can only pass a
+ * single void * to it.
+ */
+typedef struct
+  {
+    pthread_mutex_t *mutexPtr;
+    pthread_cond_t cv;
+    int *resultPtr;
+  } pte_cond_wait_cleanup_args_t;
+
+static void
+pte_cond_wait_cleanup (void *args)
+{
+  pte_cond_wait_cleanup_args_t *cleanup_args =
+    (pte_cond_wait_cleanup_args_t *) args;
+  pthread_cond_t cv = cleanup_args->cv;
+  int *resultPtr = cleanup_args->resultPtr;
+  int nSignalsWasLeft;
+  int result;
+
+  /*
+   * Whether we got here as a result of signal/broadcast or because of
+   * timeout on wait or thread cancellation we indicate that we are no
+   * longer waiting. The waiter is responsible for adjusting waiters
+   * (to)unblock(ed) counts (protected by unblock lock).
+   */
+  if ((result = pthread_mutex_lock (&(cv->mtxUnblockLock))) != 0)
+    {
+      *resultPtr = result;
+      return;
+    }
+
+  if (0 != (nSignalsWasLeft = cv->nWaitersToUnblock))
+    {
+      --(cv->nWaitersToUnblock);
+    }
+  else if (INT_MAX / 2 == ++(cv->nWaitersGone))
+    {
+      /* Use the non-cancellable version of sem_wait() */
+//      if (sem_wait_nocancel (&(cv->semBlockLock)) != 0)
+      if (sem_wait (&(cv->semBlockLock)) != 0)
+        {
+          *resultPtr = errno;
+          /*
+           * This is a fatal error for this CV,
+           * so we deliberately don't unlock
+           * cv->mtxUnblockLock before returning.
+           */
+          return;
+        }
+      cv->nWaitersBlocked -= cv->nWaitersGone;
+      if (sem_post (&(cv->semBlockLock)) != 0)
+        {
+          *resultPtr = errno;
+          /*
+           * This is a fatal error for this CV,
+           * so we deliberately don't unlock
+           * cv->mtxUnblockLock before returning.
+           */
+          return;
+        }
+      cv->nWaitersGone = 0;
+    }
+
+  if ((result = pthread_mutex_unlock (&(cv->mtxUnblockLock))) != 0)
+    {
+      *resultPtr = result;
+      return;
+    }
+
+  if (1 == nSignalsWasLeft)
+    {
+      if (sem_post (&(cv->semBlockLock)) != 0)
+        {
+          *resultPtr = errno;
+          return;
+        }
+    }
+
+  /*
+   * XSH: Upon successful return, the mutex has been locked and is owned
+   * by the calling thread.
+   */
+  if ((result = pthread_mutex_lock (cleanup_args->mutexPtr)) != 0)
+    {
+      *resultPtr = result;
+    }
+}				/* pte_cond_wait_cleanup */
+
+static int
+pte_cond_timedwait (pthread_cond_t * cond,
+                    pthread_mutex_t * mutex, const struct timespec *abstime)
+{
+  int result = 0;
+  pthread_cond_t cv;
+  pte_cond_wait_cleanup_args_t cleanup_args;
+
+  if (cond == NULL || *cond == NULL)
+    {
+      return EINVAL;
+    }
+
+  /*
+   * We do a quick check to see if we need to do more work
+   * to initialise a static condition variable. We check
+   * again inside the guarded section of pte_cond_check_need_init()
+   * to avoid race conditions.
+   */
+  if (*cond == PTHREAD_COND_INITIALIZER)
+    {
+      result = pte_cond_check_need_init (cond);
+    }
+
+  if (result != 0 && result != EBUSY)
+    {
+      return result;
+    }
+
+  cv = *cond;
+
+  /* Thread can be cancelled in sem_wait() but this is OK */
+  if (sem_wait (&(cv->semBlockLock)) != 0)
+    {
+      return errno;
+    }
+
+  ++(cv->nWaitersBlocked);
+
+  if (sem_post (&(cv->semBlockLock)) != 0)
+    {
+      return errno;
+    }
+
+  /*
+   * Setup this waiter cleanup handler
+   */
+  cleanup_args.mutexPtr = mutex;
+  cleanup_args.cv = cv;
+  cleanup_args.resultPtr = &result;
+
+  pthread_cleanup_push (pte_cond_wait_cleanup, (void *) &cleanup_args);
+
+  /*
+   * Now we can release 'mutex' and...
+   */
+  if ((result = pthread_mutex_unlock (mutex)) == 0)
+    {
+      /*
+       * ...wait to be awakened by
+       *              pthread_cond_signal, or
+       *              pthread_cond_broadcast, or
+       *              timeout, or
+       *              thread cancellation
+       *
+       * Note:
+       *
+       *      sem_timedwait is a cancellation point,
+       *      hence providing the mechanism for making
+       *      pthread_cond_wait a cancellation point.
+       *      We use the cleanup mechanism to ensure we
+       *      re-lock the mutex and adjust (to)unblock(ed) waiters
+       *      counts if we are cancelled, timed out or signalled.
+       */
+      if (sem_timedwait (&(cv->semBlockQueue), abstime) != 0)
+        {
+          result = errno;
+        }
+    }
+
+
+  /*
+   * Always cleanup
+   */
+  pthread_cleanup_pop (1);
+
+  /*
+   * "result" can be modified by the cleanup handler.
+   */
+  return result;
+
+}				/* pte_cond_timedwait */
+
+
+int
+pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function waits on a condition variable until
+ *      awakened by a signal or broadcast.
+ *
+ *      Caller MUST be holding the mutex lock; the
+ *      lock is released and the caller is blocked waiting
+ *      on 'cond'. When 'cond' is signaled, the mutex
+ *      is re-acquired before returning to the caller.
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *      mutex
+ *              pointer to an instance of pthread_mutex_t
+ *
+ *
+ * DESCRIPTION
+ *      This function waits on a condition variable until
+ *      awakened by a signal or broadcast.
+ *
+ *      NOTES:
+ *
+ *      1)      The function must be called with 'mutex' LOCKED
+ *              by the calling thread, or undefined behaviour
+ *              will result.
+ *
+ *      2)      This routine atomically releases 'mutex' and causes
+ *              the calling thread to block on the condition variable.
+ *              The blocked thread may be awakened by
+ *                      pthread_cond_signal or
+ *                      pthread_cond_broadcast.
+ *
+ * Upon successful completion, the 'mutex' has been locked and
+ * is owned by the calling thread.
+ *
+ *
+ * RESULTS
+ *              0               caught condition; mutex released,
+ *              EINVAL          'cond' or 'mutex' is invalid,
+ *              EINVAL          different mutexes for concurrent waits,
+ *              EINVAL          mutex is not held by the calling thread,
+ *
+ * ------------------------------------------------------
+ */
+{
+  /*
+   * The NULL abstime arg means INFINITE waiting.
+   */
+  return (pte_cond_timedwait (cond, mutex, NULL));
+
+}				/* pthread_cond_wait */
+
+
+int
+pthread_cond_timedwait (pthread_cond_t * cond,
+                        pthread_mutex_t * mutex,
+                        const struct timespec *abstime)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function waits on a condition variable either until
+ *      awakened by a signal or broadcast; or until the time
+ *      specified by abstime passes.
+ *
+ * PARAMETERS
+ *      cond
+ *              pointer to an instance of pthread_cond_t
+ *
+ *      mutex
+ *              pointer to an instance of pthread_mutex_t
+ *
+ *      abstime
+ *              pointer to an instance of (const struct timespec)
+ *
+ *
+ * DESCRIPTION
+ *      This function waits on a condition variable either until
+ *      awakened by a signal or broadcast; or until the time
+ *      specified by abstime passes.
+ *
+ *      NOTES:
+ *      1)      The function must be called with 'mutex' LOCKED
+ *              by the calling thread, or undefined behaviour
+ *              will result.
+ *
+ *      2)      This routine atomically releases 'mutex' and causes
+ *              the calling thread to block on the condition variable.
+ *              The blocked thread may be awakened by
+ *                      pthread_cond_signal or
+ *                      pthread_cond_broadcast.
+ *
+ *
+ * RESULTS
+ *              0               caught condition; mutex released,
+ *              EINVAL          'cond', 'mutex', or abstime is invalid,
+ *              EINVAL          different mutexes for concurrent waits,
+ *              EINVAL          mutex is not held by the calling thread,
+ *              ETIMEDOUT       abstime ellapsed before cond was signaled.
+ *
+ * ------------------------------------------------------
+ */
+{
+  if (abstime == NULL)
+    {
+      return EINVAL;
+    }
+
+  return (pte_cond_timedwait (cond, mutex, abstime));
+
+}				/* pthread_cond_timedwait */

+ 94 - 0
pthread_condattr_destroy.c

@@ -0,0 +1,94 @@
+/*
+ * condvar_attr_destroy.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_destroy (pthread_condattr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Destroys a condition variable attributes object.
+ *      The object can no longer be used.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ *      Destroys a condition variable attributes object.
+ *      The object can no longer be used.
+ *
+ *      NOTES:
+ *      1)      Does not affect condition variables created
+ *              using 'attr'
+ *
+ * RESULTS
+ *              0               successfully released attr,
+ *              EINVAL          'attr' is invalid.
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result = 0;
+
+  if (attr == NULL || *attr == NULL)
+    {
+      result = EINVAL;
+    }
+  else
+    {
+      (void) free (*attr);
+
+      *attr = NULL;
+      result = 0;
+    }
+
+  return result;
+
+}				/* pthread_condattr_destroy */

+ 103 - 0
pthread_condattr_getpshared.c

@@ -0,0 +1,103 @@
+/*
+ * pthread_condattr_getpshared.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_getpshared (const pthread_condattr_t * attr, int *pshared)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Determine whether condition variables created with 'attr'
+ *      can be shared between processes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_condattr_t
+ *
+ *      pshared
+ *              will be set to one of:
+ *
+ *                      PTHREAD_PROCESS_SHARED
+ *                              May be shared if in shared memory
+ *
+ *                      PTHREAD_PROCESS_PRIVATE
+ *                              Cannot be shared.
+ *
+ *
+ * DESCRIPTION
+ *      Condition Variables created with 'attr' can be shared
+ *      between processes if pthread_cond_t variable is allocated
+ *      in memory shared by these processes.
+ *      NOTES:
+ *      1)      pshared condition variables MUST be allocated in
+ *              shared memory.
+ *
+ *      2)      The following macro is defined if shared mutexes
+ *              are supported:
+ *                      _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ *              0               successfully retrieved attribute,
+ *              EINVAL          'attr' or 'pshared' is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+
+  if ((attr != NULL && *attr != NULL) && (pshared != NULL))
+    {
+      *pshared = (*attr)->pshared;
+      result = 0;
+    }
+  else
+    {
+      result = EINVAL;
+    }
+
+  return result;
+
+}				/* pthread_condattr_getpshared */

+ 95 - 0
pthread_condattr_init.c

@@ -0,0 +1,95 @@
+/*
+ * pthread_condattr_init.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_init (pthread_condattr_t * attr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Initializes a condition variable attributes object
+ *      with default attributes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_condattr_t
+ *
+ *
+ * DESCRIPTION
+ *      Initializes a condition variable attributes object
+ *      with default attributes.
+ *
+ *      NOTES:
+ *              1)      Use to define condition variable types
+ *              2)      It is up to the application to ensure
+ *                      that it doesn't re-init an attribute
+ *                      without destroying it first. Otherwise
+ *                      a memory leak is created.
+ *
+ * RESULTS
+ *              0               successfully initialized attr,
+ *              ENOMEM          insufficient memory for attr.
+ *
+ * ------------------------------------------------------
+ */
+{
+  pthread_condattr_t attr_result;
+  int result = 0;
+
+  attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result));
+
+  if (attr_result == NULL)
+    {
+      result = ENOMEM;
+    }
+
+  *attr = attr_result;
+
+  return result;
+
+}				/* pthread_condattr_init */

+ 123 - 0
pthread_condattr_setpshared.c

@@ -0,0 +1,123 @@
+/*
+ * pthread_condattr_setpshared.c
+ *
+ * Description:
+ * This translation unit implements condition variables and their primitives.
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      Mutexes created with 'attr' can be shared between
+ *      processes if pthread_mutex_t variable is allocated
+ *      in memory shared by these processes.
+ *
+ * PARAMETERS
+ *      attr
+ *              pointer to an instance of pthread_mutexattr_t
+ *
+ *      pshared
+ *              must be one of:
+ *
+ *                      PTHREAD_PROCESS_SHARED
+ *                              May be shared if in shared memory
+ *
+ *                      PTHREAD_PROCESS_PRIVATE
+ *                              Cannot be shared.
+ *
+ * DESCRIPTION
+ *      Mutexes creatd with 'attr' can be shared between
+ *      processes if pthread_mutex_t variable is allocated
+ *      in memory shared by these processes.
+ *
+ *      NOTES:
+ *              1)      pshared mutexes MUST be allocated in shared
+ *                      memory.
+ *
+ *              2)      The following macro is defined if shared mutexes
+ *                      are supported:
+ *                              _POSIX_THREAD_PROCESS_SHARED
+ *
+ * RESULTS
+ *              0               successfully set attribute,
+ *              EINVAL          'attr' or pshared is invalid,
+ *              ENOSYS          PTHREAD_PROCESS_SHARED not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+
+  if ((attr != NULL && *attr != NULL)
+      && ((pshared == PTHREAD_PROCESS_SHARED)
+          || (pshared == PTHREAD_PROCESS_PRIVATE)))
+    {
+      if (pshared == PTHREAD_PROCESS_SHARED)
+        {
+
+#if !defined( _POSIX_THREAD_PROCESS_SHARED )
+          result = ENOSYS;
+          pshared = PTHREAD_PROCESS_PRIVATE;
+#else
+          result = 0;
+
+#endif /* _POSIX_THREAD_PROCESS_SHARED */
+
+        }
+      else
+        {
+          result = 0;
+        }
+
+      (*attr)->pshared = pshared;
+    }
+  else
+    {
+      result = EINVAL;
+    }
+
+  return result;
+
+}				/* pthread_condattr_setpshared */

+ 166 - 0
pthread_delay_np.c

@@ -0,0 +1,166 @@
+/*
+ * pthreads_delay_np.c
+ *
+ * Description:
+ * This translation unit implements non-portable thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+/*
+ * pthread_delay_np
+ *
+ * DESCRIPTION
+ *
+ *       This routine causes a thread to delay execution for a specific period of time.
+ *       This period ends at the current time plus the specified interval. The routine
+ *       will not return before the end of the period is reached, but may return an
+ *       arbitrary amount of time after the period has gone by. This can be due to
+ *       system load, thread priorities, and system timer granularity.
+ *
+ *       Specifying an interval of zero (0) seconds and zero (0) nanoseconds is
+ *       allowed and can be used to force the thread to give up the processor or to
+ *       deliver a pending cancelation request.
+ *
+ *       The timespec structure contains the following two fields:
+ *
+ *            tv_sec is an integer number of seconds.
+ *            tv_nsec is an integer number of nanoseconds.
+ *
+ *  Return Values
+ *
+ *  If an error condition occurs, this routine returns an integer value indicating
+ *  the type of error. Possible return values are as follows:
+ *
+ *  0
+ *           Successful completion.
+ *  [EINVAL]
+ *           The value specified by interval is invalid.
+ *
+ * Example
+ *
+ * The following code segment would wait for 5 and 1/2 seconds
+ *
+ *  struct timespec tsWait;
+ *  int      intRC;
+ *
+ *  tsWait.tv_sec  = 5;
+ *  tsWait.tv_nsec = 500000000L;
+ *  intRC = pthread_delay_np(&tsWait);
+ */
+int
+pthread_delay_np (struct timespec *interval)
+{
+  unsigned int wait_time;
+  unsigned int secs_in_millisecs;
+  unsigned int millisecs;
+  pthread_t self;
+  pte_thread_t * sp;
+
+  if (interval == NULL)
+    {
+      return EINVAL;
+    }
+
+  if (interval->tv_sec == 0L && interval->tv_nsec == 0L)
+    {
+      pthread_testcancel ();
+      pte_osThreadSleep (1);
+      pthread_testcancel ();
+      return (0);
+    }
+
+  /* convert secs to millisecs */
+  secs_in_millisecs = interval->tv_sec * 1000L;
+
+  /* convert nanosecs to millisecs (rounding up) */
+  millisecs = (interval->tv_nsec + 999999L) / 1000000L;
+
+  wait_time = secs_in_millisecs + millisecs;
+
+  if (NULL == (self = pthread_self ()).p)
+    {
+      return ENOMEM;
+    }
+
+  sp = (pte_thread_t *) self.p;
+
+  if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
+    {
+      pte_osResult cancelStatus;
+      /*
+       * Async cancelation won't catch us until wait_time is up.
+       * Deferred cancelation will cancel us immediately.
+       */
+      cancelStatus = pte_osThreadCheckCancel(sp->threadId);
+
+      if (cancelStatus == PTE_OS_INTERRUPTED)
+        {
+          /*
+           * Canceling!
+           */
+          (void) pthread_mutex_lock (&sp->cancelLock);
+          if (sp->state < PThreadStateCanceling)
+            {
+              sp->state = PThreadStateCanceling;
+              sp->cancelState = PTHREAD_CANCEL_DISABLE;
+              (void) pthread_mutex_unlock (&sp->cancelLock);
+
+              pte_throw (PTE_EPS_CANCEL);
+            }
+
+          (void) pthread_mutex_unlock (&sp->cancelLock);
+          return ESRCH;
+        }
+      else if (cancelStatus != PTE_OS_OK)
+        {
+          return EINVAL;
+        }
+    }
+  else
+
+    {
+      pte_osThreadSleep (wait_time);
+    }
+
+  return (0);
+}

+ 142 - 0
pthread_detach.c

@@ -0,0 +1,142 @@
+/*
+ * pthread_detach.c
+ *
+ * Description:
+ * This translation unit implements functions related to thread
+ * synchronisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <pte_osal.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_detach (pthread_t thread)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function detaches the given thread.
+ *
+ * PARAMETERS
+ *      thread
+ *              an instance of a pthread_t
+ *
+ *
+ * DESCRIPTION
+ *      This function detaches the given thread. You may use it to
+ *      detach the main thread or to detach a joinable thread.
+ *      NOTE:   detached threads cannot be joined;
+ *              storage is freed immediately on termination.
+ *
+ * RESULTS
+ *              0               successfully detached the thread,
+ *              EINVAL          thread is not a joinable thread,
+ *              ENOSPC          a required resource has been exhausted,
+ *              ESRCH           no thread could be found for 'thread',
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+  unsigned char destroyIt = PTE_FALSE;
+  pte_thread_t * tp = (pte_thread_t *) thread.p;
+
+
+  pte_osMutexLock (pte_thread_reuse_lock);
+
+  if (NULL == tp
+      || thread.x != tp->ptHandle.x)
+    {
+      result = ESRCH;
+    }
+  else if (PTHREAD_CREATE_DETACHED == tp->detachState)
+    {
+      result = EINVAL;
+    }
+  else
+    {
+      /*
+       * Joinable pte_thread_t structs are not scavenged until
+       * a join or detach is done. The thread may have exited already,
+       * but all of the state and locks etc are still there.
+       */
+      result = 0;
+
+      if (pthread_mutex_lock (&tp->cancelLock) == 0)
+        {
+          if (tp->state != PThreadStateLast)
+            {
+              tp->detachState = PTHREAD_CREATE_DETACHED;
+            }
+          else if (tp->detachState != PTHREAD_CREATE_DETACHED)
+            {
+              /*
+               * Thread is joinable and has exited or is exiting.
+               */
+              destroyIt = PTE_TRUE;
+            }
+          (void) pthread_mutex_unlock (&tp->cancelLock);
+        }
+      else
+        {
+          /* cancelLock shouldn't fail, but if it does ... */
+          result = ESRCH;
+        }
+    }
+
+  pte_osMutexUnlock(pte_thread_reuse_lock);
+
+  if (result == 0)
+    {
+      /* Thread is joinable */
+
+      if (destroyIt)
+        {
+          /* The thread has exited or is exiting but has not been joined or
+           * detached. Need to wait in case it's still exiting.
+           */
+          pte_osThreadWaitForEnd(tp->threadId);
+
+          pte_threadDestroy (thread);
+        }
+    }
+
+  return (result);
+
+}				/* pthread_detach */

+ 82 - 0
pthread_equal.c

@@ -0,0 +1,82 @@
+/*
+ * pthread_equal.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_equal (pthread_t t1, pthread_t t2)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function returns nonzero if t1 and t2 are equal, else
+ *      returns nonzero
+ *
+ * PARAMETERS
+ *      t1,
+ *      t2
+ *              thread IDs
+ *
+ *
+ * DESCRIPTION
+ *      This function returns nonzero if t1 and t2 are equal, else
+ *      returns zero.
+ *
+ * RESULTS
+ *              non-zero        if t1 and t2 refer to the same thread,
+ *              0               t1 and t2 do not refer to the same thread
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+
+  /*
+   * We also accept NULL == NULL - treating NULL as a thread
+   * for this special case, because there is no error that we can return.
+   */
+  result = ( t1.p == t2.p && t1.x == t2.x );
+
+  return (result);
+
+}				/* pthread_equal */

+ 101 - 0
pthread_exit.c

@@ -0,0 +1,101 @@
+/*
+ * pthread_exit.c
+ *
+ * Description:
+ * This translation unit implements routines associated with exiting from
+ * a thread.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+void
+pthread_exit (void *value_ptr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function terminates the calling thread, returning
+ *      the value 'value_ptr' to any joining thread.
+ *
+ * PARAMETERS
+ *      value_ptr
+ *              a generic data value (i.e. not the address of a value)
+ *
+ *
+ * DESCRIPTION
+ *      This function terminates the calling thread, returning
+ *      the value 'value_ptr' to any joining thread.
+ *      NOTE: thread should be joinable.
+ *
+ * RESULTS
+ *              N/A
+ *
+ * ------------------------------------------------------
+ */
+{
+  pte_thread_t * sp;
+
+  /*
+   * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
+   * unnecessarily.
+   */
+  sp = (pte_thread_t *) pthread_getspecific (pte_selfThreadKey);
+
+  if (NULL == sp)
+    {
+      /*
+       * A POSIX thread handle was never created. I.e. this is a
+       * Win32 thread that has never called a pthreads-win32 routine that
+       * required a POSIX handle.
+       *
+       * Implicit POSIX handles are cleaned up in pte_throw() now.
+       */
+
+      /* Terminate thread */
+      pte_osThreadExit();
+
+      /* Never reached */
+    }
+
+  sp->exitStatus = value_ptr;
+
+  pte_throw (PTE_EPS_EXIT);
+
+  /* Never reached. */
+
+}

+ 51 - 0
pthread_getconcurrency.c

@@ -0,0 +1,51 @@
+/*
+ * pthread_getconcurrency.c
+ *
+ * Description:
+ * This translation unit implements miscellaneous thread functions.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_getconcurrency (void)
+{
+  return pte_concurrency;
+}

+ 81 - 0
pthread_getschedparam.c

@@ -0,0 +1,81 @@
+/*
+ * sched_getschedparam.c
+ *
+ * Description:
+ * POSIX thread functions that deal with thread scheduling.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+#include "sched.h"
+
+int
+pthread_getschedparam (pthread_t thread, int *policy,
+                       struct sched_param *param)
+{
+  int result;
+
+  /* Validate the thread id. */
+  result = pthread_kill (thread, 0);
+  if (0 != result)
+    {
+      return result;
+    }
+
+  /*
+   * Validate the policy and param args.
+   * Check that a policy constant wasn't passed rather than &policy.
+   */
+  if (policy <= (int *) SCHED_MAX || param == NULL)
+    {
+      return EINVAL;
+    }
+
+  /* Fill out the policy. */
+  *policy = SCHED_OTHER;
+
+  /*
+   * This function must return the priority value set by
+   * the most recent pthread_setschedparam() or pthread_create()
+   * for the target thread. It must not return the actual thread
+   * priority as altered by any system priority adjustments etc.
+   */
+  param->sched_priority = ((pte_thread_t *)thread.p)->sched_priority;
+
+  return 0;
+}

+ 86 - 0
pthread_getspecific.c

@@ -0,0 +1,86 @@
+
+/*
+ * pthread_getspecific.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "pthread.h"
+#include "implement.h"
+
+
+void *
+pthread_getspecific (pthread_key_t key)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function returns the current value of key in the
+ *      calling thread. If no value has been set for 'key' in
+ *      the thread, NULL is returned.
+ *
+ * PARAMETERS
+ *      key
+ *              an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ *      This function returns the current value of key in the
+ *      calling thread. If no value has been set for 'key' in
+ *      the thread, NULL is returned.
+ *
+ * RESULTS
+ *              key value or NULL on failure
+ *
+ * ------------------------------------------------------
+ */
+{
+  void * ptr;
+
+  if (key == NULL)
+    {
+      ptr = NULL;
+    }
+  else
+    {
+      ptr = pte_osTlsGetValue (key->key);
+    }
+
+  return ptr;
+}

+ 91 - 0
pthread_init.c

@@ -0,0 +1,91 @@
+
+/*
+ * pthread_init.c
+ *
+ * Description:
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int pthread_init(void)
+{
+
+  if (pte_processInitialized)
+    {
+      /*
+       * Ignore if already initialized. this is useful for
+       * programs that uses a non-dll pthread
+       * library. Such programs must call pte_processInitialize() explicitly,
+       * since this initialization routine is automatically called only when
+       * the dll is loaded.
+       */
+      return PTE_TRUE;
+    }
+
+  pte_processInitialized = PTE_TRUE;
+
+  // Must happen before creating keys.
+  pte_osInit();
+
+  /*
+   * Initialize Keys
+   */
+  if ((pthread_key_create (&pte_selfThreadKey, NULL) != 0) ||
+      (pthread_key_create (&pte_cleanupKey, NULL) != 0))
+    {
+      pthread_terminate();
+    }
+
+  /*
+   * Set up the global locks.
+   */
+  pte_osMutexCreate (&pte_thread_reuse_lock);
+  pte_osMutexCreate (&pte_mutex_test_init_lock);
+  pte_osMutexCreate (&pte_cond_list_lock);
+  pte_osMutexCreate (&pte_cond_test_init_lock);
+  pte_osMutexCreate (&pte_rwlock_test_init_lock);
+  pte_osMutexCreate (&pte_spinlock_test_init_lock);
+
+
+  return (pte_processInitialized);
+
+}

+ 164 - 0
pthread_join.c

@@ -0,0 +1,164 @@
+/*
+ * pthread_join.c
+ *
+ * Description:
+ * This translation unit implements functions related to thread
+ * synchronisation.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <pte_osal.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+#include <stdio.h>
+
+int
+pthread_join (pthread_t thread, void **value_ptr)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function waits for 'thread' to terminate and
+ *      returns the thread's exit value if 'value_ptr' is not
+ *      NULL. This also detaches the thread on successful
+ *      completion.
+ *
+ * PARAMETERS
+ *      thread
+ *              an instance of pthread_t
+ *
+ *      value_ptr
+ *              pointer to an instance of pointer to void
+ *
+ *
+ * DESCRIPTION
+ *      This function waits for 'thread' to terminate and
+ *      returns the thread's exit value if 'value_ptr' is not
+ *      NULL. This also detaches the thread on successful
+ *      completion.
+ *      NOTE:   detached threads cannot be joined or canceled
+ *
+ * RESULTS
+ *              0               'thread' has completed
+ *              EINVAL          thread is not a joinable thread,
+ *              ESRCH           no thread could be found with ID 'thread',
+ *              ENOENT          thread couldn't find it's own valid handle,
+ *              EDEADLK         attempt to join thread with self
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result;
+  pthread_t self;
+  pte_thread_t * tp = (pte_thread_t *) thread.p;
+
+
+  pte_osMutexLock (pte_thread_reuse_lock);
+
+  if (NULL == tp
+      || thread.x != tp->ptHandle.x)
+    {
+      result = ESRCH;
+    }
+  else if (PTHREAD_CREATE_DETACHED == tp->detachState)
+    {
+      result = EINVAL;
+    }
+  else
+    {
+      result = 0;
+    }
+
+  pte_osMutexUnlock(pte_thread_reuse_lock);
+
+  if (result == 0)
+    {
+      /*
+       * The target thread is joinable and can't be reused before we join it.
+       */
+      self = pthread_self();
+
+      if (NULL == self.p)
+        {
+          result = ENOENT;
+        }
+      else if (pthread_equal (self, thread))
+        {
+          result = EDEADLK;
+        }
+      else
+        {
+          /*
+           * Pthread_join is a cancelation point.
+           * If we are canceled then our target thread must not be
+           * detached (destroyed). This is guarranteed because
+           * pthreadCancelableWait will not return if we
+           * are canceled.
+           */
+
+          result = pte_osThreadWaitForEnd(tp->threadId);
+
+          if (PTE_OS_OK == result)
+            {
+              if (value_ptr != NULL)
+                {
+                  *value_ptr = tp->exitStatus;
+                }
+
+              /*
+               * The result of making multiple simultaneous calls to
+               * pthread_join() or pthread_detach() specifying the same
+               * target is undefined.
+               */
+              result = pthread_detach (thread);
+            }
+	  else if (result == PTE_OS_INTERRUPTED)
+	    {
+	      /* Call was cancelled, but still return success (per spec) */
+	      result = 0;
+	    }
+          else
+            {
+              result = ESRCH;
+            }
+        }
+    }
+
+  return (result);
+
+}				/* pthread_join */

+ 119 - 0
pthread_key_create.c

@@ -0,0 +1,119 @@
+/*
+ * pthread_key_create.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdlib.h>
+
+#include "pte_osal.h"
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_key_create (pthread_key_t * key, void (*destructor) (void *))
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function creates a thread-specific data key visible
+ *      to all threads. All existing and new threads have a value
+ *      NULL for key until set using pthread_setspecific. When any
+ *      thread with a non-NULL value for key terminates, 'destructor'
+ *      is called with key's current value for that thread.
+ *
+ * PARAMETERS
+ *      key
+ *              pointer to an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ *      This function creates a thread-specific data key visible
+ *      to all threads. All existing and new threads have a value
+ *      NULL for key until set using pthread_setspecific. When any
+ *      thread with a non-NULL value for key terminates, 'destructor'
+ *      is called with key's current value for that thread.
+ *
+ * RESULTS
+ *              0               successfully created semaphore,
+ *              EAGAIN          insufficient resources or PTHREAD_KEYS_MAX
+ *                              exceeded,
+ *              ENOMEM          insufficient memory to create the key,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result = 0;
+  pthread_key_t newkey;
+
+  if ((newkey = (pthread_key_t) calloc (1, sizeof (*newkey))) == NULL)
+    {
+      result = ENOMEM;
+    }
+  else
+    {
+      pte_osResult osResult = pte_osTlsAlloc(&(newkey->key));
+
+      if (osResult != PTE_OS_OK)
+        {
+          result = EAGAIN;
+
+          free (newkey);
+          newkey = NULL;
+        }
+      else if (destructor != NULL)
+        {
+          /*
+           * Have to manage associations between thread and key;
+           * Therefore, need a lock that allows multiple threads
+           * to gain exclusive access to the key->threads list.
+           *
+           * The mutex will only be created when it is first locked.
+           */
+          newkey->keyLock = PTHREAD_MUTEX_INITIALIZER;
+          newkey->destructor = destructor;
+        }
+
+    }
+
+  *key = newkey;
+
+  return (result);
+}

+ 140 - 0
pthread_key_delete.c

@@ -0,0 +1,140 @@
+/*
+ * pthread_key_delete.c
+ *
+ * Description:
+ * POSIX thread functions which implement thread-specific data (TSD).
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_key_delete (pthread_key_t key)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function deletes a thread-specific data key. This
+ *      does not change the value of the thread specific data key
+ *      for any thread and does not run the key's destructor
+ *      in any thread so it should be used with caution.
+ *
+ * PARAMETERS
+ *      key
+ *              pointer to an instance of pthread_key_t
+ *
+ *
+ * DESCRIPTION
+ *      This function deletes a thread-specific data key. This
+ *      does not change the value of the thread specific data key
+ *      for any thread and does not run the key's destructor
+ *      in any thread so it should be used with caution.
+ *
+ * RESULTS
+ *              0               successfully deleted the key,
+ *              EINVAL          key is invalid,
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result = 0;
+
+  if (key != NULL)
+    {
+      if (key->threads != NULL &&
+          key->destructor != NULL &&
+          pthread_mutex_lock (&(key->keyLock)) == 0)
+        {
+          ThreadKeyAssoc *assoc;
+          /*
+           * Run through all Thread<-->Key associations
+           * for this key.
+           *
+           * While we hold at least one of the locks guarding
+           * the assoc, we know that the assoc pointed to by
+           * key->threads is valid.
+           */
+          while ((assoc = (ThreadKeyAssoc *) key->threads) != NULL)
+            {
+              pte_thread_t * thread = assoc->thread;
+
+              if (assoc == NULL)
+                {
+                  /* Finished */
+                  break;
+                }
+
+              if (pthread_mutex_lock (&(thread->threadLock)) == 0)
+                {
+                  /*
+                   * Since we are starting at the head of the key's threads
+                   * chain, this will also point key->threads at the next assoc.
+                   * While we hold key->keyLock, no other thread can insert
+                   * a new assoc via pthread_setspecific.
+                   */
+                  pte_tkAssocDestroy (assoc);
+                  (void) pthread_mutex_unlock (&(thread->threadLock));
+                }
+              else
+                {
+                  /* Thread or lock is no longer valid? */
+                  pte_tkAssocDestroy (assoc);
+                }
+            }
+          pthread_mutex_unlock (&(key->keyLock));
+        }
+
+      pte_osTlsFree (key->key);
+      if (key->destructor != NULL)
+        {
+          /* A thread could be holding the keyLock */
+          while (EBUSY == (result = pthread_mutex_destroy (&(key->keyLock))))
+            {
+              pte_osThreadSleep(1); // Ugly.
+            }
+        }
+
+      free (key);
+    }
+
+  return (result);
+}

+ 107 - 0
pthread_kill.c

@@ -0,0 +1,107 @@
+/*
+ * pthread_kill.c
+ *
+ * Description:
+ * This translation unit implements the pthread_kill routine.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+int
+pthread_kill (pthread_t thread, int sig)
+/*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ *      This function requests that a signal be delivered to the
+ *      specified thread. If sig is zero, error checking is
+ *      performed but no signal is actually sent such that this
+ *      function can be used to check for a valid thread ID.
+ *
+ * PARAMETERS
+ *      thread  reference to an instances of pthread_t
+ *      sig     signal. Currently only a value of 0 is supported.
+ *
+ *
+ * DESCRIPTION
+ *      This function requests that a signal be delivered to the
+ *      specified thread. If sig is zero, error checking is
+ *      performed but no signal is actually sent such that this
+ *      function can be used to check for a valid thread ID.
+ *
+ * RESULTS
+ *              ESRCH           the thread is not a valid thread ID,
+ *              EINVAL          the value of the signal is invalid
+ *                              or unsupported.
+ *              0               the signal was successfully sent.
+ *
+ * ------------------------------------------------------
+ */
+{
+  int result = 0;
+  pte_thread_t * tp;
+
+
+  pte_osMutexLock (pte_thread_reuse_lock);
+
+  tp = (pte_thread_t *) thread.p;
+
+  if (NULL == tp
+      || thread.x != tp->ptHandle.x
+      || 0 == tp->threadId)
+    {
+      result = ESRCH;
+    }
+
+  pte_osMutexUnlock(pte_thread_reuse_lock);
+
+  if (0 == result && 0 != sig)
+    {
+      /*
+       * Currently does not support any signals.
+       */
+      result = EINVAL;
+    }
+
+  return result;
+
+}				/* pthread_kill */

+ 154 - 0
pthread_mutex_destroy.c

@@ -0,0 +1,154 @@
+/*
+ * pthread_mutex_destroy.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_destroy (pthread_mutex_t * mutex)
+{
+  int result = 0;
+  pthread_mutex_t mx;
+
+  /*
+   * Let the system deal with invalid pointers.
+   */
+
+  /*
+   * Check to see if we have something to delete.
+   */
+  if (*mutex < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      mx = *mutex;
+
+      result = pthread_mutex_trylock (&mx);
+
+      /*
+       * If trylock succeeded and the mutex is not recursively locked it
+       * can be destroyed.
+       */
+      if (result == 0)
+        {
+          if (mx->kind != PTHREAD_MUTEX_RECURSIVE || 1 == mx->recursive_count)
+            {
+              /*
+               * FIXME!!!
+               * The mutex isn't held by another thread but we could still
+               * be too late invalidating the mutex below since another thread
+               * may already have entered mutex_lock and the check for a valid
+               * *mutex != NULL.
+               *
+               * Note that this would be an unusual situation because it is not
+               * common that mutexes are destroyed while they are still in
+               * use by other threads.
+               */
+              *mutex = NULL;
+
+              result = pthread_mutex_unlock (&mx);
+
+              if (result == 0)
+                {
+                  pte_osSemaphoreDelete(mx->handle);
+
+                  free(mx);
+
+                }
+              else
+                {
+                  /*
+                   * Restore the mutex before we return the error.
+                   */
+                  *mutex = mx;
+                }
+            }
+          else			/* mx->recursive_count > 1 */
+            {
+              /*
+               * The mutex must be recursive and already locked by us (this thread).
+               */
+              mx->recursive_count--;	/* Undo effect of pthread_mutex_trylock() above */
+              result = EBUSY;
+            }
+        }
+    }
+  else
+    {
+      /*
+       * See notes in pte_mutex_check_need_init() above also.
+       */
+
+      pte_osMutexLock (pte_mutex_test_init_lock);
+
+
+      /*
+       * Check again.
+       */
+      if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+        {
+          /*
+           * This is all we need to do to destroy a statically
+           * initialised mutex that has not yet been used (initialised).
+           * If we get to here, another thread
+           * waiting to initialise this mutex will get an EINVAL.
+           */
+          *mutex = NULL;
+        }
+      else
+        {
+          /*
+           * The mutex has been initialised while we were waiting
+           * so assume it's in use.
+           */
+          result = EBUSY;
+        }
+
+      pte_osMutexUnlock(pte_mutex_test_init_lock);
+
+    }
+
+  return (result);
+}

+ 83 - 0
pthread_mutex_init.c

@@ -0,0 +1,83 @@
+/*
+ * pthread_mutex_init.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr)
+{
+  int result = 0;
+  pthread_mutex_t mx;
+
+
+  if (mutex == NULL)
+    {
+      return EINVAL;
+    }
+
+  mx = (pthread_mutex_t) calloc (1, sizeof (*mx));
+
+  if (mx == NULL)
+    {
+      result = ENOMEM;
+    }
+  else
+    {
+      mx->lock_idx = 0;
+      mx->recursive_count = 0;
+      mx->kind = (attr == NULL || *attr == NULL
+                  ? PTHREAD_MUTEX_DEFAULT : (*attr)->kind);
+      mx->ownerThread.p = NULL;
+
+      pte_osSemaphoreCreate(0,&mx->handle);
+
+    }
+
+  *mutex = mx;
+
+  return (result);
+}

+ 140 - 0
pthread_mutex_lock.c

@@ -0,0 +1,140 @@
+/*
+ * pthread_mutex_lock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_lock (pthread_mutex_t * mutex)
+{
+  int result = 0;
+  pthread_mutex_t mx;
+
+  /*
+   * Let the system deal with invalid pointers.
+   */
+  if (*mutex == NULL)
+    {
+      return EINVAL;
+    }
+
+  /*
+   * We do a quick check to see if we need to do more work
+   * to initialise a static mutex. We check
+   * again inside the guarded section of pte_mutex_check_need_init()
+   * to avoid race conditions.
+   */
+  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      if ((result = pte_mutex_check_need_init (mutex)) != 0)
+        {
+          return (result);
+        }
+    }
+
+  mx = *mutex;
+
+  if (mx->kind == PTHREAD_MUTEX_NORMAL)
+    {
+      if (PTE_ATOMIC_EXCHANGE(
+            &mx->lock_idx,
+            1) != 0)
+        {
+          while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0)
+            {
+              if (pte_osSemaphorePend(mx->handle,NULL) != PTE_OS_OK)
+                {
+                  result = EINVAL;
+                  break;
+                }
+            }
+        }
+    }
+  else
+    {
+      pthread_t self = pthread_self();
+
+      if (PTE_ATOMIC_COMPARE_EXCHANGE(&mx->lock_idx,1,0) == 0)
+        {
+          mx->recursive_count = 1;
+          mx->ownerThread = self;
+        }
+      else
+        {
+          if (pthread_equal (mx->ownerThread, self))
+            {
+              if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
+                {
+                  mx->recursive_count++;
+                }
+              else
+                {
+                  result = EDEADLK;
+                }
+            }
+          else
+            {
+              while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0)
+                {
+                  if (pte_osSemaphorePend(mx->handle,NULL) != PTE_OS_OK)
+                    {
+                      result = EINVAL;
+                      break;
+                    }
+                }
+
+              if (0 == result)
+                {
+                  mx->recursive_count = 1;
+                  mx->ownerThread = self;
+                }
+            }
+        }
+
+    }
+
+  return (result);
+}

+ 189 - 0
pthread_mutex_timedlock.c

@@ -0,0 +1,189 @@
+/*
+ * pthread_mutex_timedlock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <pte_osal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+static int
+pte_timed_eventwait (pte_osSemaphoreHandle event, const struct timespec *abstime)
+/*
+ * ------------------------------------------------------
+ * DESCRIPTION
+ *      This function waits on an event until signaled or until
+ *      abstime passes.
+ *      If abstime has passed when this routine is called then
+ *      it returns a result to indicate this.
+ *
+ *      If 'abstime' is a NULL pointer then this function will
+ *      block until it can successfully decrease the value or
+ *      until interrupted by a signal.
+ *
+ *      This routine is not a cancelation point.
+ *
+ * RESULTS
+ *              0               successfully signaled,
+ *              ETIMEDOUT       abstime passed
+ *              EINVAL          'event' is not a valid event,
+ *
+ * ------------------------------------------------------
+ */
+{
+
+  unsigned int milliseconds;
+  pte_osResult status;
+  int retval;
+
+  if (abstime == NULL)
+    {
+      status = pte_osSemaphorePend(event, NULL);
+    }
+  else
+    {
+      /*
+       * Calculate timeout as milliseconds from current system time.
+       */
+      milliseconds = pte_relmillisecs (abstime);
+
+      status = pte_osSemaphorePend(event, &milliseconds);
+    }
+
+
+  if (status == PTE_OS_TIMEOUT)
+    {
+      retval = ETIMEDOUT;
+    }
+  else
+    {
+      retval = 0;
+    }
+
+  return retval;
+
+}				/* pte_timed_semwait */
+
+
+int
+pthread_mutex_timedlock (pthread_mutex_t * mutex,
+                         const struct timespec *abstime)
+{
+  int result;
+  pthread_mutex_t mx;
+
+  /*
+   * Let the system deal with invalid pointers.
+   */
+
+  /*
+   * We do a quick check to see if we need to do more work
+   * to initialise a static mutex. We check
+   * again inside the guarded section of pte_mutex_check_need_init()
+   * to avoid race conditions.
+   */
+  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      if ((result = pte_mutex_check_need_init (mutex)) != 0)
+        {
+          return (result);
+        }
+    }
+
+  mx = *mutex;
+
+  if (mx->kind == PTHREAD_MUTEX_NORMAL)
+    {
+      if (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,1) != 0)
+        {
+          while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0)
+            {
+              if (0 != (result = pte_timed_eventwait (mx->handle, abstime)))
+                {
+                  return result;
+                }
+            }
+        }
+    }
+  else
+    {
+      pthread_t self = pthread_self();
+
+      if (PTE_ATOMIC_COMPARE_EXCHANGE(&mx->lock_idx,1,0) == 0)
+        {
+          mx->recursive_count = 1;
+          mx->ownerThread = self;
+        }
+      else
+        {
+          if (pthread_equal (mx->ownerThread, self))
+            {
+              if (mx->kind == PTHREAD_MUTEX_RECURSIVE)
+                {
+                  mx->recursive_count++;
+                }
+              else
+                {
+                  return EDEADLK;
+                }
+            }
+          else
+            {
+              while (PTE_ATOMIC_EXCHANGE(&mx->lock_idx,-1) != 0)
+                {
+                  if (0 != (result = pte_timed_eventwait (mx->handle, abstime)))
+                    {
+                      return result;
+                    }
+                }
+
+              mx->recursive_count = 1;
+              mx->ownerThread = self;
+            }
+        }
+    }
+
+  return 0;
+}

+ 95 - 0
pthread_mutex_trylock.c

@@ -0,0 +1,95 @@
+/*
+ * pthread_mutex_trylock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 included with the
+ *      source code distribution. The list can also be seen at the
+ *      following World Wide Web location:
+ *      http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ *      This library is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU Lesser General Public
+ *      License as published by the Free Software Foundation; either
+ *      version 2 of the License, or (at your option) any later version.
+ *
+ *      This library is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *      Lesser General Public License for more details.
+ *
+ *      You should have received a copy of the GNU Lesser General Public
+ *      License along with this library in the file COPYING.LIB;
+ *      if not, write to the Free Software Foundation, Inc.,
+ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+
+int
+pthread_mutex_trylock (pthread_mutex_t * mutex)
+{
+  int result = 0;
+  pthread_mutex_t mx;
+
+  /*
+   * Let the system deal with invalid pointers.
+   */
+
+  /*
+   * We do a quick check to see if we need to do more work
+   * to initialise a static mutex. We check
+   * again inside the guarded section of pte_mutex_check_need_init()
+   * to avoid race conditions.
+   */
+  if (*mutex >= PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      if ((result = pte_mutex_check_need_init (mutex)) != 0)
+        {
+          return (result);
+        }
+    }
+
+  mx = *mutex;
+
+  if (0 == PTE_ATOMIC_COMPARE_EXCHANGE (&mx->lock_idx,1,0))
+    {
+      if (mx->kind != PTHREAD_MUTEX_NORMAL)
+        {
+          mx->recursive_count = 1;
+          mx->ownerThread = pthread_self ();
+        }
+    }
+  else
+    {
+      if (mx->kind == PTHREAD_MUTEX_RECURSIVE &&
+          pthread_equal (mx->ownerThread, pthread_self ()))
+        {
+          mx->recursive_count++;
+        }
+      else
+        {
+          result = EBUSY;
+        }
+    }
+
+  return (result);
+}

+ 130 - 0
pthread_mutex_unlock.c

@@ -0,0 +1,130 @@
+/*
+ * pthread_mutex_unlock.c
+ *
+ * Description:
+ * This translation unit implements mutual exclusion (mutex) primitives.
+ *
+ * --------------------------------------------------------------------------
+ *
+ *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
+ *      Copyright(C) 2008 Jason Schmidlapp
+ *
+ *      Contact Email: [email protected]
+ *
+ *
+ *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
+ *      Copyright(C) 1998 John E. Bossom
+ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ *      Contact Email: [email protected]
+ *
+ *      The original list of contributors to the Pthreads-win32 project
+ *      is contained in the file CONTRIBUTORS.ptw32 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 <pte_osal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pthread.h"
+#include "implement.h"
+
+
+#define TEST_IE InterlockedExchange
+
+int
+pthread_mutex_unlock (pthread_mutex_t * mutex)
+{
+  int result = 0;
+  pthread_mutex_t mx;
+
+  /*
+   * Let the system deal with invalid pointers.
+   */
+
+  mx = *mutex;
+
+  /*
+   * If the thread calling us holds the mutex then there is no
+   * race condition. If another thread holds the
+   * lock then we shouldn't be in here.
+   */
+  if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
+    {
+      if (mx->kind == PTHREAD_MUTEX_NORMAL)
+        {
+          int idx;
+
+          idx = PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0);
+          if (idx != 0)
+            {
+              if (idx < 0)
+                {
+                  /*
+                   * Someone may be waiting on that mutex.
+                   */
+                  if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK)
+                    {
+                      result = EINVAL;
+                    }
+                }
+            }
+          else
+            {
+              /*
+               * Was not locked (so can't be owned by us).
+               */
+              result = EPERM;
+            }
+        }
+      else
+        {
+          if (pthread_equal (mx->ownerThread, pthread_self ()))
+            {
+              if (mx->kind != PTHREAD_MUTEX_RECURSIVE
+                  || 0 == --mx->recursive_count)
+                {
+                  mx->ownerThread.p = NULL;
+
+                  if (PTE_ATOMIC_EXCHANGE (&mx->lock_idx,0) < 0)
+                    {
+                      if (pte_osSemaphorePost(mx->handle,1) != PTE_OS_OK)
+                        {
+                          result = EINVAL;
+                        }
+
+                    }
+                }
+            }
+          else
+            {
+              result = EPERM;
+            }
+        }
+    }
+  else
+    {
+      result = EINVAL;
+    }
+
+  return (result);
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно