version 1.1.2.2, 2006/07/28 17:41:27
|
version 1.14.2.2, 2007/12/01 01:16:30
|
|
|
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Mike Brasher (m.brasher@inovadevelopment.com) |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#ifndef Pegasus_Threads_h | #ifndef Pegasus_Threads_h |
#define Pegasus_Threads_h | #define Pegasus_Threads_h |
| |
#include <cstring> | #include <cstring> |
|
#include <cstdio> |
|
#include <cstring> |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
#include <Pegasus/Common/Linkage.h> | #include <Pegasus/Common/Linkage.h> |
| |
|
// ATTN: can we consolidate these someplace? |
|
|
#if defined(PEGASUS_HAVE_PTHREADS) | #if defined(PEGASUS_HAVE_PTHREADS) |
# if defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM) |
|
# define _MULTI_THREADED // Is this really necessary? |
|
# endif |
|
# include <pthread.h> | # include <pthread.h> |
# include <errno.h> | # include <errno.h> |
# include <sys/time.h> | # include <sys/time.h> |
#elif defined(PEGASUS_HAVE_WINDOWS_THREADS) | #elif defined(PEGASUS_HAVE_WINDOWS_THREADS) |
# include <windows.h> | # include <windows.h> |
|
# include <process.h> |
#else | #else |
# error "<Pegasus/Common/Threads.h>: not implemented" | # error "<Pegasus/Common/Threads.h>: not implemented" |
#endif | #endif |
|
|
// | // |
//============================================================================== | //============================================================================== |
| |
#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) |
#if defined(PEGASUS_OS_TYPE_WINDOWS) |
# define PEGASUS_THREAD_CDECL __stdcall | # define PEGASUS_THREAD_CDECL __stdcall |
#else | #else |
# define PEGASUS_THREAD_CDECL /* empty */ | # define PEGASUS_THREAD_CDECL /* empty */ |
|
|
| |
//============================================================================== | //============================================================================== |
// | // |
// Thread-related type definitions |
// ThreadId |
// | // |
//============================================================================== | //============================================================================== |
| |
#if defined(PEGASUS_HAVE_PTHREADS) |
struct ThreadId |
|
|
struct ThreadType |
|
{ |
|
public: |
|
|
|
ThreadType() |
|
{ |
|
clear(); |
|
} |
|
|
|
ThreadType(const ThreadType& x) : _thread(x._thread), _id(x._id) |
|
{ | { |
} |
// The character representation of a uint64 requires 22 bytes including the |
|
// null terminator. |
|
char buffer[22]; |
|
}; |
| |
ThreadType(pthread_t thread, Uint32 id) : _thread(thread), _id(id) |
//============================================================================== |
{ |
// |
} |
// ThreadType |
|
// |
|
//============================================================================== |
| |
ThreadType& operator=(const ThreadType& x) |
#if defined(PEGASUS_HAVE_PTHREADS) |
|
struct ThreadType |
{ | { |
if (&x != this) |
ThreadType() |
{ | { |
_id = x._id; |
memset(&thread, 0, sizeof(thread)); |
_thread = x._thread; |
|
} |
|
return *this; |
|
} | } |
| |
void clear() |
ThreadType(pthread_t thread_) : thread(thread_) |
{ | { |
memset(this, 0, sizeof(*this)); |
|
} | } |
| |
pthread_t thread() const |
pthread_t thread; |
{ |
}; |
return _thread; |
#endif /* PEGASUS_HAVE_PTHREADS */ |
} |
|
| |
Uint32 id() const |
#if defined(PEGASUS_HAVE_WINDOWS_THREADS) |
|
struct ThreadType |
{ | { |
return _id; |
ThreadType() : handle(NULL) |
} |
|
|
|
void print() const |
|
{ | { |
printf("ThreadType(%lu, %lu)\n", _thread, (unsigned long)_id); |
|
} | } |
| |
private: |
HANDLE handle; |
pthread_t _thread; |
|
|
|
// And id of zero indicates a null object. 1 indicates the main thread. |
|
Uint32 _id; |
|
}; | }; |
|
#endif /* PEGASUS_HAVE_WINDOWS_THREADS */ |
| |
|
//============================================================================== |
|
// |
|
// ThreadReturnType |
|
// |
|
//============================================================================== |
|
|
|
#if defined(PEGASUS_HAVE_PTHREADS) |
typedef void* ThreadReturnType; | typedef void* ThreadReturnType; |
#endif | #endif |
| |
#if defined(PEGASUS_HAVE_WINDOWS_THREADS) | #if defined(PEGASUS_HAVE_WINDOWS_THREADS) |
typedef HANDLE ThreadType; |
|
typedef unsigned ThreadReturnType; | typedef unsigned ThreadReturnType; |
#endif | #endif |
| |
|
|
struct ThreadHandle | struct ThreadHandle |
{ | { |
ThreadType thid; | ThreadType thid; |
pthread_attr_t thatt; |
|
}; | }; |
#elif defined(PEGASUS_HAVE_WINDOWS_THREADS) | #elif defined(PEGASUS_HAVE_WINDOWS_THREADS) |
struct ThreadHandle | struct ThreadHandle |
{ | { |
ThreadType thid; | ThreadType thid; |
void * thatt; |
|
}; | }; |
#endif | #endif |
| |
|
|
static void cleanup_push(void (*start)(void*), void* arg); | static void cleanup_push(void (*start)(void*), void* arg); |
| |
static void cleanup_pop(int execute); | static void cleanup_pop(int execute); |
|
|
|
static ThreadId id(const ThreadType& x = Threads::self()); |
|
|
|
static bool null(const ThreadType& x = Threads::self()); |
|
|
|
static void clear(ThreadType& x); |
}; | }; |
| |
//============================================================================== | //============================================================================== |
|
|
| |
inline bool Threads::equal(ThreadType x, ThreadType y) | inline bool Threads::equal(ThreadType x, ThreadType y) |
{ | { |
return pthread_equal(x.thread(), y.thread()); |
return pthread_equal(x.thread, y.thread); |
} | } |
| |
inline void Threads::exit(ThreadReturnType rc) | inline void Threads::exit(ThreadReturnType rc) |
{ | { |
|
// NOTE: pthread_exit exhibits unusual behavior on RHEL 3 U2, as |
|
// documented in Bugzilla 3836. Where feasible, it may be advantageous |
|
// to avoid using this function. |
pthread_exit(rc); | pthread_exit(rc); |
} | } |
| |
inline void Threads::cancel(ThreadType th, ThreadReturnType rc) | inline void Threads::cancel(ThreadType th, ThreadReturnType rc) |
{ | { |
pthread_cancel(th.thread()); |
pthread_cancel(th.thread); |
} | } |
| |
inline void Threads::yield() | inline void Threads::yield() |
{ | { |
#if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || \ | #if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || \ |
|
defined(PEGASUS_PLATFORM_PASE_ISERIES_IBMCXX) || \ |
defined(PEGASUS_PLATFORM_HPUX_ACC) || \ | defined(PEGASUS_PLATFORM_HPUX_ACC) || \ |
defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM) || \ |
|
defined(PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX) || \ | defined(PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX) || \ |
defined(PEGASUS_OS_VMS) |
defined(PEGASUS_OS_VMS) || \ |
|
defined(PEGASUS_OS_ZOS) || \ |
|
defined(PEGASUS_OS_VXWORKS) || \ |
|
defined(PEGASUS_OS_DARWIN) || \ |
|
defined(PEGASUS_OS_SOLARIS) |
sched_yield(); | sched_yield(); |
#else | #else |
pthread_yield(); | pthread_yield(); |
|
|
// ATTN: not implemented. | // ATTN: not implemented. |
} | } |
| |
|
inline ThreadId Threads::id(const ThreadType& x) |
|
{ |
|
ThreadId tid; |
|
|
|
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) |
|
const char* s = x.thread.__; |
|
sprintf(tid.buffer, "%X%X%X%X%X%X%X%X", |
|
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]); |
|
#else |
|
sprintf(tid.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", |
|
Uint64(x.thread)); |
|
#endif |
|
|
|
return tid; |
|
} |
|
|
|
inline bool Threads::null(const ThreadType& x) |
|
{ |
|
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) |
|
Uint64 tmp; |
|
memcpy(&tmp, x.thread.__, sizeof(Uint64)); |
|
return tmp == 0; |
|
#else |
|
return x.thread == 0; |
|
#endif |
|
} |
|
|
|
inline void Threads::clear(ThreadType& x) |
|
{ |
|
memset(&x, 0, sizeof(x)); |
|
} |
|
|
#endif /* defined(PEGASUS_HAVE_PTHREADS) */ | #endif /* defined(PEGASUS_HAVE_PTHREADS) */ |
| |
//============================================================================== | //============================================================================== |
|
|
| |
inline ThreadType Threads::self() | inline ThreadType Threads::self() |
{ | { |
return ThreadType(GetCurrentThreadId()); |
ThreadType tt; |
|
tt.handle = GetCurrentThread(); |
|
return tt; |
} | } |
| |
inline bool Threads::equal(ThreadType x, ThreadType y) | inline bool Threads::equal(ThreadType x, ThreadType y) |
{ | { |
return x == y; |
return x.handle == y.handle; |
} | } |
| |
inline void Threads::exit(ThreadReturnType rc) | inline void Threads::exit(ThreadReturnType rc) |
|
|
| |
inline void Threads::cancel(ThreadType th, ThreadReturnType rc) | inline void Threads::cancel(ThreadType th, ThreadReturnType rc) |
{ | { |
TerminateThread(th, rc); |
TerminateThread(th.handle, rc); |
} | } |
| |
inline void Threads::yield() | inline void Threads::yield() |
|
|
// ATTN: Not implemented on Windows. | // ATTN: Not implemented on Windows. |
} | } |
| |
|
inline ThreadId Threads::id(const ThreadType& x) |
|
{ |
|
ThreadId tmp; |
|
|
|
sprintf(tmp.buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", |
|
Uint64(x.handle)); |
|
|
|
return tmp; |
|
} |
|
|
|
inline bool Threads::null(const ThreadType& x) |
|
{ |
|
return x.handle == NULL; |
|
} |
|
|
|
inline void Threads::clear(ThreadType& x) |
|
{ |
|
x.handle = NULL; |
|
} |
|
|
#endif /* defined(PEGASUS_HAVE_WINDOWS_THREADS) */ | #endif /* defined(PEGASUS_HAVE_WINDOWS_THREADS) */ |
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |