cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
thread.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Thread/Mutex Handling *
4 * Copyright Peter Gutmann 1992-2011 *
5 * *
6 ****************************************************************************/
7 
8 #ifndef _THREAD_DEFINED
9 
10 #define _THREAD_DEFINED
11 
12 /* In multithreaded environments we need to use mutexes to protect the
13  information inside cryptlib data structures from access by other threads
14  while we use it. In most cases (mutexes not taken) mutexes are extremely
15  quick, being implemented using compare-and-swap on x86 or load/store
16  conditional on most RISC CPUs.
17 
18  The types and macros that are needed to handle mutexes are:
19 
20  MUTEX_HANDLE -- Handle for mutexes/semaphores
21 
22  MUTEX_DECLARE_STORAGE -- Declare storage for mutex
23  MUTEX_CREATE -- Initialise mutex
24  MUTEX_DESTROY -- Delete mutex
25  MUTEX_LOCK -- Acquire mutex
26  MUTEX_UNLOCK -- Release mutex
27 
28  Before deleting a mutex we lock and unlock it again to ensure that if
29  some other thread is holding it they'll release it before we delete it.
30 
31  Many systems don't provide re-entrant semaphores/mutexes. To handle this
32  we implement our own re-entrant mutexes on top of the OS ones. Using
33  the Posix terminology, what we do is use mutex_trylock(), which doesn't
34  re-lock the mutex if it's already locked, and as a side-benefit can be up
35  to twice as fast as mutex_lock(), depending on the OS. This works as
36  follows:
37 
38  // Try and lock the mutex
39  if( mutex_trylock( mutex ) == error )
40  {
41  // The mutex is already locked, see who owns it
42  if( thread_self() != mutex_owner )
43  // Someone else has it locked, wait for it to become available
44  mutex_lock( mutex );
45  else
46  // We have it locked, increment its lock count
47  mutex_lockcount++;
48  }
49  mutex_owner = thread_self();
50 
51  // ....
52 
53  // Decrement the lock count and if we reach zero, unlock the mutex
54  if( mutex_lockcount > 0 )
55  mutex_lockcount--;
56  else
57  {
58  mutex_owner = none;
59  mutex_unlock( mutex );
60  }
61 
62  This is safe from race conditions via the following:
63 
64  if( mutex_trylock( mutex ) == error )
65  { --> Unlock #1
66  if( thread_self() != mutex_owner )
67  --> Unlock #2
68  mutex_lock( mutex );
69  else
70  mutex_lockcount++;
71  }
72 
73  If the mutex is unlocked after the trylock at one of the two given
74  points, we can get the following situations:
75 
76  Unlock #1, no relock: mutex owner = none -> we lock the mutex
77  Unlock #1, relock by another thread:
78  mutex owner = other -> we wait on the mutex lock
79 
80  Unlock #2, no relock: mutex owner = none -> we lock the mutex
81  Unlock #2, relock by another thread:
82  mutex owner = other -> we wait on the mutex lock
83 
84  There's no race condition in the lock process since the only thing that
85  could cause a problem is if we unlock the mutex ourselves, which we can't
86  do.
87 
88  For the unlock process, the only possibility for a race condition is in
89  conjunction with the lock process, if the owner field isn't reset on
90  unlock then thread #1 could unlock the mutex and thread #2 could lock it
91  but be pre-empted before it can (re-)set the owner field. Then thread #1
92  could reacquire it thinking that it still owns the mutex because the
93  owner field hasn't been reset yet from its previous ownership. For this
94  reason it's essential that the owner field be reset before the mutex is
95  unlocked.
96 
97  Note that this implementation of re-entrant mutexes will cause some
98  static source analysers to give false-positive warnings about not
99  unlocking mutexes, since they don't understand the reference-counting
100  mechanism and assume that the mutex is always locked but not always
101  unlocked.
102 
103  An additional benefit to performing our own OS object management is that
104  we can avoid OS-specific exposure issues arising from the use of global
105  objects. For example under Windows if an object with a given name
106  already exists, CreateXYZ() opens the existing object, ignores the
107  security parameters and the object-held flag (!!), and returns a success
108  status. The only way to tell that we didn't actually get what we asked
109  for is that GetLastError() will return ERROR_ALREADY_EXISTS. Without
110  this check we could end up thinking we safely hold the object (via the
111  ignored object-held flag) when in fact we don't. Under Unix it's no
112  better, since a semaphore set (for example) is disconnected from the
113  processes that use it (access requires an on-demand lookup by semid) it's
114  possible for a name-squatting process to create the set before we do, we
115  "create" (= open) it, and then the other process deletes it and recreates
116  it in a different (and totally unexpected) configuration. To our process
117  the disconnected lookup makes it appear to be the same semaphore set. By
118  synthesising any higher-level objects that we need from low-level
119  primitives that aren't visible outside our process, we avoid this type
120  of exposure.
121 
122  The types and macros that need to be declared to handle threading are:
123 
124  THREAD_HANDLE -- Handle for threads
125 
126  THREADFUNC_DEFINE -- Define thread function
127 
128  THREAD_CREATE -- Create thread
129  THREAD_EXIT -- Exit from thread
130  THREAD_INITIALISER -- Value to initialise thread handle
131  THREAD_SELF -- Get handle of current thread
132  THREAD_SAME -- Compare two thread handles
133  THREAD_SLEEP -- Sleep for n milliseconds
134  THREAD_YIELD -- Yield thread's timeslice
135  THREAD_WAIT -- Wait for thread to terminate
136  THREAD_CLOSE -- Clean up thread after THREAD_WAIT
137 
138  Some systems allow a thread/task handle to be used as a synchronisation
139  object while others require a separate semaphore object for
140  synchronisation. To handle this we create a synchronisation semaphore in
141  the non-signalled state when we create a thread/task, signal it when the
142  task exits, and wait on it in the calling thread/task:
143 
144  Parent: Child:
145 
146  syncSem = createSem( 1 );
147  thread = createThread( syncSem );
148  signal( syncSem );
149  exit();
150  wait( syncSem );
151  destroySem( syncSem );
152 
153  If the thread/task handle can be used as a synchronisation object, these
154  additional operations are turned into no-ops.
155 
156  Several of the embedded OSes are extremely difficult to work with because
157  their kernels perform no memory (or, often, resource) management of their
158  own, assuming that all memory will be allocated by the caller. In the
159  simplest case this means that the thread stack/workspace has to be user-
160  allocated, in the worst case every object handle variable that's normally
161  a simple scalar value in other OSes is a composite non-scalar type that
162  contains all of the object's data, requiring that the caller manually
163  allocate state data for threads, mutexes, and semaphores rather than
164  having the OS do it for them.
165 
166  For things like mutex and semaphore 'handles', which have a fixed number
167  or location, this is manageable by statically allocating the storage in
168  advance. However it significantly complicates things like thread
169  handling because the thread that dynamically creates a worker thread has
170  to be around later on to clean up after it when it terminates, and the
171  state data has to be maintained in external (non-thread) storage. We
172  handle this in one of two ways, either by not using cryptlib-internal
173  threads (they're only used for initialisation and keygen, neither of
174  which will benefit much from the ability to run them in the background in
175  an embedded system), or by wrapping the threading functions in our own
176  ones which allocate memory as required and access the information via a
177  scalar handle.
178 
179  To enable the use of thread wrappers, see the xxx_THREAD_WRAPPERS define
180  for each embedded OS type */
181 
182 /* Define the following to debug mutex lock/unlock operations (only enabled
183  under Windows at the moment) */
184 
185 /* #define MUTEX_DEBUG */
186 
187 /****************************************************************************
188 * *
189 * AMX *
190 * *
191 ****************************************************************************/
192 
193 #if defined( __AMX__ )
194 
195 /* To use resource-management wrappers for the AMX thread functions,
196  undefine the following */
197 
198 /* #define AMX_THREAD_WRAPPERS */
199 
200 #include <cjzzz.h>
201 
202 /* Object handles */
203 
204 #define THREAD_HANDLE CJ_ID
205 #define MUTEX_HANDLE CJ_ID
206 
207 /* Mutex management functions. AMX resource semaphores are re-entrant so we
208  don't have to jump through the hoops that are necessary with most other
209  OSes */
210 
211 #define MUTEX_DECLARE_STORAGE( name ) \
212  CJ_ID name##Mutex; \
213  BOOLEAN name##MutexInitialised
214 #define MUTEX_CREATE( name, status ) \
215  status = CRYPT_OK; \
216  if( !krnlData->name##MutexInitialised ) \
217  { \
218  if( cjrmcreate( &krnlData->name##Mutex, NULL ) == CJ_EROK ) \
219  krnlData->name##MutexInitialised = TRUE; \
220  else \
221  status = CRYPT_ERROR; \
222  }
223 #define MUTEX_DESTROY( name ) \
224  if( krnlData->name##MutexInitialised ) \
225  { \
226  cjrmrsv( krnlData->name##Mutex, threadPriority(), 0 ); \
227  cjrmrls( krnlData->name##Mutex ); \
228  cjrmdelete( krnlData->name##Mutex ); \
229  krnlData->name##MutexInitialised = FALSE; \
230  }
231 #define MUTEX_LOCK( name ) \
232  cjrmrsv( krnlData->name##Mutex, x, 0 )
233 #define MUTEX_UNLOCK( name ) \
234  cjrmrls( krnlData->name##Mutex )
235 
236 /* Thread management functions. AMX threads require that the user allocate
237  the stack space for them, unlike virtually every other embedded OS, which
238  make this at most a rarely-used option. To handle this, we use our own
239  wrappers which hide this mess. A second problem with AMX threads is that
240  there's no obvious way to pass an argument to a thread. In theory we
241  could convey the information by sending it via a mailbox, but this
242  requires first conveying the mailbox ID to the new task, which has the
243  same problem.
244 
245  We create the thread with the same priority as the calling thread, AMX
246  threads are created in the suspended state so after we create the thread
247  we have to trigger it to start it running.
248 
249  The 4096 byte storage area provides enough space for the task control
250  block and about half a dozen levels of function nesting (if no large on-
251  stack arrays are used), this should be enough for background init but
252  probably won't be sufficient for the infinitely-recursive OpenSSL bignum
253  code, so the value may need to be adjusted if background keygen is being
254  used */
255 
256 #define THREADFUNC_DEFINE( name, arg ) void name( cyg_addrword_t arg )
257 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
258  { \
259  BYTE *threadData = malloc( 4096 ); \
260  \
261  cjsmcreate( &syncHandle, NULL, CJ_SMBINARY ); \
262  if( cjtkcreate( &threadHandle, NULL, function, threadData, \
263  4096, 0, threadPriority(), 0 ) != CJ_EROK ) \
264  { \
265  free( threadData ); \
266  status = CRYPT_ERROR; \
267  } \
268  else \
269  { \
270  cjtktrigger( threadHandle ); \
271  status = CRYPT_OK; \
272  } \
273  }
274 #define THREAD_EXIT( sync ) cjsmsignal( sync ); \
275  return
276 #define THREAD_INITIALISER CJ_IDNULL
277 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
278 #define THREAD_SELF() cjtkid()
279 #define THREAD_SLEEP( ms ) cjtkdelay( cjtmconvert( ms ) )
280 #define THREAD_YIELD() cjtkdelay( 1 )
281 #define THREAD_WAIT( sync, status ) \
282  if( cjsmwait( sync, threadPriority(), 0 ) != CJ_EROK ) \
283  status = CRYPT_ERROR; \
284  cjsmdelete( sync )
285 #define THREAD_CLOSE( sync )
286 
287 /* Because of the problems with resource management of AMX tasks and
288  related metadata, we no-op them out unless we're using wrappers by
289  ensuring that any attempt to spawn a thread inside cryptlib fails,
290  falling back to the non-threaded alternative. Note that cryptlib itself
291  is still thread-safe, it just can't do its init or keygen in an internal
292  background thread */
293 
294 #ifndef AMX_THREAD_WRAPPERS
295  #undef THREAD_CREATE
296  #undef THREAD_EXIT
297  #undef THREAD_CLOSE
298  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
299  status = CRYPT_ERROR
300  #define THREAD_EXIT( sync )
301  #define THREAD_CLOSE( sync )
302 #endif /* !AMX_THREAD_WRAPPERS */
303 
304 /* The AMX task-priority function returns the priority via a reference
305  parameter. Because of this we have to provide a wrapper that returns
306  it as a return value */
307 
308 int threadPriority( void );
309 
310 /****************************************************************************
311 * *
312 * BeOS *
313 * *
314 ****************************************************************************/
315 
316 #elif defined( __BEOS__ )
317 
318 #include <kernel/OS.h>
319 
320 /* Object handles */
321 
322 #define THREAD_HANDLE thread_id
323 #define MUTEX_HANDLE thread_id
324 
325 /* Mutex management functions */
326 
327 #define MUTEX_DECLARE_STORAGE( name ) \
328  sem_id name##Mutex; \
329  BOOLEAN name##MutexInitialised; \
330  thread_id name##MutexOwner; \
331  int name##MutexLockcount
332 #define MUTEX_CREATE( name, status ) \
333  status = CRYPT_OK; \
334  if( !krnlData->name##MutexInitialised ) \
335  { \
336  if( ( krnlData->name##Mutex = create_sem( 1, NULL ) ) < B_NO_ERROR ) \
337  status = CRYPT_ERROR; \
338  else \
339  krnlData->name##MutexInitialised = TRUE; \
340  }
341 #define MUTEX_DESTROY( name ) \
342  if( krnlData->name##MutexInitialised ) \
343  { \
344  acquire_sem( krnlData->name##Mutex ); \
345  release_sem( krnlData->name##Mutex ); \
346  delete_sem( krnlData->name##Mutex ); \
347  krnlData->name##MutexInitialised = FALSE; \
348  }
349 #define MUTEX_LOCK( name ) \
350  if( acquire_sem_etc( krnlData->name##Mutex, 1, \
351  B_RELATIVE_TIMEOUT, 0 ) == B_WOULD_BLOCK ) \
352  { \
353  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
354  acquire_sem( krnlData->name##Mutex ); \
355  else \
356  krnlData->name##MutexLockcount++; \
357  } \
358  krnlData->name##MutexOwner = THREAD_SELF();
359 #define MUTEX_UNLOCK( name ) \
360  if( krnlData->name##MutexLockcount > 0 ) \
361  krnlData->name##MutexLockcount--; \
362  else \
363  { \
364  krnlData->name##MutexOwner = THREAD_INITIALISER; \
365  release_sem( krnlData->name##Mutex ); \
366  }
367 
368 /* Thread management functions. BeOS threads are created in the suspended
369  state, so after we create the thread we have to resume it to start it
370  running */
371 
372 #define THREADFUNC_DEFINE( name, arg ) thread_id name( void *arg )
373 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
374  { \
375  threadHandle = syncHandle = \
376  spawn_thread( ( function ), NULL, B_NORMAL_PRIORITY, \
377  ( arg ) ); \
378  if( threadHandle < B_NO_ERROR ) \
379  status = CRYPT_ERROR; \
380  else \
381  resume_thread( threadHandle ); \
382  }
383 #define THREAD_EXIT( sync ) exit_thread( 0 )
384 #define THREAD_INITIALISER 0
385 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
386 #define THREAD_SELF() find_thread( NULL )
387 #define THREAD_SLEEP( ms ) snooze( ms )
388 #define THREAD_YIELD() snooze( estimate_max_scheduling_latency( -1 ) + 1 )
389 #define THREAD_WAIT( sync, status ) \
390  { \
391  status_t dummy; \
392  \
393  if( wait_for_thread( sync, &dummy ) != B_NO_ERROR.) \
394  status = CRYPT_ERROR; \
395  }
396 #define THREAD_CLOSE( sync )
397 
398 /****************************************************************************
399 * *
400 * ChorusOS *
401 * *
402 ****************************************************************************/
403 
404 #elif defined( __CHORUS__ )
405 
406 /* To use resource-management wrappers for the AMX thread functions,
407  undefine the following */
408 
409 /* #define AMX_THREAD_WRAPPERS */
410 
411 #include <chorus.h>
412 #include <exec/chExec.h>
413 
414 /* Object handles */
415 
416 #define THREAD_HANDLE KnThreadLid
417 #define MUTEX_HANDLE KnMutex
418 
419 /* Mutex management functions. ChorusOS provides no way to destroy a
420  mutex once it's initialised, presumably it gets cleaned up when the
421  owning actor terminates */
422 
423 #define MUTEX_DECLARE_STORAGE( name ) \
424  KnMutex name##Mutex; \
425  BOOLEAN name##MutexInitialised; \
426  KnThreadLid name##MutexOwner; \
427  int name##MutexLockcount
428 #define MUTEX_CREATE( name, status ) \
429  status = CRYPT_OK; \
430  if( !krnlData->name##MutexInitialised ) \
431  { \
432  if( mutexInit( &krnlData->name##Mutex ) == K_OK ) \
433  krnlData->name##MutexInitialised = TRUE; \
434  else \
435  status = CRYPT_ERROR; \
436  }
437 #define MUTEX_DESTROY( name ) \
438  if( krnlData->name##MutexInitialised ) \
439  { \
440  mutexGet( &krnlData->name##Mutex ); \
441  mutexRel( &krnlData->name##Mutex ); \
442  krnlData->name##MutexInitialised = FALSE; \
443  }
444 #define MUTEX_LOCK( name ) \
445  if( mutexTry( &krnlData->name##Mutex ) == 0 ) \
446  { \
447  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
448  mutexGet( &krnlData->name##Mutex ); \
449  else \
450  krnlData->name##MutexLockcount++; \
451  } \
452  krnlData->name##MutexOwner = THREAD_SELF();
453 #define MUTEX_UNLOCK( name ) \
454  if( krnlData->name##MutexLockcount > 0 ) \
455  krnlData->name##MutexLockcount--; \
456  else \
457  { \
458  krnlData->name##MutexOwner = THREAD_INITIALISER; \
459  mutexRel( &krnlData->name##Mutex ); \
460  }
461 
462 /* Thread management functions. ChorusOS threads require that the user
463  allocate the stack space for them, unlike virtually every other embedded
464  OS, which make this at most a rarely-used option. To handle this, we use
465  our own wrappers which hide this mess. A second problem with ChorusOS
466  threads is that there's no easy way to pass an argument to a thread, so
467  we have to include it as a "software register" value that the thread then
468  obtains via threadLoadR().
469 
470  The 4096 byte storage area provides enough space for about half a dozen
471  levels of function nesting (if no large on-stack arrays are used), this
472  should be enough for background init but probably won't be sufficient for
473  the infinitely-recursive OpenSSL bignum code, so the value may need to be
474  adjusted if background keygen is being used.
475 
476  ChorusOS provides no way to destroy a semaphore once it's initialised,
477  presumably it gets cleaned up when the owning actor terminates */
478 
479 #define THREADFUNC_DEFINE( name, arg ) void name( void )
480 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
481  { \
482  BYTE *threadStack = malloc( 4096 ); \
483  KnDefaultStartInfo startInfo = { \
484  K_START_INFO | K_START_INFO_SOFTREG, K_DEFAULT_STACK_SIZE, \
485  function, threadStack, K_USERTHREAD, arg }; \
486  \
487  semInit( &syncHandle, 1 ); \
488  if( threadCreate( K_MYACTOR, &threadHandle, K_ACTIVE, NULL, \
489  &startInfo ) != K_OK ) \
490  { \
491  free( threadStack ); \
492  status = CRYPT_ERROR; \
493  } \
494  else \
495  status = CRYPT_OK; \
496  }
497 #define THREAD_EXIT( sync ) semV( sync ); \
498  threadDelete( K_MYACTOR, K_MYSELF )
499 #define THREAD_INITIALISER NULL
500 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
501 #define THREAD_SELF() threadSelf()
502 #define THREAD_SLEEP( ms ) { \
503  KnTimeVal timeVal; \
504  \
505  K_MILLI_TO_TIMEVAL( &timeVal, ms ); \
506  threadDelay( &timeVal ); \
507  }
508 #define THREAD_YIELD() threadDelay( K_NOBLOCK )
509 #define THREAD_WAIT( sync, status ) \
510  if( semP( sync, K_NOTIMEOUT ) < 0 ) \
511  status = CRYPT_ERROR
512 #define THREAD_CLOSE( sync )
513 
514 /* Because of the problems with resource management of Chorus thread stack
515  space, we no-op out threads unless we're using wrappers by ensuring that
516  any attempt to spawn a thread inside cryptlib fails, falling back to the
517  non-threaded alternative. Note that cryptlib itself is still thread-
518  safe, it just can't do its init or keygen in an internal background
519  thread */
520 
521 #ifndef CHORUS_THREAD_WRAPPERS
522  #undef THREAD_CREATE
523  #undef THREAD_EXIT
524  #undef THREAD_CLOSE
525  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
526  status = CRYPT_ERROR
527  #define THREAD_EXIT( sync )
528  #define THREAD_CLOSE( sync )
529 #endif /* !CHORUS_THREAD_WRAPPERS */
530 
531 /****************************************************************************
532 * *
533 * eCOS *
534 * *
535 ****************************************************************************/
536 
537 #elif defined( __ECOS__ )
538 
539 /* To use resource-management wrappers for the eCOS thread functions,
540  undefine the following */
541 
542 /* #define ECOS_THREAD_WRAPPERS */
543 
544 #include <cyg/hal/hal_arch.h>
545 #include <cyg/kernel/kapi.h>
546 
547 /* Object handles */
548 
549 #define THREAD_HANDLE cyg_handle_t
550 #define MUTEX_HANDLE cyg_sem_t
551 
552 /* Since eCOS has non-scalar handles we need to define a custom version of
553  the value DUMMY_INIT_MUTEX (see the end of this file) */
554 
555 #define NONSCALAR_THREADS
556 #define DUMMY_INIT_MUTEX { 0 }
557 
558 /* Mutex management functions */
559 
560 #define MUTEX_DECLARE_STORAGE( name ) \
561  cyg_mutex_t name##Mutex; \
562  BOOLEAN name##MutexInitialised; \
563  cyg_handle_t name##MutexOwner; \
564  int name##MutexLockcount
565 #define MUTEX_CREATE( name, status ) \
566  status = CRYPT_OK; /* Apparently never fails */ \
567  if( !krnlData->name##MutexInitialised ) \
568  { \
569  cyg_mutex_init( &krnlData->name##Mutex ); \
570  krnlData->name##MutexInitialised = TRUE; \
571  }
572 #define MUTEX_DESTROY( name ) \
573  if( krnlData->name##MutexInitialised ) \
574  { \
575  cyg_mutex_lock( &krnlData->name##Mutex ); \
576  cyg_mutex_unlock( &krnlData->name##Mutex ); \
577  cyg_mutex_destroy( &krnlData->name##Mutex ); \
578  krnlData->name##MutexInitialised = FALSE; \
579  }
580 #define MUTEX_LOCK( name ) \
581  if( !cyg_mutex_trylock( &krnlData->name##Mutex ) ) \
582  { \
583  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
584  cyg_mutex_lock( &krnlData->name##Mutex ); \
585  else \
586  krnlData->name##MutexLockcount++; \
587  } \
588  krnlData->name##MutexOwner = THREAD_SELF();
589 #define MUTEX_UNLOCK( name ) \
590  if( krnlData->name##MutexLockcount > 0 ) \
591  krnlData->name##MutexLockcount--; \
592  else \
593  { \
594  krnlData->name##MutexOwner = THREAD_INITIALISER; \
595  cyg_mutex_unlock( &krnlData->name##Mutex ); \
596  }
597 
598 /* Thread management functions. eCOS threads require that the user allocate
599  the stack space for them, unlike virtually every other embedded OS, which
600  make this at most a rarely-used option. To handle this, we use our own
601  wrappers, which hide this mess and provide access via a single scalar
602  variable. For synchronisation we use semaphores, eCOS also provides
603  condition variables for this purpose but they require a user-managed
604  mutex to synchronise access to them, making them (at best) a primitive
605  DIY semaphore.
606 
607  We create the thread with the same priority as the calling thread, note
608  that this precludes the use of the bitmap scheduler (but not the lottery
609  scheduler). There doesn't seem to be any way to tell whether a thread
610  has been successfully created/started or not (!!), the best that we can
611  do is assume that if the thread handle is zero or negative then there's
612  been a problem. eCOS threads are created in the suspended state, so
613  after we create the thread we have to resume it to start it running.
614 
615  The CYGNUM_HAL_STACK_SIZE_TYPICAL provides enough stack space for about
616  half a dozen levels of function nesting (if no large on-stack arrays are
617  used), this should be enough for background init but probably won't be
618  sufficient for the infinitely-recursive OpenSSL bignum code, so the value
619  may need to be adjusted if background keygen is being used.
620 
621  Thread sleep times are measured in implementation-specific ticks rather
622  than ms, but the default is 100Hz so we divide by 10 to convert ms to
623  ticks */
624 
625 #define THREADFUNC_DEFINE( name, arg ) void name( cyg_addrword_t arg )
626 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
627  { \
628  BYTE *threadData = malloc( sizeof( cyg_thread ) + \
629  CYGNUM_HAL_STACK_SIZE_TYPICAL ); \
630  \
631  cyg_semaphore_init( &syncHandle, 0 ); \
632  cyg_thread_create( cyg_thread_get_priority( cyg_thread_self() ), \
633  function, ( cyg_addrword_t ) arg, NULL, \
634  threadData + sizeof( cyg_thread ), \
635  CYGNUM_HAL_STACK_SIZE_TYPICAL, \
636  &threadHandle, ( cyg_thread * ) threadData ); \
637  if( threadHandle <= 0 ) \
638  { \
639  free( threadData ); \
640  status = CRYPT_ERROR; \
641  } \
642  else \
643  { \
644  cyg_thread_resume( threadHandle ); \
645  status = CRYPT_OK; \
646  } \
647  }
648 #define THREAD_EXIT( sync ) cyg_semaphore_post( &sync ); \
649  cyg_thread_exit()
650 #define THREAD_INITIALISER 0
651 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
652 #define THREAD_SELF() cyg_thread_self()
653 #define THREAD_SLEEP( ms ) cyg_thread_delay( ( ms ) / 10 )
654 #define THREAD_YIELD() cyg_thread_yield()
655 #define THREAD_WAIT( sync, status ) \
656  if( !cyg_semaphore_wait( &sync ) ) \
657  status = CRYPT_ERROR; \
658  cyg_semaphore_destroy( &sync )
659 #define THREAD_CLOSE( sync ) cyg_thread_delete( &sync )
660 
661 /* Because of the problems with resource management of eCOS threads and
662  related metadata, we no-op them out unless we're using wrappers by
663  ensuring that any attempt to spawn a thread inside cryptlib fails,
664  falling back to the non-threaded alternative. Note that cryptlib itself
665  is still thread-safe, it just can't do its init or keygen in an internal
666  background thread */
667 
668 #ifndef ECOS_THREAD_WRAPPERS
669  #undef THREAD_CREATE
670  #undef THREAD_EXIT
671  #undef THREAD_CLOSE
672  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
673  status = CRYPT_ERROR
674  #define THREAD_EXIT( sync )
675  #define THREAD_CLOSE( sync )
676 #endif /* !ECOS_THREAD_WRAPPERS */
677 
678 /****************************************************************************
679 * *
680 * EmbOS *
681 * *
682 ****************************************************************************/
683 
684 #elif defined( __EmbOS__ )
685 
686 /* To use resource-management wrappers for the EmbOS thread functions,
687  undefine the following */
688 
689 /* #define EMBOS_THREAD_WRAPPERS */
690 
691 #include <RTOS.h>
692 
693 /* Object handles */
694 
695 #define THREAD_HANDLE OS_TASK *
696 #define MUTEX_HANDLE OS_RSEMA
697 
698 /* Since EmbOS has non-scalar handles we need to define a custom version of
699  the value DUMMY_INIT_MUTEX (see the end of this file) */
700 
701 #define NONSCALAR_THREADS
702 #define DUMMY_INIT_MUTEX { 0 }
703 
704 /* Mutex management functions. EmbOS mutexes are reentrant so we don't have
705  to hand-assemble reentrant mutexes as for many other OSes */
706 
707 #define MUTEX_DECLARE_STORAGE( name ) \
708  OS_RSEMA name##Mutex; \
709  BOOLEAN name##MutexInitialised
710 #define MUTEX_CREATE( name, status ) \
711  status = CRYPT_OK; /* Apparently never fails */ \
712  if( !krnlData->name##MutexInitialised ) \
713  { \
714  OS_CREATERSEMA( &krnlData->name##Mutex ); \
715  krnlData->name##MutexInitialised = TRUE; \
716  }
717 #define MUTEX_DESTROY( name ) \
718  if( krnlData->name##MutexInitialised ) \
719  { \
720  OS_Use( &krnlData->name##Mutex ); \
721  OS_Unuse( &krnlData->name##Mutex ); \
722  OS_DeleteRSema( &krnlData->name##Mutex ); \
723  krnlData->name##MutexInitialised = FALSE; \
724  }
725 #define MUTEX_LOCK( name ) \
726  OS_Use( &krnlData->name##Mutex )
727 #define MUTEX_UNLOCK( name ) \
728  OS_Unuse( &krnlData->name##Mutex )
729 
730 /* Thread management functions. EmbOS threads require that the user allocate
731  the stack space for them, unlike virtually every other embedded OS, which
732  make this at most a rarely-used option. To handle this, we use our own
733  wrappers, which hide this mess and provide access via a single scalar
734  variable.
735 
736  We create the thread with the same priority as the calling thread. There
737  doesn't seem to be any way to tell whether a thread has been successfully
738  created/started or not (!!). The stack size of 4096 provides enough space
739  for about half a dozen levels of function nesting (if no large on-stack
740  arrays are used), this should be enough for background init but probably
741  won't be sufficient for the infinitely-recursive OpenSSL bignum code, so
742  the value may need to be adjusted if background keygen is being used.
743 
744  The implementation of THREAD_SAME() is somewhat ugly in that since thread
745  data storage is handled by the caller rather than being allocated by the
746  OS we end up with a mixture of 'struct' (if we're referring to a block of
747  storage for the thread data) and 'struct *' (if we're referring to a thread
748  handle returned from a function like OS_GetTaskID()). THREAD_SAME() takes
749  advantage of the fact that when it's used, the first argument is always a
750  'struct' and the second is always a 'struct *', which is rather ugly but the
751  only other way to do it would be to wrap the thread functions with our own
752  code that dynamically allocates thread data so that all handles are
753  'struct *'s */
754 
755 #define THREADFUNC_DEFINE( name, arg ) void name( void *arg )
756 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
757  { \
758  BYTE *threadData = malloc( 4096 ); \
759  \
760  if( threadData == NULL ) \
761  status = CRYPT_ERROR_MEMORY; \
762  else \
763  { \
764  OS_CREATERSEMA( &syncHandle ); \
765  OS_CREATETASK_EX( threadHandle, NULL, function, \
766  OS_GetPriority( NULL ), threadData, arg ); \
767  status = CRYPT_OK; \
768  } \
769  }
770 #define THREAD_EXIT( sync ) OS_Unuse( ( OS_RSEMA * ) &sync ); \
771  OS_Terminate( OS_GetTaskID() )
772 #define THREAD_INITIALISER { 0 }
773 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
774 #define THREAD_SELF() OS_GetTaskID()
775 #define THREAD_SLEEP( ms ) OS_Delay( ms )
776 #define THREAD_YIELD() OS_Yield()
777 #define THREAD_WAIT( sync, status ) \
778  OS_Use( &sync ); \
779  OS_DeleteRSema( &sync ); \
780  status = CRYPT_OK
781 #define THREAD_CLOSE( sync )
782 
783 /* Because of the problems with resource management of EmbOS threads and
784  related metadata, we no-op them out unless we're using wrappers by
785  ensuring that any attempt to spawn a thread inside cryptlib fails,
786  falling back to the non-threaded alternative. Note that cryptlib itself
787  is still thread-safe, it just can't do its init or keygen in an internal
788  background thread */
789 
790 #ifndef EMBOS_THREAD_WRAPPERS
791  #undef THREAD_CREATE
792  #undef THREAD_EXIT
793  #undef THREAD_CLOSE
794  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
795  status = CRYPT_ERROR
796  #define THREAD_EXIT( sync )
797  #define THREAD_CLOSE( sync )
798 #endif /* !EMBOS_THREAD_WRAPPERS */
799 
800 /****************************************************************************
801 * *
802 * FreeRTOS/OpenRTOS *
803 * *
804 ****************************************************************************/
805 
806 #elif defined( __FreeRTOS__ )
807 
808 #include <FreeRTOS.h>
809 #include <task.h>
810 #include <semphr.h>
811 
812 /* Object handles */
813 
814 #define THREAD_HANDLE xTaskHandle
815 #define MUTEX_HANDLE xSemaphoreHandle
816 
817 /* Mutex management functions. Mutexes aren't recursive but binary
818  semaphores are so we use those instead of mutexes. In addition most of
819  the functions are implemented via macros rather than functions so we use
820  the handles directly instead of passing a reference. Finally, there's no
821  way to destroy/clean up a mutex after it's been created because the kernel
822  and code are linked into a single monolithic blob that's running the
823  entire time, so we don't perform any explicit cleanup */
824 
825 #define MUTEX_WAIT_TIME ( 5000 / portTICK_RATE_MS )
826 
827 #define MUTEX_DECLARE_STORAGE( name ) \
828  xSemaphoreHandle name##Mutex; \
829  BOOLEAN name##MutexInitialised
830 #define MUTEX_CREATE( name, status ) \
831  status = CRYPT_OK; \
832  if( !krnlData->name##MutexInitialised ) \
833  { \
834  vSemaphoreCreateBinary( krnlData->name##Mutex ); \
835  if( krnlData->name##Mutex == NULL ) \
836  status = CRYPT_ERROR; \
837  else \
838  { \
839  krnlData->name##MutexInitialised = TRUE; \
840  status = CRYPT_OK; \
841  } \
842  }
843 #define MUTEX_DESTROY( name ) \
844  if( krnlData->name##MutexInitialised ) \
845  { \
846  xSemaphoreTakeRecursive( krnlData->name##Mutex, \
847  MUTEX_WAIT_TIME ); \
848  xSemaphoreGiveRecursive( krnlData->name##Mutex ); \
849  krnlData->name##MutexInitialised = FALSE; \
850  }
851 #define MUTEX_LOCK( name ) \
852  xSemaphoreTakeRecursive( krnlData->name##Mutex, \
853  MUTEX_WAIT_TIME )
854 #define MUTEX_UNLOCK( name ) \
855  xSemaphoreGiveRecursive( krnlData->name##Mutex )
856 
857 /* Thread management functions. FreeRTOS threads are generally sensible and
858  don't require user management of stack space as with many other
859  minimalist embedded OSes, although they do have the peculiarity that the
860  stack size is given as a "depth" rather than an actual stack size, where
861  the total size is defined by "depth" x "width" (= machine word size) */
862 
863 #define STACK_DEPTH 8192
864 
865 #define THREADFUNC_DEFINE( name, arg ) void name( void *arg )
866 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
867  { \
868  portBASE_TYPE result; \
869  \
870  syncHandle = xSemaphoreCreateMutex(); \
871  xSemaphoreTake( syncHandle, MUTEX_WAIT_TIME ); \
872  result = xTaskCreate( function, "clibTask", STACK_DEPTH, \
873  arg, tskIDLE_PRIORITY, &threadHandle ); \
874  if( result != pdPASS ) \
875  status = CRYPT_ERROR; \
876  else \
877  status = CRYPT_OK; \
878  }
879 #define THREAD_EXIT( sync ) xSemaphoreGive( &sync )
880 #define THREAD_INITIALISER 0
881 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
882 #define THREAD_SELF() xTaskGetCurrentTaskHandle()
883 #define THREAD_SLEEP( ms ) vTaskDelay( ( ms ) / portTICK_RATE_MS )
884 #define THREAD_YIELD() taskYIELD()
885 #define THREAD_WAIT( sync, status ) \
886  if( xSemaphoreTake( sync, MUTEX_WAIT_TIME ) != pdTRUE ) \
887  status = CRYPT_ERROR
888 #define THREAD_CLOSE( sync ) vTaskDelete( &sync )
889 
890 /****************************************************************************
891 * *
892 * IBM 4758 *
893 * *
894 ****************************************************************************/
895 
896 #elif defined( __IBM4758__ )
897 
898 #include <cpqlib.h>
899 
900 /* Object handles */
901 
902 #define THREAD_HANDLE long
903 #define MUTEX_HANDLE long
904 
905 /* Mutex management functions */
906 
907 #define MUTEX_DECLARE_STORAGE( name ) \
908  long name##Semaphore; \
909  BOOLEAN name##SemaphoreInitialised
910 #define MUTEX_CREATE( name, status ) \
911  status = CRYPT_OK; \
912  if( !krnlData->name##SemaphoreInitialised ) \
913  { \
914  if( CPCreateSerSem( NULL, 0, 0, \
915  &krnlData->name##Semaphore ) == 0 ) \
916  krnlData->name##SemaphoreInitialised = TRUE; \
917  else \
918  status = CRYPT_ERROR; \
919  }
920 #define MUTEX_DESTROY( name ) \
921  if( krnlData->name##SemaphoreInitialised ) \
922  { \
923  CPSemClaim( krnlData->name##Semaphore, SVCWAITFOREVER ); \
924  CPSemRelease( krnlData->name##Semaphore ); \
925  CPDelete( krnlData->name##Semaphore, 0 ); \
926  krnlData->name##SemaphoreInitialised = FALSE; \
927  }
928 #define MUTEX_LOCK( name ) \
929  CPSemClaim( krnlData->name##Semaphore, SVCWAITFOREVER )
930 #define MUTEX_UNLOCK( name ) \
931  CPSemRelease( krnlData->name##Semaphore )
932 
933 /* Thread management functions. CP/Q doesn't use threads but only supports
934  CP/Q tasks. These function in a somewhat peculiar manner, so this
935  facility isn't currently used */
936 
937 /****************************************************************************
938 * *
939 * uITRON *
940 * *
941 ****************************************************************************/
942 
943 #elif defined( __ITRON__ )
944 
945 /* In the following includes, kernel.h is the uITRON kernel.h, not the
946  cryptlib one */
947 
948 #include <itron.h>
949 #include <kernel.h>
950 
951 /* Object handles */
952 
953 #define THREAD_HANDLE ID
954 #define MUTEX_HANDLE ID
955 
956 /* Mutex management functions. We could use either semaphores or mutexes
957  for this, semaphores are supported under uITRON 3.0 but since we're
958  using automatic assignment of handles (which requires uITRON 4.0) we may
959  as well use mutexes */
960 
961 #define MUTEX_DECLARE_STORAGE( name ) \
962  ID name##Mutex; \
963  BOOLEAN name##MutexInitialised; \
964  ID name##MutexOwner; \
965  int name##MutexLockcount
966 #define MUTEX_CREATE( name, status ) \
967  status = CRYPT_OK; \
968  if( !krnlData->name##MutexInitialised ) \
969  { \
970  static const T_CMTX pk_cmtx = { TA_TFIFO, 0, 0 }; \
971  \
972  if( ( krnlData->name##Mutex = \
973  acre_mtx( ( T_CMTX * ) &pk_cmtx ) ) < E_OK ) \
974  status = CRYPT_ERROR; \
975  else \
976  krnlData->name##MutexInitialised = TRUE; \
977  }
978 #define MUTEX_DESTROY( name ) \
979  if( krnlData->name##MutexInitialised ) \
980  { \
981  loc_mtx( krnlData->name##Mutex ); \
982  unl_mtx( krnlData->name##Mutex ); \
983  del_mtx( krnlData->name##Mutex ); \
984  krnlData->name##MutexInitialised = FALSE; \
985  }
986 #define MUTEX_LOCK( name ) \
987  if( ploc_mtx( krnlData->name##Mutex ) == E_ILUSE ) \
988  { \
989  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
990  loc_mtx( krnlData->name##Mutex ); \
991  else \
992  krnlData->name##MutexLockcount++; \
993  } \
994  krnlData->name##MutexOwner = threadSelf();
995 #define MUTEX_UNLOCK( name ) \
996  if( krnlData->name##MutexLockcount > 0 ) \
997  krnlData->name##MutexLockcount--; \
998  else \
999  { \
1000  krnlData->name##MutexOwner = THREAD_INITIALISER; \
1001  unl_mtx( krnlData->name##Mutex ); \
1002  }
1003 
1004 /* Thread management functions. The attributes for task creation are:
1005 
1006  TA_HLNG | TA_ACT -- C interface, create task in the active rather
1007  than suspended state (otherwise we'd have to use
1008  act_tsk() to activate it a la BeOS).
1009  arg -- Task extended info.
1010  function -- Task function.
1011  TPRI_SELF -- Same priority as invoking task.
1012  16384 -- Stack size.
1013  NULL -- Auto-allocate stack. This is given as 0 rather
1014  than NULL since some uITRON headers define their
1015  own NULL as 0, leading to compiler warnings.
1016 
1017  uITRON status values are 8:8 bit pairs with the actual status in the
1018  low 8 bits. The sub-values can be extracted with the MERCD() and SERCD()
1019  (main- and sub-error-code) macros, however simply using the MERCD()
1020  result isn't safe because it could be the (negative) low 8 bits of a
1021  (positive overall) return value. When creating a task we therefore
1022  consider a status < E_OK as being an error, without trying to pick apart
1023  the overall value.
1024 
1025  The handling of initialisers is a bit dodgy since TSK_NONE == TSK_SELF
1026  (== 0) and it isn't even safe to use negative values since in some cases
1027  these can be valid system task handles. In general however uITRON
1028  numbers IDs from 1...n, so using 0 as a non-value is safe.
1029 
1030  Handling of task sleep is also somewhat dodgy, time is measured in clock
1031  ticks of an implementation-specific duration, the best that we can do is
1032  to assume that it's close enough to ms.
1033 
1034  In theory we don't really need to use exd_tsk() since returning from a
1035  task ends it, but we make it explicit to be neat */
1036 
1037 #define THREADFUNC_DEFINE( name, arg ) void name( VP_INT *arg )
1038 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1039  { \
1040  static const T_CSEM pk_csem = { TA_TFIFO, 1, 64 }; \
1041  T_CTSK pk_ctsk = { TA_HLNG | TA_ACT, ( arg ), ( function ), \
1042  TPRI_SELF, 16384, 0 }; \
1043  \
1044  syncHandle = acre_sem( ( T_CSEM * ) &pk_csem ); \
1045  threadHandle = acre_tsk( &pk_ctsk ); \
1046  if( threadHandle < E_OK ) \
1047  { \
1048  del_sem( syncHandle ); \
1049  status = CRYPT_ERROR; \
1050  } \
1051  else \
1052  status = CRYPT_OK; \
1053  }
1054 #define THREAD_EXIT( sync ) sig_sem( sync ); \
1055  exd_tsk()
1056 #define THREAD_INITIALISER TSK_NONE
1057 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1058 #define THREAD_SELF() threadSelf()
1059 #define THREAD_SLEEP( ms ) dly_tsk( ms )
1060 #define THREAD_YIELD() dly_tsk( 0 )
1061 #define THREAD_WAIT( sync, status ) \
1062  if( wai_sem( sync ) != E_OK ) \
1063  status = CRYPT_ERROR; \
1064  del_sem( sync )
1065 #define THREAD_CLOSE( sync )
1066 
1067 /* The uITRON thread-self function returns the thread ID via a reference
1068  parameter since uITRON IDs can be negative and there'd be no way to
1069  differentiate a thread ID from an error code. Because of this we have
1070  to provide a wrapper that returns it as a return value */
1071 
1072 ID threadSelf( void );
1073 
1074 /****************************************************************************
1075 * *
1076 * MQX *
1077 * *
1078 ****************************************************************************/
1079 
1080 #elif defined( __MQX__ )
1081 
1082 #include <mqx.h>
1083 
1084 /* Object handles */
1085 
1086 #define THREAD_HANDLE _task_id
1087 #define MUTEX_HANDLE MUTEX_STRUCT
1088 
1089 /* Mutex management functions. It's unclear whether MQX mutexes are
1090  reentrant or not, if they aren't then the following macros would need
1091  to be changed to hand-assemble reentrant mutexes as is done for many
1092  other OSes */
1093 
1094 #define MUTEX_DECLARE_STORAGE( name ) \
1095  MUTEX_HANDLE name##Mutex; \
1096  BOOLEAN name##MutexInitialised
1097 #define MUTEX_CREATE( name, status ) \
1098  status = CRYPT_OK; \
1099  if( !krnlData->name##MutexInitialised ) \
1100  { \
1101  if( _mutex_init( &krnlData->name##Mutex, NULL ) == MQX_OK ) \
1102  krnlData->name##MutexInitialised = TRUE; \
1103  else \
1104  status = CRYPT_ERROR; \
1105  }
1106 #define MUTEX_DESTROY( name ) \
1107  if( krnlData->name##MutexInitialised ) \
1108  { \
1109  _mutex_lock( &krnlData->name##Mutex ); \
1110  _mutex_unlock( &krnlData->name##Mutex ); \
1111  _mutex_destroy( &krnlData->name##Mutex ); \
1112  krnlData->name##MutexInitialised = FALSE; \
1113  }
1114 #define MUTEX_LOCK( name ) \
1115  _mutex_lock( &krnlData->name##Mutex )
1116 #define MUTEX_UNLOCK( name ) \
1117  _mutex_unlock( &krnlData->name##Mutex )
1118 
1119 /* Thread management functions. MQX's task creation is weird in that it
1120  doesn't take task parameters like any other OS but requres an integer
1121  that identifies an entry in a list of task templates that was specified at
1122  compile time. This is weird in that we can't simply start an arbitrary
1123  task by specifying its function name but have to refer to it indirectly.
1124  Fortunately the only time this capability is used is when we're performing
1125  an async init, if it were used in other locations then it'd be necessary
1126  to have THREAD_CREATE compare the 'function' value passed to it with a
1127  built-in list and map that to an integer ID for _task_create(), which then
1128  maps it back to a function name.
1129 
1130  To deal with this strangeness you need to define an entry in your app's
1131  TASK_TEMPLATE_STRUCT list something like the following:
1132 
1133  { 0x100, threadedBind, 16384, 15, NULL, 0, 0, 0 }
1134 
1135  which creates a non-auto-start task with FIFO scheduling and a default
1136  timeslice. Unfortunately because of this bizarre way of specifying things
1137  we can't set the priority in any sane way, normally we'd use
1138  _task_get_priority() with MQX_NULL_TASK_ID to get the current task's
1139  priority but this doesn't work because the value has to be allocated at
1140  compile time. We give the task a mid-range priority value of 15 (from a
1141  range of 0 = highest ... 31 = lowest), this is somewhat ugly but there
1142  doesn't seem to be much else that we can do */
1143 
1144 #define THREADFUNC_DEFINE( name, arg ) void name( uint32 /* = void* */ arg )
1145 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1146  { \
1147  _lwsem_create( &syncHandle, 1 ); \
1148  threadHandle = _task_create( 0, 0x100, ( uint32 ) arg ); \
1149  if( threadHandle == MQX_NULL_TASK_ID ) \
1150  status = CRYPT_ERROR; \
1151  else \
1152  status = CRYPT_OK; \
1153  }
1154 #define THREAD_EXIT( sync ) _lwsem_post( &sync ); \
1155  _task_destroy( MQX_NULL_TASK_ID )
1156 #define THREAD_INITIALISER 0
1157 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1158 #define THREAD_SELF() _task_get_id()
1159 #define THREAD_SLEEP( ms ) _time_delay( ms )
1160 #define THREAD_YIELD() _sched_yield()
1161 #define THREAD_WAIT( sync, status ) \
1162  if( _lwsem_wait( &sync ) != MQX_OK ) \
1163  status = CRYPT_ERROR; \
1164  _lwsem_destroy( &sync )
1165 #define THREAD_CLOSE( sync )
1166 
1167 /****************************************************************************
1168 * *
1169 * OS/2 *
1170 * *
1171 ****************************************************************************/
1172 
1173 #elif defined( __OS2__ )
1174 
1175 #define INCL_DOSSEMAPHORES
1176 #define INCL_DOSMISC
1177 #define INCL_DOSFILEMGR
1178 #define INCL_DOSMISC
1179 #define INCL_DOSDATETIME
1180 #define INCL_DOSPROCESS
1181 #define INCL_WINWINDOWMGR
1182 #define INCL_WINSYS
1183 #include <os2.h>
1184 ULONG DosGetThreadID( void );
1185 
1186 /* Object handles */
1187 
1188 #define THREAD_HANDLE TID
1189 #define MUTEX_HANDLE HEV
1190 
1191 /* Mutex management functions */
1192 
1193 #define MUTEX_DECLARE_STORAGE( name ) \
1194  HMTX name##Mutex; \
1195  BOOLEAN name##MutexInitialised
1196 #define MUTEX_CREATE( name, status ) \
1197  status = CRYPT_OK; \
1198  if( !krnlData->name##MutexInitialised ) \
1199  { \
1200  if( DosCreateMutexSem( NULL, &krnlData->name##Mutex, 0L, \
1201  FALSE ) == NO_ERROR ) \
1202  krnlData->name##MutexInitialised = TRUE; \
1203  else \
1204  status = CRYPT_ERROR; \
1205  }
1206 #define MUTEX_DESTROY( name ) \
1207  if( krnlData->name##MutexInitialised ) \
1208  { \
1209  DosRequestMutexSem( krnlData->name##Mutex, \
1210  ( ULONG ) SEM_INDEFINITE_WAIT ); \
1211  DosReleaseMutexSem( krnlData->name##Mutex ); \
1212  DosCloseMutexSem( krnlData->name##Mutex ); \
1213  krnlData->name##MutexInitialised = FALSE; \
1214  }
1215 #define MUTEX_LOCK( name ) \
1216  DosRequestMutexSem( krnlData->name##Mutex, \
1217  ( ULONG ) SEM_INDEFINITE_WAIT )
1218 #define MUTEX_UNLOCK( name ) \
1219  DosReleaseMutexSem( krnlData->name##Mutex )
1220 
1221 /* Thread management functions */
1222 
1223 #define THREADFUNC_DEFINE( name, arg ) void _Optlink name( void *arg )
1224 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1225  { \
1226  threadHandle = syncHandle = \
1227  _beginthread( ( function ), NULL, 8192, ( arg ) ); \
1228  status = ( threadHandle == -1 ) ? CRYPT_ERROR : CRYPT_OK ); \
1229  }
1230 #define THREAD_EXIT( sync ) _endthread()
1231 #define THREAD_INITIALISER 0
1232 #define THREAD_SELF() DosGetThreadID()
1233 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1234 #define THREAD_SLEEP( ms ) DosWait( ms )
1235 #define THREAD_YIELD() DosWait( 0 )
1236 #define THREAD_WAIT( sync, status ) \
1237  if( DosWaitThread( sync, INFINITE ) != NO_ERROR ) \
1238  status = CRYPT_ERROR
1239 #define THREAD_CLOSE( sync )
1240 
1241 /****************************************************************************
1242 * *
1243 * PalmOS *
1244 * *
1245 ****************************************************************************/
1246 
1247 #elif defined( __PALMOS__ )
1248 
1249 #include <CmnErrors.h>
1250 #include <SysThread.h>
1251 
1252 /* Object handles */
1253 
1254 #define THREAD_HANDLE SysHandle
1255 #define MUTEX_HANDLE SysHandle
1256 
1257 /* Mutex management functions. These are just initialised in a slightly
1258  odd manner, there isn't any function to explicitly initialise them but
1259  instead they're statically initialised to a fixed value (NULL), when
1260  the lock/unlock functions are passed this value they perform the
1261  initialisation on-demand. This means that if the underlying hardware
1262  supports it they can be implemented using atomic operations directly
1263  on the critical-section value without having to allocate memory for
1264  a struct to contain the critical-section data */
1265 
1266 #define MUTEX_DECLARE_STORAGE( name ) \
1267  SysCriticalSectionType name##Mutex; \
1268  BOOLEAN name##MutexInitialised
1269 #define MUTEX_CREATE( name, status ) \
1270  status = CRYPT_OK; \
1271  if( !krnlData->name##MutexInitialised ) \
1272  { \
1273  krnlData->name##Mutex = sysCriticalSectionInitializer; \
1274  krnlData->name##MutexInitialised = TRUE; \
1275  }
1276 #define MUTEX_DESTROY( name ) \
1277  if( krnlData->name##MutexInitialised ) \
1278  { \
1279  SysCriticalSectionEnter( &krnlData->name##Mutex ); \
1280  SysCriticalSectionExit( &krnlData->name##Mutex ); \
1281  krnlData->name##Mutex = sysCriticalSectionInitializer; \
1282  krnlData->name##MutexInitialised = FALSE; \
1283  }
1284 #define MUTEX_LOCK( name ) \
1285  SysCriticalSectionEnter( &krnlData->name##Mutex )
1286 #define MUTEX_UNLOCK( name ) \
1287  SysCriticalSectionExit( &krnlData->name##Mutex )
1288 
1289 /* Thread management functions. PalmOS threads are created in the suspended
1290  state, so after we create the thread we have to explicitly start it to
1291  get it running. The default stack size (via SysThreadCreateEZ()) is a
1292  pathetic 4K for standard threads or 8K for UI threads, to avoid this we
1293  have to use the full SysThreadCreate() and specify our own stack size */
1294 
1295 #define THREADFUNC_DEFINE( name, arg ) void name( void *arg )
1296 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1297  { \
1298  SysSemaphoreCreateEZ( 0, ( SysHandle * ) &syncHandle ); \
1299  if( SysThreadCreate( sysThreadNoGroup, "", \
1300  sysThreadPriorityNormal, 32768, function, \
1301  arg, &threadHandle ) != errNone ) \
1302  { \
1303  SysSemaphoreDestroy( syncHandle ); \
1304  status = CRYPT_ERROR; \
1305  } \
1306  else \
1307  { \
1308  SysThreadStart( threadHandle ); \
1309  status = CRYPT_OK; \
1310  } \
1311  }
1312 #define THREAD_EXIT( sync ) SysSemaphoreSignal( sync ); \
1313  SysThreadExit()
1314 #define THREAD_INITIALISER 0
1315 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1316 #define THREAD_SELF() SysCurrentThread()
1317 #define THREAD_SLEEP( ms ) SysThreadDelay( ( ms ) * 1000000L, P_ABSOLUTE_TIMEOUT )
1318 #define THREAD_YIELD() SysThreadDelay( 0, P_POLL )
1319 #define THREAD_WAIT( sync, status ) \
1320  if( SysSemaphoreWait( sync, P_WAIT_FOREVER, 0 ) != errNone ) \
1321  status = CRYPT_ERROR; \
1322  SysSemaphoreDestroy( sync )
1323 #define THREAD_CLOSE( sync )
1324 
1325 /****************************************************************************
1326 * *
1327 * RTEMS *
1328 * *
1329 ****************************************************************************/
1330 
1331 #elif defined( __RTEMS__ )
1332 
1333 #include <rtems.h>
1334 
1335 /* Object handles. These are actually multi-component object IDs, but they
1336  act like standard handles */
1337 
1338 #define THREAD_HANDLE rtems_id
1339 #define MUTEX_HANDLE rtems_id
1340 
1341 /* RTEMS objects have names, which aren't really names but 32-bit integer
1342  tags (the term 'name' comes from the fact that they can be initialised
1343  to four ASCII chars like original Mac resource IDs). Since we don't
1344  really care about names, we pass in a dummy name value for all of our
1345  calls */
1346 
1347 #define NO_NAME 0
1348 
1349 /* Mutex management functions. RTEMS semaphores (or at least standard
1350  counting semaphores, which is what we're using here) are re-entrant so
1351  we don't have to jump through the hoops that are necessary with most
1352  other OSes.
1353 
1354  We specify the priority ceiling as zero since it's not used for the
1355  semaphore type that we're creating */
1356 
1357 #define MUTEX_DECLARE_STORAGE( name ) \
1358  rtems_id name##Mutex; \
1359  BOOLEAN name##MutexInitialised
1360 #define MUTEX_CREATE( name, status ) \
1361  status = CRYPT_OK; \
1362  if( !krnlData->name##MutexInitialised ) \
1363  { \
1364  if( rtems_semaphore_create( NO_NAME, 1, RTEMS_DEFAULT_ATTRIBUTES, 0, \
1365  &krnlData->name##Mutex ) == RTEMS_SUCCESSFUL ) \
1366  krnlData->name##MutexInitialised = TRUE; \
1367  else \
1368  status = CRYPT_ERROR; \
1369  }
1370 #define MUTEX_DESTROY( name ) \
1371  if( krnlData->name##MutexInitialised ) \
1372  { \
1373  rtems_semaphore_obtain( krnlData->name##Mutex, RTEMS_WAIT, 0 ); \
1374  rtems_semaphore_release( krnlData->name##Mutex ); \
1375  rtems_semaphore_delete( krnlData->name##Mutex ); \
1376  krnlData->name##MutexInitialised = FALSE; \
1377  }
1378 #define MUTEX_LOCK( name ) \
1379  rtems_semaphore_obtain( krnlData->name##Mutex, RTEMS_WAIT, 0 );
1380 #define MUTEX_UNLOCK( name ) \
1381  rtems_semaphore_release( krnlData->name##Mutex );
1382 
1383 /* Thread management functions. RTEMS tasks are created in the suspended
1384  state, so after we create the task we have to resume it to start it
1385  running. The attributes for task creation are:
1386 
1387  NO_NAME -- Task name.
1388  RTEMS_CURRENT_PRIORITY -- Task priority. The documentation is unclear
1389  as to whether we can specify this directly as
1390  the priority or have to obtain it via a call,
1391  we use the call to be safe.
1392  RTEMS_STACK_SIZE -- Task stack size. We use the default size for
1393  RTEMS tasks.
1394  RTEMS_ASR | \ -- Task mode: Enable async signal processing
1395  RTEMS_INT_LEVEL(0) | \ (default), all interrupts enabled (default),
1396  RTEMS_PREEMPT | \ preemptive scheduling (default), timeslicing
1397  RTEMS_TIMESLICE for tasks of the same priority.
1398  RTEMS_DEFAULT_ATTRIBUTES-- Task attributes: Local task, no FP regs.
1399 
1400  Specifying the default values for the task mode is optional, but we do it
1401  anyway to make the behaviour explicit.
1402 
1403  We could make the synchronisation semaphore a binary semaphore, but
1404  there's no indication that this is any more efficient than a counting
1405  semaphore, and it saves having to create a long list of (non-default)
1406  attributes to specify this.
1407 
1408  Task sleep times are measured in implementation-specific ticks rather
1409  than ms, but the default is 10ms so we divide by 10. If necessary the
1410  absolute value can be calculated from the microseconds_per_tick field in
1411  the RTEMS configuration table or from CONFIGURE_MICROSECONDS_PER_TICK in
1412  confdefs.h */
1413 
1414 #define TASK_MODE ( RTEMS_ASR | RTEMS_INTERRUPT_LEVEL(0) | \
1415  RTEMS_PREEMPT | RTEMS_TIMESLICE )
1416 
1417 #define THREADFUNC_DEFINE( name, arg ) rtems_task name( rtems_task_argument arg )
1418 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1419  { \
1420  rtems_status_code rtemsStatus; \
1421  rtems_task_priority rtemsPriority; \
1422  \
1423  rtems_task_set_priority( RTEMS_SELF, RTEMS_CURRENT_PRIORITY, \
1424  &rtemsPriority ); \
1425  rtems_semaphore_create( NO_NAME, 1, RTEMS_DEFAULT_ATTRIBUTES, 0, \
1426  &syncHandle ); \
1427  rtemsStatus = rtems_task_create( NO_NAME, rtemsPriority, \
1428  RTEMS_STACK_SIZE, TASK_MODE, \
1429  RTEMS_DEFAULT_ATTRIBUTES, \
1430  &threadHandle ); \
1431  if( rtemsStatus == RTEMS_SUCCESSFUL ) \
1432  rtemsStatus = rtems_task_start( threadHandle, function, \
1433  ( rtems_task_argument ) arg ); \
1434  if( rtemsStatus == RTEMS_SUCCESSFUL ) \
1435  status = CRYPT_OK; \
1436  else \
1437  { \
1438  rtems_semaphore_delete( syncHandle ); \
1439  status = CRYPT_ERROR; \
1440  } \
1441  }
1442 #define THREAD_EXIT( sync ) rtems_semaphore_release( sync ); \
1443  rtems_task_delete( RTEMS_SELF );
1444 #define THREAD_INITIALISER 0
1445 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1446 #define THREAD_SELF() threadSelf()
1447 #define THREAD_SLEEP( ms ) rtems_task_wake_after( ( ms ) / 10 )
1448 #define THREAD_YIELD() rtems_task_wake_after( RTEMS_YIELD_PROCESSOR )
1449 #define THREAD_WAIT( sync, status ) \
1450  if( rtems_semaphore_obtain( sync, RTEMS_WAIT, 0 ) != RTEMS_SUCCESSFUL ) \
1451  status = CRYPT_ERROR; \
1452  else \
1453  rtems_semaphore_release( sync ); \
1454  rtems_semaphore_delete( sync )
1455 #define THREAD_CLOSE( sync )
1456 
1457 /* The RTEMS thread-self function returns the task ID via a reference
1458  parameter, because of this we have to provide a wrapper that returns it
1459  as a return value */
1460 
1461 rtems_id threadSelf( void );
1462 
1463 /****************************************************************************
1464 * *
1465 * ThreadX *
1466 * *
1467 ****************************************************************************/
1468 
1469 #elif defined( __ThreadX__ )
1470 
1471 /* To use resource-management wrappers for the ThreadX thread functions,
1472  undefine the following */
1473 
1474 /* #define THREADX_THREAD_WRAPPERS */
1475 
1476 //#include <tx_api.h>
1477 #pragma message( "ThreadX header path faked" )
1478 #include <threadx_tx_api.h>
1479 
1480 /* Object handles */
1481 
1482 #define THREAD_HANDLE TX_THREAD *
1483 #define MUTEX_HANDLE TX_MUTEX
1484 
1485 /* Since ThreadX has non-scalar handles we need to define a custom version
1486  of the value DUMMY_INIT_MUTEX (see the end of this file) */
1487 
1488 #define NONSCALAR_THREADS
1489 #define DUMMY_INIT_MUTEX { 0 }
1490 
1491 /* Mutex management functions. ThreadX mutexes are reentrant so we don't
1492  have to hand-assemble reentrant mutexes as for many other OSes. All
1493  ThreadX objects have names (presumably for debugging) but what the
1494  requirements for these are aren't documented so we just use a dummy name
1495  for everything. Since we don't care whether the threads waiting on the
1496  mutex get woken up in priority order, we use TX_NO_INHERIT to ignore
1497  priority inheritance */
1498 
1499 #define MUTEX_DECLARE_STORAGE( name ) \
1500  TX_MUTEX name##Mutex; \
1501  BOOLEAN name##MutexInitialised
1502 #define MUTEX_CREATE( name, status ) \
1503  status = CRYPT_OK; \
1504  if( !krnlData->name##MutexInitialised ) \
1505  { \
1506  if( tx_mutex_create( &krnlData->name##Mutex, "name", \
1507  TX_NO_INHERIT ) == TX_SUCCESS ) \
1508  krnlData->name##MutexInitialised = TRUE; \
1509  else \
1510  status = CRYPT_ERROR; \
1511  }
1512 #define MUTEX_DESTROY( name ) \
1513  if( krnlData->name##MutexInitialised ) \
1514  { \
1515  tx_mutex_get( &krnlData->name##Mutex, TX_WAIT_FOREVER ); \
1516  tx_mutex_put( &krnlData->name##Mutex ); \
1517  tx_mutex_delete( &krnlData->name##Mutex ); \
1518  krnlData->name##MutexInitialised = FALSE; \
1519  }
1520 #define MUTEX_LOCK( name ) \
1521  tx_mutex_get( &krnlData->name##Mutex, TX_WAIT_FOREVER )
1522 #define MUTEX_UNLOCK( name ) \
1523  tx_mutex_put( &krnlData->name##Mutex )
1524 
1525 /* Thread management functions. ThreadX threads require that the user
1526  allocate the stack space for them, unlike virtually every other embedded
1527  OS, which make this at most a rarely-used option. To handle this, we use
1528  our own wrappers.
1529 
1530  The thread function's argument is a ULONG, since we use this as a pointer
1531  to parameter data we declare it as a 'void *' since that's how it's
1532  treated in practice.
1533 
1534  We give the thread a mid-range priority value and preemption threshold of
1535  15 (from a range of 0 = highest ... 31 = lowest) and a 50-tick timeslice.
1536  The timeslice value is HAL-dependent so it's not really possible to tell
1537  how much runtime this will actually give the thread, anyone using cryptlib
1538  with ThreadX will need to set an appropriate value for their HAL. The
1539  same goes for the sleep time, the code assumes that 1 tick = 10ms so we
1540  divide by 10 to convert ms to ticks */
1541 
1542 #define THREADFUNC_DEFINE( name, arg ) VOID name( void * /*ULONG*/ arg )
1543 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1544  { \
1545  BYTE *threadData = malloc( 16384 ); \
1546  \
1547  tx_mutex_create( &syncHandle, "name", TX_NO_INHERIT ); \
1548  if( tx_thread_create( &threadHandle, "name", function, \
1549  ( ULONG ) arg, threadData, 16384, \
1550  15, 50, 15, TX_AUTO_START ) != TX_SUCCESS ) \
1551  { \
1552  free( threadData ); \
1553  status = CRYPT_ERROR; \
1554  } \
1555  else \
1556  status = CRYPT_OK; \
1557  }
1558 #define THREAD_EXIT( sync ) tx_mutex_put( &sync ); \
1559  tx_thread_terminate( tx_thread_identify() )
1560 #define THREAD_INITIALISER 0
1561 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1562 #define THREAD_SELF() tx_thread_identify()
1563 #define THREAD_SLEEP( ms ) tx_thread_sleep( ( ms ) / 10 )
1564 #define THREAD_YIELD() tx_thread_relinquish()
1565 #define THREAD_WAIT( sync, status ) \
1566  if( !tx_mutex_get( &sync, TX_WAIT_FOREVER ) ) \
1567  status = CRYPT_ERROR; \
1568  tx_mutex_delete( &sync )
1569 #define THREAD_CLOSE( sync ) tx_thread_delete( &sync )
1570 
1571 /* Because of the problems with resource management of ThreadX threads and
1572  related metadata we no-op them out unless we're using wrappers by
1573  ensuring that any attempt to spawn a thread inside cryptlib fails,
1574  falling back to the non-threaded alternative. Note that cryptlib itself
1575  is still thread-safe, it just can't do its init or keygen in an internal
1576  background thread */
1577 
1578 #ifndef THREADX_THREAD_WRAPPERS
1579  #undef THREAD_CREATE
1580  #undef THREAD_EXIT
1581  #undef THREAD_CLOSE
1582  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1583  status = CRYPT_ERROR
1584  #define THREAD_EXIT( sync )
1585  #define THREAD_CLOSE( sync )
1586 #endif /* !THREADX_THREAD_WRAPPERS */
1587 
1588 /****************************************************************************
1589 * *
1590 * T-Kernel *
1591 * *
1592 ****************************************************************************/
1593 
1594 #elif defined( __TKernel__ )
1595 
1596 #include <tkernel.h>
1597 
1598 /* Object handles */
1599 
1600 #define THREAD_HANDLE ID
1601 #define MUTEX_HANDLE ID
1602 
1603 /* Mutex management functions. We could use either semaphores or mutexes
1604  for this, semaphores are supported under uITRON 3.0 but since we're
1605  using automatic assignment of handles (which requires uITRON 4.0) we may
1606  as well use mutexes */
1607 
1608 #define MUTEX_DECLARE_STORAGE( name ) \
1609  ID name##Mutex; \
1610  BOOLEAN name##MutexInitialised; \
1611  ID name##MutexOwner; \
1612  int name##MutexLockcount
1613 #define MUTEX_CREATE( name, status ) \
1614  status = CRYPT_OK; \
1615  if( !krnlData->name##MutexInitialised ) \
1616  { \
1617  static const T_CMTX pk_cmtx = { NULL, TA_TFIFO, 0 }; \
1618  \
1619  if( ( krnlData->name##Mutex = \
1620  tk_cre_mtx( &pk_cmtx ) ) < E_OK ) \
1621  status = CRYPT_ERROR; \
1622  else \
1623  krnlData->name##MutexInitialised = TRUE; \
1624  }
1625 #define MUTEX_DESTROY( name ) \
1626  if( krnlData->name##MutexInitialised ) \
1627  { \
1628  tk_loc_mtx( krnlData->name##Mutex, TMO_FEVR ); \
1629  tk_unl_mtx( krnlData->name##Mutex ); \
1630  tk_del_mtx( krnlData->name##Mutex ); \
1631  krnlData->name##MutexInitialised = FALSE; \
1632  }
1633 #define MUTEX_LOCK( name ) \
1634  if( tk_loc_mtx( krnlData->name##Mutex, TMO_POL ) == E_TMOUT ) \
1635  { \
1636  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
1637  tk_loc_mtx( krnlData->name##Mutex, TMO_FEVR ); \
1638  else \
1639  krnlData->name##MutexLockcount++; \
1640  } \
1641  krnlData->name##MutexOwner = THREAD_SELF();
1642 #define MUTEX_UNLOCK( name ) \
1643  if( krnlData->name##MutexLockcount > 0 ) \
1644  krnlData->name##MutexLockcount--; \
1645  else \
1646  { \
1647  krnlData->name##MutexOwner = THREAD_INITIALISER; \
1648  tk_unl_mtx( krnlData->name##Mutex ); \
1649  }
1650 
1651 /* Thread management functions. The attributes for task creation are:
1652 
1653  arg -- Task argument.
1654  TA_HLNG -- C interface.
1655  function -- Task function.
1656  TPRI_SELF -- Same priority as invoking task.
1657  16384 -- User stack size.
1658  Other -- Various parameters left at their default
1659  settings.
1660 
1661  The handling of initialisers is a bit dodgy since TSK_SELF == 0 and it
1662  isn't even safe to use negative values since in some cases these can be
1663  valid system task handles. In general however T-Kernel numbers IDs from
1664  1...n, so using 0 as a non-value is safe.
1665 
1666  Dealing with the task's priority is a bit complicated since T-Kernel
1667  provides no way of determining a task's current priority, for now we
1668  use TPRI_INI = the priority of the task when it was started, if this
1669  isn't appropriate then it'd be necessary to call td_ref_tsk() and read
1670  the tskpri field from the rtsk data, however this may be just as bad
1671  because it returns the priority at read time which may differ from the
1672  usual priority.
1673 
1674  T-Kernel status values are 8:8 bit pairs with the actual status in the
1675  low 8 bits. The sub-values can be extracted with the MERCD() and SERCD()
1676  (main- and sub-error-code) macros, however simply using the MERCD()
1677  result isn't safe because it could be the (negative) low 8 bits of a
1678  (positive overall) return value. When creating a task we therefore
1679  consider a status < E_OK as being an error, without trying to pick apart
1680  the overall value */
1681 
1682 #define THREADFUNC_DEFINE( name, arg ) void name( INT stacd, VP arg )
1683 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1684  { \
1685  static const T_CSEM pk_csem = { NULL, TA_TFIFO, 1, 64 }; \
1686  T_CTSK pk_ctsk = { ( arg ), TA_HLNG, ( function ), \
1687  TPRI_INI, 16384, 0, 0, 0, 0, 0 }; \
1688  \
1689  syncHandle = tk_cre_sem( &pk_csem ); \
1690  threadHandle = tk_cre_tsk( &pk_ctsk ); \
1691  if( threadHandle < E_OK ) \
1692  { \
1693  tk_del_sem( syncHandle ); \
1694  status = CRYPT_ERROR; \
1695  } \
1696  else \
1697  { \
1698  tk_sta_tsk( threadHandle, 0 ); \
1699  status = CRYPT_OK; \
1700  } \
1701  }
1702 #define THREAD_EXIT( sync ) tk_sig_sem( sync, 1 ); \
1703  tk_exd_tsk()
1704 #define THREAD_INITIALISER 0
1705 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1706 #define THREAD_SELF() tk_get_tid()
1707 #define THREAD_SLEEP( ms ) tk_slp_tsk( ms )
1708 #define THREAD_YIELD() tk_slp_tsk( 0 )
1709 #define THREAD_WAIT( sync, status ) \
1710  if( tk_wai_sem( sync, 1, TMO_FEVR ) != E_OK ) \
1711  status = CRYPT_ERROR; \
1712  tk_del_sem( sync )
1713 #define THREAD_CLOSE( sync )
1714 
1715 /****************************************************************************
1716 * *
1717 * uC/OS-II *
1718 * *
1719 ****************************************************************************/
1720 
1721 #elif defined( __UCOS__ )
1722 
1723 /* uC/OS-II has a pure priority-based scheduler (no round-robin scheduling)
1724  and makes a task's priority do double duty as the task ID, which means
1725  that it's unlikely it'll ever get round-robin scheduling without a
1726  major overhaul of the API. Because of this, a background task started
1727  inside cryptlib for initialisation or keygen will either never run or
1728  always run depending on the priority it's started with, thus making it
1729  equivalent to performing the operation synchronously. This means that
1730  there's no point in using cryptlib-internal tasks, so they're disabled
1731  unless the following is commented out. Note that cryptlib is still
1732  thread-(task)-safe, it just won't use internal tasks for asynchronous
1733  ops, because uC/OS-II's scheduling will make the synchronous */
1734 
1735 /* #define UCOS_USE_TASKS */
1736 
1737 /* Most systems handle priority-inversion-avoidance automatically, however
1738  for some reason in uC/OS-II this has to be managed manually by the user.
1739  This is done by specifying the priority-inherit priority level that a
1740  low-priority task is raised to when a high-priority task attempts to
1741  acquire a mutex that the low-priority task is currently holding. This
1742  has to be higher than the priority of any of the tasks that will try
1743  to acquire the mutex, as well as being different from the task ID/
1744  priority of any task (another problem caused by the task ID == priority
1745  issue). The following is a sample value that'll need to be adjusted
1746  based on usage by the calling application */
1747 
1748 #define UCOS_PIP 10
1749 
1750 /* Because of the strict priority scheduling, we have to specify the task
1751  priority (which then also becomes the task ID) when we create the task.
1752  The following is a sample task ID, which must be less than UCOS_PIP */
1753 
1754 #define UCOS_TASKID 20
1755 
1756 /* uC/OS-II typedefs 'BOOLEAN', which clashes with our own BOOLEAN, so we
1757  undefine it around the include of the uC/OS-II headers */
1758 
1759 #undef BOOLEAN
1760 
1761 #include <ucos_ucos_ii.h>
1762 
1763 #define BOOLEAN int
1764 
1765 /* uC/OS-II defines 'BYTE' for backwards-compatibility with uC/OS-I but
1766  never uses it, so we remove it again to make our definition visible */
1767 
1768 #undef BYTE
1769 
1770 /* Object handles */
1771 
1772 #define THREAD_HANDLE INT8U
1773 #define MUTEX_HANDLE OS_EVENT *
1774 
1775 /* Mutex management functions. uC/OS-II mutexes aren't re-entrant (although
1776  this is never mentioned explicitly in any documentation the description
1777  of how mutexes work in App.Note 1002 makes it clear that they're not), we
1778  use the standard trylock()-style mechanism to work around this */
1779 
1780 #define MUTEX_DECLARE_STORAGE( name ) \
1781  OS_EVENT *name##Mutex; \
1782  BOOLEAN name##MutexInitialised; \
1783  INT8U name##MutexOwner; \
1784  int name##MutexLockcount
1785 #define MUTEX_CREATE( name, status ) \
1786  status = CRYPT_OK; \
1787  if( !krnlData->name##MutexInitialised ) \
1788  { \
1789  INT8U err; \
1790  \
1791  krnlData->name##Mutex = OSMutexCreate( UCOS_PIP, &err ); \
1792  if( err == OS_ERR_NONE ) \
1793  krnlData->name##MutexInitialised = TRUE; \
1794  else \
1795  status = CRYPT_ERROR; \
1796  }
1797 #define MUTEX_DESTROY( name ) \
1798  if( krnlData->name##MutexInitialised ) \
1799  { \
1800  INT8U err; \
1801  \
1802  OSMutexPend( krnlData->name##Mutex, 0, &err ); \
1803  OSMutexPost( krnlData->name##Mutex ); \
1804  OSMutexDel( krnlData->name##Mutex, OS_DEL_ALWAYS, &err ); \
1805  krnlData->name##MutexInitialised = FALSE; \
1806  }
1807 #define MUTEX_LOCK( name ) \
1808  { \
1809  INT8U err; \
1810  \
1811  if( OSMutexAccept( krnlData->name##Mutex, &err ) == 0 ) \
1812  { \
1813  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
1814  OSMutexPend( krnlData->name##Mutex, 0, &err ); \
1815  else \
1816  krnlData->name##MutexLockcount++; \
1817  } \
1818  krnlData->name##MutexOwner = THREAD_SELF(); \
1819  }
1820 #define MUTEX_UNLOCK( name ) \
1821  if( krnlData->name##MutexLockcount > 0 ) \
1822  krnlData->name##MutexLockcount--; \
1823  else \
1824  { \
1825  krnlData->name##MutexOwner = THREAD_INITIALISER; \
1826  OSMutexPost( krnlData->name##Mutex ); \
1827  }
1828 
1829 /* Thread management functions. Because of the strict priority-based
1830  scheduling there's no way to perform a yield, the best that we can do
1831  is sleep for 1ms, which is better than performing a busy wait.
1832 
1833  Thread sleep times are measured in implementation-specific ticks rather
1834  than ms, so we have to scale the time based on the OS_TICKS_PER_SEC
1835  value */
1836 
1837 #define THREADFUNC_DEFINE( name, arg ) void name( void *arg )
1838 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1839  { \
1840  OS_STK *threadData = malloc( 4096 ); \
1841  \
1842  syncHandle = OSSemCreate( 0 ); \
1843  if( OSTaskCreate( function, arg, ( BYTE * ) threadData + 4095, \
1844  UCOS_TASKID ) != OS_ERR_NONE ) \
1845  { \
1846  free( threadData ); \
1847  status = CRYPT_ERROR; \
1848  } \
1849  else \
1850  status = CRYPT_OK; \
1851  }
1852 #define THREAD_EXIT( sync ) OSSemPost( sync ); \
1853  OSTaskDel( OS_PRIO_SELF )
1854 #define THREAD_INITIALISER 0
1855 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
1856 #define THREAD_SELF() threadSelf()
1857 #if OS_TICKS_PER_SEC >= 1000
1858  #define THREAD_SLEEP( ms ) OSTimeDly( ( OS_TICKS_PER_SEC / 1000 ) * ms )
1859 #else
1860  #define THREAD_SLEEP( ms ) OSTimeDly( max( ( ms * OS_TICKS_PER_SEC ) / 1000, 1 ) )
1861 #endif /* OS_TICKS_PER_SEC time scaling */
1862 #define THREAD_YIELD() THREAD_SLEEP( 1 )
1863 #define THREAD_WAIT( sync, status ) \
1864  { \
1865  INT8U err; \
1866  \
1867  OSSemPend( sync, 0, &err ); \
1868  if( err != OS_ERR_NONE ) \
1869  status = CRYPT_ERROR; \
1870  OSSemDel( sync, OS_DEL_ALWAYS, &err ); \
1871  }
1872 #define THREAD_CLOSE( sync )
1873 
1874 /* uC/OS-II doesn't have a thread-self function, but allows general task
1875  info to be queried. Because of this we provide a wrapper that returns
1876  the task ID as its return value */
1877 
1878 INT8U threadSelf( void );
1879 
1880 /* Because of the inability to do round-robin scheduling, we no-op out the
1881  use of internal threads/tasks. Note that cryptlib itself is still thread-
1882  safe, it just can't do its init or keygen in an internal background
1883  thread */
1884 
1885 #ifndef UCOS_USE_TASKS
1886  #undef THREAD_CREATE
1887  #undef THREAD_EXIT
1888  #undef THREAD_CLOSE
1889  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
1890  status = CRYPT_ERROR
1891  #define THREAD_EXIT( sync )
1892  #define THREAD_CLOSE( sync )
1893 #endif /* !UCOS_USE_TASKS */
1894 
1895 /****************************************************************************
1896 * *
1897 * Unix/MVS/XMK *
1898 * *
1899 ****************************************************************************/
1900 
1901 #elif ( defined( __UNIX__ ) || defined( __XMK__ ) ) && defined( USE_THREADS )
1902 
1903 /* Under OSF/1 pthread.h includes c_asm.h which contains a declaration
1904 
1905  long asm( const char *,...);
1906 
1907  that conflicts with the gcc asm keyword. This asm stuff is only used
1908  when inline asm alternatives to the Posix threading functions are enabled,
1909  which isn't done by default so in theory we could also fix this by
1910  defining asm to something else before including pthread.h, but it's safer
1911  to just disable inclusion of c_asm.h by pre-defining the guard define.
1912  This will result in a more useful warning if for some reason inline
1913  threading functions with asm are enabled */
1914 
1915 #if defined( __osf__ ) || defined( __alpha__ )
1916  #define __C_ASM_H
1917 #endif /* Alpha */
1918 
1919 /* Linux threads are a particularly peculiar implementation, being based on
1920  the Linux clone() system call, which clones an entire process and uses
1921  a special "manager thread" to provide the appearance of a multithreaded
1922  application. This threads == processes model produces very strange
1923  effects such as the appearance of a mass of (pseudo-)processes, each with
1924  their own PID, that appear to consume more memory than is physically
1925  present. Another problem was that signals, which are done on a per-PID
1926  basis and should have been consistent across all threads in the process,
1927  were instead only delivered to one thread/pseudo-process and never got
1928  any further. The clone()-based hack results in non-conformance with the
1929  pthreads spec as well as significant scalability and performance issues.
1930 
1931  The problem was finally (mostly) fixed with Ingo Molnar's native Posix
1932  thread library (NPTL) patches to the 2.5 development) kernel, which
1933  still retains the strange clone()-based threading mechanism but provides
1934  enough kludges to other parts of the kernel that it's not longer so
1935  obvious. For example the clone() call has been optimised to make it
1936  more lightweight, Molnar's O(1) scheduler reduces the overhead of the
1937  process-per-thread mechanism, fast userspace mutexes eliminate the need
1938  for interthread signalling to implement locking, and most importantly the
1939  kernel identification of all threads has been collapsed to a single PID,
1940  eliminating the confusion caused by the cloned pseudo-processes */
1941 
1942 #include <pthread.h>
1943 #include <sys/time.h>
1944 #ifdef __XMK__
1945  #include <sys/process.h>
1946  #include <sys/timer.h>
1947 #endif /* Xilinx XMK */
1948 
1949 /* Object handles */
1950 
1951 #define THREAD_HANDLE pthread_t
1952 #define MUTEX_HANDLE pthread_t
1953 
1954 /* Mutex management functions. Most Unix mutex implementations are non-
1955  re-entrant, which means that re-locking a mutex leads to deadlock
1956  (charming). Some implementations can fix this by setting a mutex
1957  attribute to ensure that it doesn't deadlock using:
1958 
1959  pthread_mutexattr_settype( attr, PTHREAD_MUTEX_RECURSIVE );
1960 
1961  or:
1962 
1963  pthread_mutex_setrecursive();
1964 
1965  but this isn't universal. To fix the problem, we implement our own
1966  re-entrant mutexes on top of the Posix ones.
1967 
1968  Due to the complexity of the locking process using pthreads' (usually)
1969  non-reentrant mutexes, we don't try and lock+unlock the mutex before we
1970  destroy it. This isn't a major issue since it's just a safety precaution,
1971  the kernel should have forced any remaining threads to exit by the time
1972  the shutdown occurs anyway */
1973 
1974 #define MUTEX_DECLARE_STORAGE( name ) \
1975  pthread_mutex_t name##Mutex; \
1976  BOOLEAN name##MutexInitialised; \
1977  pthread_t name##MutexOwner; \
1978  int name##MutexLockcount
1979 #define MUTEX_CREATE( name, status ) \
1980  status = CRYPT_OK; \
1981  if( !krnlData->name##MutexInitialised ) \
1982  { \
1983  if( pthread_mutex_init( &krnlData->name##Mutex, \
1984  NULL ) == 0 ) \
1985  krnlData->name##MutexInitialised = TRUE; \
1986  else \
1987  status = CRYPT_ERROR; \
1988  }
1989 #define MUTEX_DESTROY( name ) \
1990  if( krnlData->name##MutexInitialised ) \
1991  { \
1992  pthread_mutex_destroy( &krnlData->name##Mutex ); \
1993  krnlData->name##MutexInitialised = FALSE; \
1994  }
1995 #define MUTEX_LOCK( name ) \
1996  if( pthread_mutex_trylock( &krnlData->name##Mutex ) ) \
1997  { \
1998  if( !THREAD_SAME( krnlData->name##MutexOwner, THREAD_SELF() ) ) \
1999  pthread_mutex_lock( &krnlData->name##Mutex ); \
2000  else \
2001  krnlData->name##MutexLockcount++; \
2002  } \
2003  krnlData->name##MutexOwner = THREAD_SELF();
2004 #define MUTEX_UNLOCK( name ) \
2005  if( krnlData->name##MutexLockcount > 0 ) \
2006  krnlData->name##MutexLockcount--; \
2007  else \
2008  { \
2009  krnlData->name##MutexOwner = THREAD_INITIALISER; \
2010  pthread_mutex_unlock( &krnlData->name##Mutex ); \
2011  }
2012 
2013 /* Instead of the DIY recursive mutexes above it's also possible to use OS
2014  recursive mutexes if they're available. Unfortunately there's no easy
2015  way to reliably test for these (they're often provided as _NP variants,
2016  or require obscure preprocessor trickery to enable them), and even if
2017  they're present they may not be supported (pthread_mutexattr_settype()
2018  returns an error), or the implementation may be flaky (some Linux
2019  threading implementations). Because of this the following use of
2020  recursive mutexes needs to be manually enabled. Note that on most
2021  systems that use gcc it's necessary to define either _XOPEN_SOURCE=500 or
2022  _GNU_SOURCE to get PTHREAD_MUTEX_RECURSIVE, otherwise only
2023  PTHREAD_MUTEX_RECURSIVE_NP is defined, i.e. the standard behaviour of gcc
2024  is to be nonstandard */
2025 
2026 #if 0
2027 
2028 #undef MUTEX_CREATE
2029 #undef MUTEX_LOCK
2030 #undef MUTEX_UNLOCK
2031 #define MUTEX_CREATE( name, status ) \
2032  if( !krnlData->name##MutexInitialised ) \
2033  { \
2034  pthread_mutexattr_t mutexAttr;\
2035  \
2036  pthread_mutexattr_init( &mutexAttr );\
2037  pthread_mutexattr_settype( &mutexAttr, \
2038  PTHREAD_MUTEX_RECURSIVE ); \
2039  if( pthread_mutex_init( &krnlData->name##Mutex, \
2040  &mutexAttr ) == 0 ) \
2041  { \
2042  krnlData->name##MutexInitialised = TRUE; \
2043  status = CRYPT_OK; \
2044  } \
2045  else \
2046  status = CRYPT_ERROR; \
2047  pthread_mutexattr_destroy ( &mutexAttr );\
2048  }
2049 #define MUTEX_LOCK( name ) pthread_mutex_lock( &krnlData->name##Mutex )
2050 #define MUTEX_UNLOCK( name ) pthread_mutex_unlock( &krnlData->name##Mutex )
2051 
2052 #endif /* 0 */
2053 
2054 /* Putting a thread to sleep for a number of milliseconds can be done with
2055  select() because it should be a thread-safe one in the presence of
2056  pthreads. In addition there are some system-specific quirks, these are
2057  handled by re-defining the macros below in a system-specific manner
2058  further on.
2059 
2060  Yielding a thread's timeslice gets rather complex due to a confusion of
2061  non-portable "portable" Posix functions. Initially there was
2062  pthread_yield() from draft 4 of the Posix thread standard in 1990,
2063  popularised in the DCE threading code and picked up by a number of other
2064  implementations. At about that time the realtime (1003.1b) and thread
2065  (1003.1c) standardisation was proceeding independently, with neither side
2066  knowing which one would make it to standards status first. As it turned
2067  out this was 1003.1b with sched_yield(). When the 1003.1c folks were
2068  looking for every place where the text said "process" but should say
2069  "thread" once 1003.1c was in effect, they noticed that sched_yield() and
2070  pthread_yield() were now identical. Since sched_yield() was already in
2071  the standard, there was no need for pthread_yield() so it was removed.
2072  However, some older implementations still do pthread_yield() and some
2073  (also older) implementations use sched_yield() to yield the processes'
2074  timeslice rather than the thread's timeslice, further complicated by the
2075  fact that some implementations like PHUX 10.x/11.x have buggy manpages
2076  that claim sched_yield() is per-process when in fact it's per-thread
2077  (PHUX 10.x still had pthread_yield() while 11.x only has sched_yield()).
2078  The whole is further confused by the fact that in some implementations,
2079  threads are processes (sort of, e.g. Linux's clone()'d threads and Sun
2080  LWPs). In addition Sun have their own thr_yield which is part of their
2081  UI threads interface and that you have to fall back to occasionally.
2082 
2083  Because of this mess, we try for pthread_yield() if possible (since that
2084  definitely yields the thread's timeslice), fall back to sched_yield() if
2085  necessary, and add a special workaround for Sun systems.
2086 
2087  "Posix is portable in the sense that you can use a forklift to move the
2088  printed volumes around" */
2089 
2090 #define THREADFUNC_DEFINE( name, arg ) void *name( void *arg )
2091 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2092  { \
2093  status = pthread_create( &threadHandle, NULL, function, arg ) ? \
2094  CRYPT_ERROR : CRYPT_OK; \
2095  syncHandle = threadHandle; \
2096  }
2097 #define THREAD_EXIT( sync ) pthread_exit( ( void * ) 0 )
2098 #define THREAD_INITIALISER 0
2099 #define THREAD_SELF() pthread_self()
2100 #define THREAD_SAME( thread1, thread2 ) pthread_equal( ( thread1 ), ( thread2 ) )
2101 #if defined( __osf__ ) || defined( __alpha__ ) || defined( __APPLE__ )
2102  #define THREAD_YIELD() pthread_yield_np()
2103 #elif defined( __MVS__ )
2104  #define THREAD_YIELD() pthread_yield( NULL )
2105 #elif defined( sun )
2106  #if OSVERSION <= 6
2107  /* Older Slowaris gets a bit complex, SunOS 4.x always returns -1 and
2108  sets errno to ENOSYS when sched_yield() is called, so we use this to
2109  fall back to the UI interface if necessary */
2110  #define THREAD_YIELD() { if( sched_yield() ) thr_yield(); }
2111  #else
2112  #define THREAD_YIELD() sched_yield()
2113  #endif /* Slowaris 5.7 / 7.x or newer */
2114 #elif defined( _AIX ) || defined( __CYGWIN__ ) || \
2115  ( defined( __hpux ) && ( OSVERSION >= 11 ) ) || \
2116  defined( __NetBSD__ ) || defined( __QNX__ ) || defined( __UCLIBC__ )
2117  #define THREAD_YIELD() sched_yield()
2118 #elif defined( __XMK__ )
2119  /* The XMK underlying scheduling object is the process context, for which
2120  the user-visible interface is the thread. Therefore yielding the
2121  underlying process context should yield the associated thread */
2122  #define THREAD_YIELD() yield()
2123 #else
2124  #if defined( __linux__ ) && !defined( __USE_GNU )
2125  void pthread_yield( void );
2126  #endif /* Present but not prototyped unless GNU extensions are enabled */
2127  #define THREAD_YIELD() pthread_yield()
2128 #endif /* Not-very-portable Posix portability */
2129 #define THREAD_SLEEP( ms ) { \
2130  struct timeval tv = { 0 }; \
2131  \
2132  tv.tv_usec = ( ms ) * 1000; \
2133  select( 1, NULL, NULL, NULL, &tv ); \
2134  }
2135 #define THREAD_WAIT( sync, status ) \
2136  if( pthread_join( sync, NULL ) < 0 ) \
2137  status = CRYPT_ERROR
2138 #define THREAD_CLOSE( sync )
2139 
2140 /* OSF1 includes some ghastly kludgery to handle binary compatibility from
2141  1003.4a to 1003.1c threading functions and inline asm functions with all
2142  sorts of name mangling and translation of function names and types.
2143  Unfortunately a straight vanilla compile leaves pthread_self() un-
2144  prototyped, which means that it's then implicitly prototyped as returned
2145  an int. This generates hundreds of warnings of int <-> pointer casting
2146  problems, so if pthread_self() isn't redefined into one of a dozen
2147  different mangled versions we prototype it ourselves here */
2148 
2149 #if ( defined( __osf__ ) || defined( __alpha__ ) ) && \
2150  !defined( pthread_self )
2151  #ifdef _PTHREAD_USE_MANGLED_NAMES_
2152  #define pthread_self __pthread_self
2153  #endif /* Name mangling */
2154  extern pthread_t pthread_self( void );
2155 #endif /* OSF1 pthread_self function prototyping bug */
2156 
2157 /* The pthreads implementation on MP-RAS (NCR User Space Threads based on
2158  CMA threads for DCE) doesn't accept NULL for several of the attribute
2159  arguments so we have to supply pthread_mutexattr_default attributes */
2160 
2161 #ifdef _MPRAS
2162  #undef MUTEX_CREATE
2163  #define MUTEX_CREATE( name, status ) \
2164  status = CRYPT_OK; \
2165  if( !krnlData->name##MutexInitialised ) \
2166  { \
2167  if( pthread_mutex_init( &krnlData->name##Mutex, \
2168  pthread_mutexattr_default ) == 0 ) \
2169  krnlData->name##MutexInitialised = TRUE; \
2170  else \
2171  status = CRYPT_ERROR; \
2172  }
2173 
2174  #undef THREAD_CREATE
2175  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2176  { \
2177  status = pthread_create( &threadHandle, pthread_attr_default, \
2178  function, arg ) ? \
2179  CRYPT_ERROR : CRYPT_OK ); \
2180  syncHandle = ( long ) threadHandle; \
2181  }
2182 #endif /* _MPRAS */
2183 
2184 /* Some systems (notably MVS and MP-RAS) use non-scalar pthread_t's, so we
2185  have to handle initialisation of these specially */
2186 
2187 #if defined( __MVS__ ) || defined( _MPRAS )
2188  #define NONSCALAR_THREADS
2189  #undef THREAD_INITIALISER
2190  #define THREAD_INITIALISER { 0 }
2191 #endif /* Non-scalar pthread_t's */
2192 
2193 /* XMK doesn't have a select(), however it has a sleep() as part of the timer
2194  package that performs the same function. Note that there's a second
2195  sleep() that takes an argument in seconds rather than ms and that sleeps
2196  the overall process in the PPC BSP library, but presumably this won't be
2197  used if the sleep() in the timer package is enabled */
2198 
2199 #ifdef __XMK__
2200  #undef THREAD_SLEEP
2201  #define THREAD_SLEEP( ms ) sleep( ms )
2202 #endif /* Xilinx XMK */
2203 
2204 /* UnixWare/SCO creates threads with a ridiculously small default stack size
2205  of a few KB or so, which means that the thread can't even start. To work
2206  around this we have to use a custom thread-creation function that sets
2207  the stack size to something reasonable */
2208 
2209 #ifdef __SCO_VERSION__
2210  #undef THREAD_CREATE
2211  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2212  { \
2213  pthread_attr_t attr; \
2214  \
2215  pthread_attr_init( &attr ); \
2216  pthread_attr_setstacksize( &attr, 32768 ); \
2217  status = pthread_create( &threadHandle, &attr, function, arg ); \
2218  pthread_attr_destroy( &attr ); \
2219  if( status ) \
2220  status = CRYPT_ERROR; \
2221  else \
2222  { \
2223  status = CRYPT_OK; \
2224  syncHandle = ( long ) threadHandle; \
2225  } \
2226  }
2227 #endif /* UnixWare/SCO */
2228 
2229 /****************************************************************************
2230 * *
2231 * VDK *
2232 * *
2233 ****************************************************************************/
2234 
2235 #elif defined( __VDK__ )
2236 
2237 /* VDK has a rather unusual concept of error handling in which it assumes
2238  that system calls rarely fail and if they do the error should be handled
2239  as an exception by a thread's ErrorFunction (augmenting the standard
2240  function return code), which is defined in the thread template alongside
2241  various other things like the thread's Run function (see the discussion
2242  on threads below for more on this). Error handling via exceptions
2243  depends on how the system is linked, if it's linked against the error-
2244  checking libraries then general error conditions are checked and result
2245  in an exception (e.g. waiting on an undefined semaphore), if the standard
2246  libraries are used then only some critical errors such as timeout on a
2247  semaphore result in an exception.
2248 
2249  This dual-path error handling is made worse by the fact that the default
2250  ErrorFunction handler invokes a kernel panic (!!!), making clean recovery
2251  somewhat difficult */
2252 
2253 #include <VDK.h>
2254 
2255 /* Object handles */
2256 
2257 #define THREAD_HANDLE VDK_ThreadID
2258 #define MUTEX_HANDLE VDK_SemaphoreID
2259 
2260 /* Mutex management functions. VDK semaphores are re-entrant so we don't
2261  have to jump through the hoops that are necessary with most other OSes.
2262 
2263  VDK uses one-size-fits all semaphores and also has the concept of a
2264  "periodic semaphore" which is actually just a waitable timer triggering
2265  every n clock ticks. We disable this functionality and create a basic
2266  binary semaphore with no (or at least near-infnite) timeout, in other
2267  words a mutex */
2268 
2269 #define MUTEX_DECLARE_STORAGE( name ) \
2270  VDK_SemaphoreID name##Mutex; \
2271  BOOLEAN name##MutexInitialised
2272 #define MUTEX_CREATE( name, status ) \
2273  status = CRYPT_OK; \
2274  if( !krnlData->name##MutexInitialised ) \
2275  { \
2276  if( ( krnlData->name##Mutex = VDK_CreateSemaphore( 1, 1, 1, 0 ) ) != UINT_MAX ) \
2277  krnlData->name##MutexInitialised = TRUE; \
2278  else \
2279  status = CRYPT_ERROR; \
2280  }
2281 #define MUTEX_DESTROY( name ) \
2282  if( krnlData->name##MutexInitialised ) \
2283  { \
2284  VDK_PendSemaphore( krnlData->name##Mutex, 1000000 ); \
2285  VDK_PostSemaphore( krnlData->name##Mutex ); \
2286  VDK_DestroySemaphore( krnlData->name##Mutex ); \
2287  krnlData->name##MutexInitialised = FALSE; \
2288  }
2289 #define MUTEX_LOCK( name ) \
2290  VDK_PendSemaphore( krnlData->name##Mutex, 1000000 ); \
2291 #define MUTEX_UNLOCK( name ) \
2292  VDK_PostSemaphore( krnlData->name##Mutex );
2293 
2294 /* VDK has a somewhat strange concept of thread management in which a thread
2295  isn't defined as a stream of execution on code but via a template whose
2296  details are fixed at compile time, with each template identified by a
2297  unique value in a header file. So instead of starting a thread with
2298  'CreatThread( threadFnPtr, threadFnParams, threadInfo )' VDK uses
2299  'CreateThread( threadType )' and the scheduler looks up the details that
2300  are normally pass in at runtime in a table mapping the thread type to the
2301  parameters that it needs.
2302 
2303  This is really awkward because it requires that all threads be defined in
2304  a single location at system build time, which is problematic for a
2305  library like cryptlib because the calling code has to be aware of
2306  cryptlib-internal thread functions when it's built. Because of this we
2307  disable the use of cryptlib-internal threads, these are only used for
2308  dynamic driver binding which isn't needed under VDK because there are
2309  unlikely to be PKCS #11 or ODBC ports to it any time soon, or even
2310  dynamic library support which would be needed before it was possible to
2311  have loadable drivers.
2312 
2313  VDK threads are exited using a standard 'return' rather than via any OS-
2314  specific exit mechanism.
2315 
2316  Task sleep times are measured in implementation-specific ticks rather
2317  than ms, but we can get the duration using VDK_GetTickPeriod() */
2318 
2319 #define THREADFUNC_DEFINE( name, arg ) thread_id name( void *arg )
2320 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2321  { \
2322  VDK_ThreadCreationBlock threadInfo; \
2323  \
2324  memset( &threadInfo, 0, sizeof( VDK_ThreadCreationBlock ) ); \
2325  threadInfo.template_id = kDynamicThread; \
2326  threadInfo.user_data_ptr = arg; \
2327  threadInfo.pTemplate = /*<thread template, see above>*/; \
2328  \
2329  syncHandle = VDK_CreateSemaphore( 1, 1, 1, 0 ); \
2330  threadHandle = VDK_CreateThreadEx( &threadInfo ); \
2331  if( threadHandle == UINT_MAX ) \
2332  { \
2333  VDK_DestroySemaphore( syncHandle ); \
2334  status = CRYPT_ERROR; \
2335  } \
2336  else \
2337  status = CRYPT_OK; \
2338  }
2339 #define THREAD_EXIT( sync ) VDK_PostSemaphore( sync ); \
2340  return( 0 )
2341 #define THREAD_INITIALISER 0
2342 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
2343 #define THREAD_SELF() VDK_GetThreadID()
2344 #define THREAD_SLEEP( ms ) VDK_Sleep( VDK_GetTickPeriod() * ms )
2345 #define THREAD_YIELD() VDK_Yield()
2346 #define THREAD_WAIT( sync, status ) \
2347  if( !VDK_PendSemaphore( sync, 1000000 ) ) \
2348  status = CRYPT_ERROR; \
2349  else \
2350  VDK_PostSemaphore( sync ); \
2351  VDK_DestroySemaphore( sync )
2352 #define THREAD_CLOSE( sync )
2353 
2354 /* Because of the odd way in which thread management works we no-op out the
2355  use of internal threads. Note that cryptlib itself is still thread-safe,
2356  it just can't do its init or keygen in an internal background thread */
2357 
2358 #ifndef VDK_USE_THREADS
2359  #undef THREAD_CREATE
2360  #undef THREAD_EXIT
2361  #undef THREAD_CLOSE
2362  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2363  status = CRYPT_ERROR
2364  #define THREAD_EXIT( sync )
2365  #define THREAD_CLOSE( sync )
2366 #endif /* !VDK_USE_THREADS */
2367 
2368 /****************************************************************************
2369 * *
2370 * VxWorks *
2371 * *
2372 ****************************************************************************/
2373 
2374 #elif defined( __VXWORKS__ )
2375 
2376 #include <vxWorks.h>
2377 #include <semLib.h>
2378 #include <taskLib.h>
2379 
2380 /* Object handles */
2381 
2382 #define THREAD_HANDLE int
2383 #define MUTEX_HANDLE SEM_ID
2384 
2385 /* Mutex management functions. VxWorks mutual exclusion semaphores (and
2386  only mutex semaphores) are re-entrant, so we don't have to jump through
2387  the hoops that are necessary with most other OSes */
2388 
2389 #define MUTEX_DECLARE_STORAGE( name ) \
2390  SEM_ID name##Mutex; \
2391  BOOLEAN name##MutexInitialised
2392 #define MUTEX_CREATE( name, status ) \
2393  status = CRYPT_OK; \
2394  if( !krnlData->name##MutexInitialised ) \
2395  { \
2396  if( ( krnlData->name##Mutex = semMCreate( SEM_Q_FIFO ) ) != NULL ) \
2397  krnlData->name##MutexInitialised = TRUE; \
2398  else \
2399  status = CRYPT_ERROR; \
2400  }
2401 #define MUTEX_DESTROY( name ) \
2402  if( krnlData->name##MutexInitialised ) \
2403  { \
2404  semTake( krnlData->name##Mutex, WAIT_FOREVER ); \
2405  semGive( krnlData->name##Mutex ); \
2406  semDelete( krnlData->name##Mutex ); \
2407  krnlData->name##MutexInitialised = FALSE; \
2408  }
2409 #define MUTEX_LOCK( name ) \
2410  semTake( krnlData->name##Mutex, WAIT_FOREVER ); \
2411 #define MUTEX_UNLOCK( name ) \
2412  semGive( krnlData->name##Mutex );
2413 
2414 /* Thread management functions. Some PPC compilers use the FP registers for
2415  non-FP operations such as working with long long data types (used for
2416  example in PKC key generation), so if we're building for the PPC we
2417  create tasks with FP register saving enabled */
2418 
2419 #ifdef __ppc__
2420  #define TASK_ATTRIBUTES VX_FP_TASK
2421 #else
2422  #define TASK_ATTRIBUTES 0
2423 #endif /* PPC vs.non-PPC register saves */
2424 
2425 /* VxWorks tasks are exited using the standard ANSI exit() function rather
2426  than any OS-specific exit mechanism.
2427 
2428  Task sleep times are measured in implementation-specific ticks rather
2429  than ms, but it's usually close enough to allow us to treat them as being
2430  identical. If we need truly accurate timing we could call a helper
2431  function that scales the time based on sysClkRateGet(), but at the moment
2432  it's only used for general short delays rather than any fixed amount of
2433  time so this isn't necessary */
2434 
2435 #define THREADFUNC_DEFINE( name, arg ) thread_id name( void *arg )
2436 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2437  { \
2438  syncHandle = semBCreate( SEM_Q_FIFO, SEM_EMPTY ); \
2439  threadHandle = taskSpawn( NULL, T_PRIORITY, TASK_ATTRIBUTES, 16384, \
2440  function, ( int ) arg, 0, 0, 0, 0, \
2441  0, 0, 0, 0, 0 ); \
2442  if( threadHandle == ERROR ) \
2443  { \
2444  semDelete( syncHandle ); \
2445  status = CRYPT_ERROR; \
2446  } \
2447  else \
2448  status = CRYPT_OK; \
2449  }
2450 #define THREAD_EXIT( sync ) semGive( sync ); \
2451  exit( 0 )
2452 #define THREAD_INITIALISER 0
2453 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
2454 #define THREAD_SELF() taskIdSelf()
2455 #define THREAD_SLEEP( ms ) taskDelay( ms )
2456 #define THREAD_YIELD() taskDelay( NO_WAIT )
2457 #define THREAD_WAIT( sync, status ) \
2458  if( semTake( sync, WAIT_FOREVER ) != OK ) \
2459  status = CRYPT_ERROR; \
2460  else \
2461  semGive( sync ); \
2462  semDelete( sync )
2463 #define THREAD_CLOSE( sync )
2464 
2465 /****************************************************************************
2466 * *
2467 * Win32/WinCE *
2468 * *
2469 ****************************************************************************/
2470 
2471 #elif ( defined( __WIN32__ ) && !defined( NT_DRIVER ) ) || \
2472  defined( __WINCE__ )
2473 
2474 #ifndef __WINCE__
2475  #include <process.h>
2476 #endif /* __WINCE__ */
2477 
2478 /* Object handles */
2479 
2480 #define THREAD_HANDLE DWORD
2481 #define MUTEX_HANDLE HANDLE
2482 
2483 /* Mutex management functions. InitializeCriticalSection() doesn't return
2484  an error code but can throw a STATUS_NO_MEMORY exception in certain low-
2485  memory situations under Win2K/XP/2003 (it was fixed in Vista), however
2486  this exception isn't raised in an exception-safe manner (the critical
2487  section object is left in a corrupted state) so it can't be safely caught
2488  and recovered from. The result is that there's no point in trying to
2489  catch it (this is a known design flaw in the function).
2490 
2491  EnterCriticalSection() is a bit more problematic. Apart from the
2492  EXCEPTION_POSSIBLE_DEADLOCK exception (which is raised if the critical
2493  section is corrupted, there's not much that can be done here), this can
2494  also raise an out-of-memory exception due to on-demand allocation of the
2495  event handle required by the critical section. In Windows NT these were
2496  always allocated by InitializeCriticalSection(), however in the Win2K
2497  timeframe applications with hundreds of threads and hundreds or even
2498  thousands of critical sections were starting to appear, many of which
2499  were never user. To avoid resource-exhaustion problems, Win2K was
2500  changed to perform on-demand allocation of event handles in critical
2501  sections, and even then only on the first contended acquire (rather than
2502  the first time EnterCriticalSection() is called). To avoid this problem,
2503  InitializeCriticalSectionAndSpinCount() was kludged under Win2K to always
2504  allocate the event handle if the high bit of the dwSpinCount value was
2505  set, but this behaviour was disabled again in WinXP.
2506 
2507  Because of this behaviour, there's no easy safe way to initialise a
2508  critical section. What we'd have to do is create a second thread to
2509  force an initialisation by trying to enter the section while another
2510  thread holds the lock, forcing the allocation of an event handle. In
2511  theory we could do this (since cryptlib only uses a handful of critical
2512  sections), but in practice if the system is so short of resources that it
2513  can't allocate event handles any more then the user has bigger things to
2514  worry about. If we were running exclusively under Vista we could use the
2515  extremely useful slim reader/writer (SRW) locks, but it'll be awhile yet
2516  before we can rely on these (they're also non-reentrant due to their
2517  extreme slimness, which means that they have to be managed very
2518  carefully).
2519 
2520  Critical sections can lead to lock convoys, a variant of the thundering
2521  herd problem that occurs due to an optimisation in lock management used
2522  under Windows where a lock with another thread waiting would be handed
2523  off to the waiting thread without ever being released. In other words
2524  the handoff consisted of handing ownership over to the waiting thread
2525  (without unlocking the lock) instead of unlocking and re-locking with the
2526  new thread. This was done to implement fair locking in which threads were
2527  serviced in strictly FIFO order.
2528 
2529  This leads to a problem because it extends the lock hold time by the
2530  thread context switch latency. Consider a lock for which a thread
2531  arrives every 2000 cycles and executes inside the lock for 1000 cycles.
2532  With thread T0 holding the lock, a new thread T1 arrives 500 cycles into
2533  the execution. T0 releases the lock after 1000 cycles, and T1 takes
2534  ownership. However, the context switch time is 4000 cycles (up to 10K
2535  cycles), so it can't actually start running inside the lock until cycle
2536  5000, even if there are other threads ready to run immediately. Windows
2537  Vista fixed this by making locks slightly unfair, so that an active
2538  thread can steal the lock from the one at the front of the wait queue if
2539  the latter isn't scheduled to be run.
2540 
2541  Finally, special handling of critical sections occurs during a process
2542  shutdown. Firstly, every thread but the one that initiated the shutdown
2543  is killed in a fairly hostile manner. Then, in order to avoid deadlocks,
2544  the system effectively ignores calls to Enter/LeaveCriticalSection(),
2545  since the lock may have been held by one of the killed threads. What
2546  this means is that if the thread left lock-protected data in an
2547  inconsistent state when it was killed and the shutdown thread comes along
2548  and tries to use it, it's going to run into problems. This is a
2549  difficult problem to solve (the MT CRT apparently has a number of
2550  problems with this in internal code paths), but luckily is triggered
2551  extremely rarely, if ever */
2552 
2553 #define MUTEX_DECLARE_STORAGE( name ) \
2554  CRITICAL_SECTION name##CriticalSection; \
2555  BOOLEAN name##CriticalSectionInitialised
2556 #define MUTEX_CREATE( name, status ) \
2557  status = CRYPT_OK; /* See note above */ \
2558  if( !krnlData->name##CriticalSectionInitialised ) \
2559  { \
2560  InitializeCriticalSection( &krnlData->name##CriticalSection ); \
2561  krnlData->name##CriticalSectionInitialised = TRUE; \
2562  }
2563 #define MUTEX_DESTROY( name ) \
2564  if( krnlData->name##CriticalSectionInitialised ) \
2565  { \
2566  EnterCriticalSection( &krnlData->name##CriticalSection ); \
2567  LeaveCriticalSection( &krnlData->name##CriticalSection ); \
2568  DeleteCriticalSection( &krnlData->name##CriticalSection ); \
2569  krnlData->name##CriticalSectionInitialised = FALSE; \
2570  }
2571 #define MUTEX_LOCK( name ) \
2572  EnterCriticalSection( &krnlData->name##CriticalSection )
2573 #define MUTEX_UNLOCK( name ) \
2574  LeaveCriticalSection( &krnlData->name##CriticalSection )
2575 
2576 /* Mutex debug support */
2577 
2578 #ifdef MUTEX_DEBUG
2579 
2580 /* A queue to record prior mutex operations */
2581 
2582 typedef struct {
2584  int lockCount;
2585  int sequenceNo;
2586  } MUTEX_QUEUE_INFO;
2587 
2588 #define MUTEX_QUEUE_SIZE 16
2589 
2590 /* Alternative debug versions of the mutex manipulation primitives. These
2591  just record the last MUTEX_QUEUE_SIZE mutex operations in a FIFO queue for
2592  later analysis */
2593 
2594 #undef MUTEX_DECLARE_STORAGE
2595 #define MUTEX_DECLARE_STORAGE( name ) \
2596  CRITICAL_SECTION name##CriticalSection; \
2597  BOOLEAN name##CriticalSectionInitialised; \
2598  MUTEX_QUEUE_INFO name##EntryQueue[ MUTEX_QUEUE_SIZE ]; \
2599  MUTEX_QUEUE_INFO name##ExitQueue[ MUTEX_QUEUE_SIZE ]; \
2600  int name##LockCount; \
2601  int name##SequenceNo
2602 #undef MUTEX_CREATE
2603 #define MUTEX_CREATE( name, status ) \
2604  status = CRYPT_OK; \
2605  if( !krnlData->name##CriticalSectionInitialised ) \
2606  { \
2607  InitializeCriticalSection( &krnlData->name##CriticalSection ); \
2608  memset( &krnlData->name##EntryQueue, 0, \
2609  sizeof( MUTEX_QUEUE_INFO ) * MUTEX_QUEUE_SIZE ); \
2610  memset( &krnlData->name##ExitQueue, 0, \
2611  sizeof( MUTEX_QUEUE_INFO ) * MUTEX_QUEUE_SIZE ); \
2612  krnlData->name##LockCount = krnlData->name##SequenceNo = 0; \
2613  krnlData->name##CriticalSectionInitialised = TRUE; \
2614  }
2615 #undef MUTEX_LOCK
2616 #undef MUTEX_UNLOCK
2617 #define MUTEX_LOCK( name ) \
2618  { \
2619  int i; \
2620  \
2621  EnterCriticalSection( &krnlData->name##CriticalSection ); \
2622  for( i = 1; i < MUTEX_QUEUE_SIZE; i++ ) \
2623  krnlData->name##EntryQueue[ i - 1 ] = \
2624  krnlData->name##EntryQueue[ i ]; \
2625  krnlData->name##EntryQueue[ MUTEX_QUEUE_SIZE - 1 ].owner = THREAD_SELF(); \
2626  krnlData->name##EntryQueue[ MUTEX_QUEUE_SIZE - 1 ].lockCount = krnlData->name##LockCount++; \
2627  krnlData->name##EntryQueue[ MUTEX_QUEUE_SIZE - 1 ].sequenceNo = krnlData->name##SequenceNo++; \
2628  }
2629 #define MUTEX_UNLOCK( name ) \
2630  { \
2631  int i; \
2632  \
2633  for( i = 1; i < MUTEX_QUEUE_SIZE; i++ ) \
2634  krnlData->name##ExitQueue[ i - 1 ] = \
2635  krnlData->name##ExitQueue[ i ]; \
2636  krnlData->name##ExitQueue[ MUTEX_QUEUE_SIZE - 1 ].owner = THREAD_SELF(); \
2637  krnlData->name##ExitQueue[ MUTEX_QUEUE_SIZE - 1 ].lockCount = krnlData->name##LockCount--; \
2638  krnlData->name##ExitQueue[ MUTEX_QUEUE_SIZE - 1 ].sequenceNo = krnlData->name##SequenceNo++; \
2639  LeaveCriticalSection( &krnlData->name##CriticalSection ); \
2640  }
2641 #endif /* MUTEX_DEBUG */
2642 
2643 /* Thread management functions. Win32 requires a C library-aware wrapper
2644  around the OS native CreateThread()/ExitThread() calls, with WinCE
2645  after 2.0 the C runtime is integrated into the OS so we can call them
2646  directly.
2647 
2648  There are two functions that we can call to get the current thread ID,
2649  GetCurrentThread() and GetCurrentThreadId(). GetCurrentThread() merely
2650  returns a constant value that's interpreted by various functions to
2651  mean "the current thread". GetCurrentThreadId() returns the thread ID,
2652  however this isn't the same as the thread handle.
2653 
2654  After we wait for the thread, we need to close the handle. This is
2655  complicated by the fact that we can only close it once all threads have
2656  exited the wait, which requires further calisthenics in the function that
2657  uses it to ensure that the last thread out closes the handle. This also
2658  means that we can't combine the close with the wait as for other OSes,
2659  since we can only perform the close once all waits have exited */
2660 
2661 #if defined( __WIN32__ )
2662  #define THREADFUNC_DEFINE( name, arg ) \
2663  unsigned __stdcall name( void *arg )
2664  #if defined( _MSC_VER ) && VC_GE_2005( _MSC_VER )
2665  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2666  { \
2667  uintptr_t hThread; \
2668  \
2669  hThread = _beginthreadex( NULL, 0, ( function ), ( arg ), 0, \
2670  &threadHandle ); \
2671  syncHandle = ( MUTEX_HANDLE ) hThread; \
2672  status = ( hThread == 0 ) ? CRYPT_ERROR : CRYPT_OK; \
2673  }
2674  #else
2675  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2676  { \
2677  unsigned long hThread; \
2678  \
2679  hThread = _beginthreadex( NULL, 0, ( function ), ( arg ), 0, \
2680  &threadHandle ); \
2681  syncHandle = ( MUTEX_HANDLE ) hThread; \
2682  status = ( hThread == 0 ) ? CRYPT_ERROR : CRYPT_OK; \
2683  }
2684  #endif /* Older vs. newer VC++ */
2685  #define THREAD_EXIT( sync ) _endthreadex( 0 ); return( 0 )
2686 #elif defined( __WINCE__ )
2687  #define THREADFUNC_DEFINE( name, arg ) \
2688  DWORD WINAPI name( void *arg )
2689  #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2690  { \
2691  HANDLE hThread; \
2692  \
2693  hThread = CreateThread( NULL, 0, ( function ), ( arg ), 0, \
2694  &threadHandle ); \
2695  syncHandle = hThread; \
2696  status = ( hThread == NULL ) ? CRYPT_ERROR : CRYPT_OK; \
2697  }
2698  #define THREAD_EXIT( sync ) ExitThread( 0 ); return( 0 )
2699 #endif /* Win32 vs. WinCE */
2700 #define THREAD_INITIALISER 0
2701 #define THREAD_SELF() GetCurrentThreadId()
2702 #define THREAD_SAME( thread1, thread2 ) ( ( thread1 ) == ( thread2 ) )
2703 #define THREAD_SLEEP( ms ) Sleep( ms )
2704 #if defined( __WIN32__ )
2705  #define THREAD_YIELD() threadYield()
2706 #else
2707  #define THREAD_YIELD() Sleep( 0 )
2708 #endif /* Win32 vs. WinCE */
2709 #define THREAD_WAIT( sync, status ) \
2710  if( WaitForSingleObject( sync, INFINITE ) != WAIT_OBJECT_0 ) \
2711  status = CRYPT_ERROR
2712 #define THREAD_CLOSE( sync ) CloseHandle( sync )
2713 
2714 /* Yielding a thread on an SMP or HT system is a tricky process, so we have
2715  to use a custom function to do this */
2716 
2717 void threadYield( void );
2718 
2719 #elif defined( __WIN32__ ) && defined( NT_DRIVER )
2720 
2721 /* Object handles */
2722 
2723 #define THREAD_HANDLE HANDLE
2724 #define MUTEX_HANDLE HANDLE
2725 
2726 /* Mutex management functions */
2727 
2728 #define MUTEX_DECLARE_STORAGE( name ) \
2729  KMUTEX name##CriticalSection; \
2730  BOOLEAN name##CriticalSectionInitialised
2731 #define MUTEX_CREATE( name, status ) \
2732  status = CRYPT_OK; /* Apparently never fails */ \
2733  if( !krnlData->name##CriticalSectionInitialised ) \
2734  { \
2735  KeInitializeMutex( &krnlData->name##CriticalSection, 1 ); \
2736  krnlData->name##CriticalSectionInitialised = TRUE; \
2737  }
2738 #define MUTEX_DESTROY( name )
2739 #define MUTEX_LOCK( name ) \
2740  KeWaitForMutexObject( &krnlData->name##CriticalSection, Executive, \
2741  KernelMode, FALSE, NULL )
2742 #define MUTEX_UNLOCK( name ) \
2743  KeReleaseMutex( &krnlData->name##CriticalSection, FALSE )
2744 
2745 /****************************************************************************
2746 * *
2747 * Non-threaded OSes *
2748 * *
2749 ****************************************************************************/
2750 
2751 #else
2752 
2753 /* Generic or NOP versions of functions and types declared for those OSes
2754  that don't support threading */
2755 
2756 #define THREAD_HANDLE int
2757 #define MUTEX_HANDLE int
2758 
2759 #define MUTEX_DECLARE_STORAGE( name )
2760 #define MUTEX_CREATE( name, status ) status = CRYPT_OK
2761 #define MUTEX_DESTROY( name )
2762 #define MUTEX_LOCK( name )
2763 #define MUTEX_UNLOCK( name )
2764 
2765 #define THREAD_CREATE( function, arg, threadHandle, syncHandle, status ) \
2766  status = CRYPT_ERROR
2767 #define THREAD_EXIT( sync )
2768 #define THREAD_INITIALISER 0
2769 #define THREAD_SAME( thread1, thread2 ) TRUE
2770 #define THREAD_SELF() 0
2771 #define THREAD_SLEEP( ms )
2772 #define THREAD_YIELD()
2773 #define THREAD_WAIT( sync, status )
2774 #define THREAD_CLOSE( sync )
2775 
2776 #endif /* Threading support macros */
2777 
2778 /****************************************************************************
2779 * *
2780 * Generic Defines *
2781 * *
2782 ****************************************************************************/
2783 
2784 /* To initialise thread/mutex handles we need our own version of DUMMY_INIT,
2785  since this may be an OS-specific and/or non-scalar value we only define
2786  it if it hasn't already been defined above */
2787 
2788 #ifndef DUMMY_INIT_MUTEX
2789  #define DUMMY_INIT_MUTEX ( MUTEX_HANDLE ) DUMMY_INIT
2790 #endif /* !DUMMY_INIT_MUTEX */
2791 
2792 #endif /* _THREAD_DEFINED */