/* wether word reads are potentially non-atomic. * this is conservatice, likely most arches this runs * on have atomic word read/writes. */ #ifndef WORDACCESS_UNSAFE # if __i386 || __x86_64 # define WORDACCESS_UNSAFE 0 # else # define WORDACCESS_UNSAFE 1 # endif #endif ///////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 typedef int ssize_t; #define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls #define _WIN32_WINNT 0x400 #include //D #include #include #include #include #include #define sigset_t int #define sigfillset(a) #define pthread_sigmask(a,b,c) #define sigaddset(a,b) #define sigemptyset(s) #define sigfillset(s) #define pthread_kill(a,b) #define pthread_self() 0 typedef HANDLE mutex_t; #define X_MUTEX_INIT 0 #define X_MUTEX_CHECK(mutex) if (!(mutex)) (mutex) = CreateMutex (NULL, FALSE, NULL) #define X_LOCK(mutex) WaitForSingleObject ((mutex), INFINITE) #define X_UNLOCK(mutex) ReleaseMutex (mutex) typedef HANDLE cond_t; #define X_COND_INIT 0 #define X_COND_CHECK(cond) if (!(cond)) (cond) = CreateEvent (NULL, FALSE, FALSE, NULL) #define X_COND_SIGNAL(cond) SetEvent (cond) #define X_COND_WAIT(cond,mutex) do { SignalObjectAndWait ((mutex), (cond),INFINITE, FALSE); WaitForSingleObject ((mutex), INFINITE); } while (0) #define ETIMEDOUT 1 struct timespec { unsigned long tv_sec, tv_nsec; }; static int X_COND_TIMEDWAIT (mutex_t mutex, cond_t cond, struct timespec to) { unsigned long ms = to.tv_nsec / 1000 + to.tv_sec * 1000; if (SignalObjectAndWait (mutex, cond, ms, FALSE) == WAIT_TIMEOUT) return ETIMEDOUT; if (WaitForSingleObject (mutex, ms) == WAIT_TIMEOUT) return ETIMEDOUT; return 0; } typedef DWORD thread_t; #define X_THREAD_PROC(name) DWORD WINAPI name (LPVOID thr_arg) #define X_THREAD_ATFORK(a,b,c) static int thread_create (thread_t *tid, LPTHREAD_START_ROUTINE proc, void *arg) { *tid = 0; CreateThread (0, 4096, proc, arg, 0, tid); return !!*tid; } int Perl_my_socketpair (int family, int type, int protocol, int fd[2]); static int create_pipe (int fd[2]) { int arg = 1; Perl_my_socketpair (AF_UNIX, SOCK_STREAM, 0, fd); ioctlsocket (fd [0], FIONBIO, &arg); ioctlsocket (fd [1], FIONBIO, &arg); return 1; } #else ///////////////////////////////////////////////////////////////////////////// /* solaris */ #define _POSIX_PTHREAD_SEMANTICS 1 #if __linux && !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif /* just in case */ #define _REENTRANT 1 #include #include #include #include #ifndef PTHREAD_STACK_MIN /* care for broken platforms, e.g. windows */ # define PTHREAD_STACK_MIN 16384 #endif typedef pthread_mutex_t mutex_t; #if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) # define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP #else # define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #endif #define X_LOCK(mutex) pthread_mutex_lock (&(mutex)) #define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) typedef pthread_cond_t cond_t; #define X_COND_INIT PTHREAD_COND_INITIALIZER #define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) #define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) #define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) typedef pthread_t thread_t; #define X_THREAD_PROC(name) static void *name (void *thr_arg) #define X_THREAD_ATFORK(prepare,parent,child) pthread_atfork (prepare, parent, child) static int thread_create (thread_t *tid, void *(*proc)(void *), void *arg) { int retval; sigset_t fullsigset, oldsigset; pthread_attr_t attr; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); #ifdef PTHREAD_SCOPE_PROCESS pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS); #endif sigfillset (&fullsigset); pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset); retval = pthread_create (tid, &attr, proc, arg) == 0; pthread_sigmask (SIG_SETMASK, &oldsigset, 0); return retval; } static int create_pipe (int fd[2]) { if (pipe (fd) || fcntl (fd [0], F_SETFL, O_NONBLOCK) || fcntl (fd [1], F_SETFL, O_NONBLOCK)) return 0; return 1; } #endif #if __ia64 # define STACKSIZE 65536 #elif __i386 || __x86_64 /* 16k is unreasonably high :( */ # define STACKSIZE PTHREAD_STACK_MIN #else # define STACKSIZE 16384 #endif