📄 cryptos.h
字号:
#define THREAD_SELF() pthread_self()
#define THREAD_SAME( thread1, thread2 ) \
pthread_equal( ( thread1 ), ( thread2 ) )
#define THREAD_SLEEP( ms ) { \
struct timeval tv = { 0 }; \
\
tv.tv_usec = ( ms ) * 1000; \
select( 1, NULL, NULL, NULL, &tv ); \
}
#define THREAD_WAIT( thread ) pthread_join( thread, NULL )
#define THREAD_CLOSE( thread )
/* Yield a thread's timeslice. This gets rather complex due to a confusion
of non-portable "portable" Posix functions. Initially there was
pthread_yield() from draft 4 of the Posix thread standard in 1990,
popularised in the DCE threading code and picked up by a number of
other implementations. Eventually this was deprecated in favour of
sched_yield(), however some implementations still do pthread_yield()
and some implementations use sched_yield() to yield the processes'
timeslice rather than the thread's timeslice. The whole is further
confused by the fact that in some implementations, threads are processes
(sort of, e.g. Linux's clone()'d threads and Sun LWPs). In addition Sun
have their own thr_yield which is part of their UI threads interface and
that you have to fall back to occasionally.
Because of this mess, we try for pthread_yield() if possible (since that
yields the thread's timeslice), fall back to sched_yield() if necessary,
and add a special workaround for Sun systems.
"Posix is portable in the sense that you can use a forklift to move the
printed volumes around" */
#if defined( __osf__ ) || defined( __alpha__ ) || defined( __APPLE__ )
#define THREAD_YIELD() pthread_yield_np()
#elif defined( __MVS__ )
#define THREAD_YIELD() pthread_yield( NULL )
#elif defined( sun )
/* Slowaris gets a bit complex, SunOS 4.x always returns -1 and sets errno
to ENOSYS when sched_yield() is called, so we use this to fall back to
the UI interface if necessary */
#define THREAD_YIELD() { if( sched_yield() ) thr_yield(); }
#elif defined( _AIX ) || defined( USE_SCHED_YIELD )
#define THREAD_YIELD() sched_yield()
#else
#define THREAD_YIELD() pthread_yield()
#endif /* Not-very-portable Posix portability */
/* OSF1 includes some ghastly kludgery to handle binary compatibility from
1003.4a to 1003.1c threading functions and inline asm functions with all
sorts of name mangling and translation of function names and types.
Unfortunately a straight vanilla compile leaves pthread_self() un-
prototyped, which means it's implicitly prototyped as returned an int.
This generates hundreds of warnings of int <-> pointer casting problems,
so if pthread_self() isn't redefined into one of a dozen different
mangled versions we prototype it ourselves here */
#if ( defined( __osf__ ) || defined( __alpha__ ) ) && \
!defined( pthread_self )
#ifdef _PTHREAD_USE_MANGLED_NAMES_
#define pthread_self __pthread_self
#endif /* Name mangling */
extern pthread_t pthread_self( void );
#endif /* OSF1 pthread_self function prototyping bug */
/* The pthreads implementation on MP-RAS (NCR User Space Threads based on
CMA threads for DCE) doesn't accept NULL for several of the attribute
arguments so we have to supply pthread_mutexattr_default attributes */
#ifdef _MPRAS
#undef MUTEX_INIT
#define MUTEX_INIT( mutex ) pthread_mutex_init( mutex, \
pthread_mutexattr_default )
#undef THREAD_CREATE
#define THREAD_CREATE( function, arg, handle ) \
( pthread_create( &handle, pthread_attr_default, \
function, arg ) ? CRYPT_ERROR : CRYPT_OK )
#endif /* _MPRAS */
/* Some systems (notable MVS and MP-RAS) use non-scalar pthread_t's, so we
have to handle initialisation of these specially */
#if defined( __MVS__ ) || defined( _MPRAS )
#undef THREAD_INITIALISER
#define THREAD_INITIALISER { 0 }
#endif /* Non-scalar pthread_t's */
/* UnixWare/SCO uses a default thread stack size so tiny that almost nothing
can run with it, so we have to use a custom thread-creation function that
sets the stack size to something reasonable */
#ifdef __SCO_VERSION__
#undef THREAD_CREATE
#define THREAD_CREATE( function, arg, handle ) \
createThread( function, arg, &handle )
int createThread( void *( *function )( void * ), void *arg, pthread_t *handle );
#endif /* UnixWare/SCO */
/* Some variables are protected by locks. Before we can read or write these
variables in a multithreaded environment we need to lock them so that they
can't be accessed or modified by other threads while we're using them.
The following macros provide this locking capability.
In some very unusual cases (see the initialistion handling code for
details) it's possible that an attempt might be made to lock a mutex
before it's been initialised (this can only happen due to a programming
error by the caller, unfortunately it can't always be caught reliably).
Setting the mutex to { 0 } is, in most threading implementations,
equivalent to initialising it normally, so we do this to catch most
occurences of the problem.
Due to the complexity of the locking process using pthreads' non-reentrant
mutexes, we don't try and lock+unlock the mutex before we destroy it.
This isn't a major issue since it's just a safety precaution, the kernel
should have forced any remaining threads to exit by the time the shutdown
occurs anyway */
#define DECLARE_LOCKING_VARS( name ) \
static MUTEX name##Mutex = { 0 }; \
static BOOLEAN name##MutexInitialised = FALSE; \
static THREAD name##MutexOwner; \
static int name##MutexLockcount = 0;
#define initResourceLock( name ) \
if( !name##MutexInitialised ) \
{ \
MUTEX_INIT( &name##Mutex ); \
name##MutexInitialised = TRUE; \
}
#define deleteResourceLock( name ) \
if( name##MutexInitialised ) \
{ \
MUTEX_DESTROY( &name##Mutex ); \
name##MutexInitialised = FALSE; \
}
#define lockResource( name ) \
if( MUTEX_TRYLOCK( &name##Mutex ) ) \
{ \
if( !THREAD_SAME( name##MutexOwner, THREAD_SELF() ) ) \
MUTEX_LOCK( &name##Mutex ); \
else \
name##MutexLockcount++; \
} \
name##MutexOwner = THREAD_SELF();
#define unlockResource( name ) \
if( name##MutexLockcount > 0 ) \
name##MutexLockcount--; \
else \
MUTEX_UNLOCK( &name##Mutex );
#elif defined( __BEOS__ )
#include <kernel/OS.h>
/* Handles to threads and system synchronisation objects */
#define THREAD_HANDLE THREAD
#define SEMAPHORE_HANDLE THREAD
/* Define a thread function */
#define THREADFUNC_DEFINE( name, arg ) thread_id name( void *arg )
/* Thead management functions. The re-entrancy of BeOS semaphores is
unclear, if they aren't re-entrant it would be necessary to emulate them
as for Posix threads
BeOS threads are created in the suspended state, so after we create the
thread we have to resume it to start it running */
#define MUTEX sem_id
#define MUTEX_INIT( mutex ) mutex = create_sem( 1, NULL )
#define MUTEX_DESTROY delete_sem
#define MUTEX_LOCK acquire_sem
#define MUTEX_TRYLOCK( mutex) ( acquire_sem_etc( mutex, 1, \
B_RELATIVE_TIMEOUT, 0 ) == B_WOULD_BLOCK )
#define MUTEX_UNLOCK release_sem
#define THREAD thread_id
#define THREAD_CREATE( function, arg, handle ) \
( ( handle = \
spawn_thread( function, NULL, \
B_NORMAL_PRIORITY, arg ) ) < B_NO_ERROR ? \
CRYPT_ERROR : \
resume_thread( handle ) )
#define THREAD_EXIT() exit_thread( 0 )
#define THREAD_CREATE_VARS
#define THREAD_INITIALISER 0
#define THREAD_SAME( thread1, thread2 ) \
( ( thread1 ) == ( thread2 ) )
#define THREAD_SELF() find_thread( NULL )
#define THREAD_SLEEP( ms ) snooze( ms )
#define THREAD_YIELD() snooze( estimate_max_scheduling_latency( -1 ) + 1 )
#define THREAD_WAIT( thread ) { \
status_t dummy; \
\
wait_for_thread( thread, &dummy ); \
}
#define THREAD_CLOSE( thread )
/* Some variables are protected by locks. Before we can read or write these
variables in a multithreaded environment we need to lock them so they
can't be accessed or modified by other threads while we're using them.
The following macros provide this locking capability.
In some very unusual cases (see the initialistion handling code for
details) it's possible that an attempt might be made to lock a mutex
before it's been initialised (this can only happen due to a programming
error by the caller, unfortunately it can't always be caught reliably).
Setting the mutex to { 0 } is, in most threading implementations,
equivalent to initialising it normally, so we do this to catch most
occurences of the problem */
#define DECLARE_LOCKING_VARS( name ) \
static MUTEX name##Mutex = { 0 }; \
static BOOLEAN name##MutexInitialised = FALSE; \
static THREAD name##MutexOwner; \
static int name##MutexLockcount = 0;
#define initResourceLock( name ) \
if( !name##MutexInitialised ) \
{ \
MUTEX_INIT( name##Mutex ); \
name##MutexInitialised = TRUE; \
}
#define deleteResourceLock( name ) \
if( name##MutexInitialised ) \
{ \
MUTEX_LOCK( name##Mutex ); \
MUTEX_UNLOCK( name##Mutex ); \
MUTEX_DESTROY( name##Mutex ); \
name##MutexInitialised = FALSE; \
}
#define lockResource( name ) \
if( MUTEX_TRYLOCK( name##Mutex ) ) \
{ \
if( !THREAD_SAME( name##MutexOwner, THREAD_SELF() ) ) \
MUTEX_LOCK( name##Mutex ); \
else \
name##MutexLockcount++; \
} \
name##MutexOwner = THREAD_SELF();
#define unlockResource( name ) \
if( name##MutexLockcount > 0 ) \
name##MutexLockcount--; \
else \
MUTEX_UNLOCK( name##Mutex );
/* Remember that we're using threaded functions */
#define USE_THREADS
#elif defined( __IBM4758__ )
#include <cpqlib.h>
/* Some variables are protected by locks. Before we can read or write these
variables in a multithreaded environment we need to lock them so they
can't be accessed or modified by other threads while we're using them.
The following macros provide this locking capability */
#define DECLARE_LOCKING_VARS( name ) \
static long name##Semaphore; \
static BOOLEAN name##SemaphoreInitialised = FALSE;
#define initResourceLock( name ) \
if( !name##SemaphoreInitialised ) \
{ \
CPCreateSerSem( NULL, 0, 0, &name##Semaphore ); \
name##SemaphoreInitialised = TRUE; \
}
#define deleteResourceLock( name ) \
if( name##SemaphoreInitialised ) \
{ \
CPSemClaim( name##Semaphore, SVCWAITFOREVER ); \
CPSemRelease( name##Semaphore ); \
CPDelete( name##Semaphore, 0 ); \
name##SemaphoreInitialised = FALSE; \
}
#define lockResource( name ) \
CPSemClaim( name##Semaphore, SVCWAITFOREVER )
#define unlockResource( name ) \
CPSemRelease( name##Semaphore )
/* Some objects are owned by one thread (called a task in CP/Q) and can't
be accessed by any other threads. The following macros provide facilities
to declare the thread ID variables and check that the current thread is
allowed to access this object.
Since the 4758 access control model differs somewhat from the standard one,
this facility isn't currently used */
/* Define a thread function: CP/Q tasks function in a somewhat peculiar
manner, this facility isn't currently used */
#endif /* OS-specific object locking and ownership handling */
/* Generic or NOP versions of functions and types declared for those OS's
that don't support extended functionality. The DECLARE_xxx macros are
expanded into dummy variable declarations to avoid problems with zero-
size entries in cases where they're the only element in a struct or
incomplete declarations where they're preceded by the static keyword or
various other, similar situations. In addition for the (global) locking
variable names we append the actual name to prevent name space
collisions */
#ifndef USE_THREADS
#define DECLARE_LOCKING_VARS( name ) int dummy##name;
#define initResourceLock( name )
#define deleteResourceLock( name )
#define lockResource( name )
#define unlockResource( name )
#define THREAD_HANDLE int
#define SEMAPHORE_HANDLE int
#define THREAD_INITIALISER 0
#define THREAD_SELF() 0
#define THREAD_SAME( thread1, thread2 ) TRUE
#define THREAD_YIELD()
#define THREAD_WAIT( thread )
#define THREAD_CLOSE( thread )
#endif /* Resource ownership macros */
/****************************************************************************
* *
* Misc.OS-specific Functions *
* *
****************************************************************************/
/* WinNT and its derivatives support ACL-based access control mechanisms for
system objects (modulo a great many holes), the following functions return
the security info needed to restrict access to owner-only when creating an
object */
#ifdef __WIN32__
void *initACLInfo( const int access );
void *getACLInfo( void *securityInfoPtr );
void freeACLInfo( void *securityInfoPtr );
#endif /* __WIN32__ */
#endif /* _CRYPTOS_DEFINED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -