michael@0: /* michael@0: * Copyright (c) 2010 The WebM project authors. All Rights Reserved. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license michael@0: * that can be found in the LICENSE file in the root of the source michael@0: * tree. An additional intellectual property rights grant can be found michael@0: * in the file PATENTS. All contributing project authors may michael@0: * be found in the AUTHORS file in the root of the source tree. michael@0: */ michael@0: michael@0: michael@0: #ifndef _PTHREAD_EMULATION michael@0: #define _PTHREAD_EMULATION michael@0: michael@0: #if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD michael@0: michael@0: /* Thread management macros */ michael@0: #ifdef _WIN32 michael@0: /* Win32 */ michael@0: #include michael@0: #include michael@0: #define THREAD_FUNCTION DWORD WINAPI michael@0: #define THREAD_FUNCTION_RETURN DWORD michael@0: #define THREAD_SPECIFIC_INDEX DWORD michael@0: #define pthread_t HANDLE michael@0: #define pthread_attr_t DWORD michael@0: #define pthread_create(thhandle,attr,thfunc,tharg) (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))thfunc,tharg,0,NULL))==NULL) michael@0: #define pthread_join(thread, result) ((WaitForSingleObject((thread),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread)) michael@0: #define pthread_detach(thread) if(thread!=NULL)CloseHandle(thread) michael@0: #define thread_sleep(nms) Sleep(nms) michael@0: #define pthread_cancel(thread) terminate_thread(thread,0) michael@0: #define ts_key_create(ts_key, destructor) {ts_key = TlsAlloc();}; michael@0: #define pthread_getspecific(ts_key) TlsGetValue(ts_key) michael@0: #define pthread_setspecific(ts_key, value) TlsSetValue(ts_key, (void *)value) michael@0: #define pthread_self() GetCurrentThreadId() michael@0: michael@0: #elif defined(__OS2__) michael@0: /* OS/2 */ michael@0: #define INCL_DOS michael@0: #include michael@0: michael@0: #include michael@0: #define THREAD_FUNCTION void michael@0: #define THREAD_FUNCTION_RETURN void michael@0: #define THREAD_SPECIFIC_INDEX PULONG michael@0: #define pthread_t TID michael@0: #define pthread_attr_t ULONG michael@0: #define pthread_create(thhandle,attr,thfunc,tharg) \ michael@0: ((int)((*(thhandle)=_beginthread(thfunc,NULL,1024*1024,tharg))==-1)) michael@0: #define pthread_join(thread, result) ((int)DosWaitThread(&(thread),0)) michael@0: #define pthread_detach(thread) 0 michael@0: #define thread_sleep(nms) DosSleep(nms) michael@0: #define pthread_cancel(thread) DosKillThread(thread) michael@0: #define ts_key_create(ts_key, destructor) \ michael@0: DosAllocThreadLocalMemory(1, &(ts_key)); michael@0: #define pthread_getspecific(ts_key) ((void *)(*(ts_key))) michael@0: #define pthread_setspecific(ts_key, value) (*(ts_key)=(ULONG)(value)) michael@0: #define pthread_self() _gettid() michael@0: #else michael@0: #ifdef __APPLE__ michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #else michael@0: #include michael@0: #endif michael@0: michael@0: #include michael@0: /* pthreads */ michael@0: /* Nearly everything is already defined */ michael@0: #define THREAD_FUNCTION void * michael@0: #define THREAD_FUNCTION_RETURN void * michael@0: #define THREAD_SPECIFIC_INDEX pthread_key_t michael@0: #define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor); michael@0: #endif michael@0: michael@0: /* Syncrhronization macros: Win32 and Pthreads */ michael@0: #ifdef _WIN32 michael@0: #define sem_t HANDLE michael@0: #define pause(voidpara) __asm PAUSE michael@0: #define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateSemaphore(NULL,0,32768,NULL))==NULL) michael@0: #define sem_wait(sem) (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem,INFINITE)) michael@0: #define sem_post(sem) ReleaseSemaphore(*sem,1,NULL) michael@0: #define sem_destroy(sem) if(*sem)((int)(CloseHandle(*sem))==TRUE) michael@0: #define thread_sleep(nms) Sleep(nms) michael@0: michael@0: #elif defined(__OS2__) michael@0: typedef struct michael@0: { michael@0: HEV event; michael@0: HMTX wait_mutex; michael@0: HMTX count_mutex; michael@0: int count; michael@0: } sem_t; michael@0: michael@0: static inline int sem_init(sem_t *sem, int pshared, unsigned int value) michael@0: { michael@0: DosCreateEventSem(NULL, &sem->event, pshared ? DC_SEM_SHARED : 0, michael@0: value > 0 ? TRUE : FALSE); michael@0: DosCreateMutexSem(NULL, &sem->wait_mutex, 0, FALSE); michael@0: DosCreateMutexSem(NULL, &sem->count_mutex, 0, FALSE); michael@0: michael@0: sem->count = value; michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static inline int sem_wait(sem_t * sem) michael@0: { michael@0: DosRequestMutexSem(sem->wait_mutex, -1); michael@0: michael@0: DosWaitEventSem(sem->event, -1); michael@0: michael@0: DosRequestMutexSem(sem->count_mutex, -1); michael@0: michael@0: sem->count--; michael@0: if (sem->count == 0) michael@0: { michael@0: ULONG post_count; michael@0: michael@0: DosResetEventSem(sem->event, &post_count); michael@0: } michael@0: michael@0: DosReleaseMutexSem(sem->count_mutex); michael@0: michael@0: DosReleaseMutexSem(sem->wait_mutex); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static inline int sem_post(sem_t * sem) michael@0: { michael@0: DosRequestMutexSem(sem->count_mutex, -1); michael@0: michael@0: if (sem->count < 32768) michael@0: { michael@0: sem->count++; michael@0: DosPostEventSem(sem->event); michael@0: } michael@0: michael@0: DosReleaseMutexSem(sem->count_mutex); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static inline int sem_destroy(sem_t * sem) michael@0: { michael@0: DosCloseEventSem(sem->event); michael@0: DosCloseMutexSem(sem->wait_mutex); michael@0: DosCloseMutexSem(sem->count_mutex); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: #define thread_sleep(nms) DosSleep(nms) michael@0: michael@0: #else michael@0: michael@0: #ifdef __APPLE__ michael@0: #define sem_t semaphore_t michael@0: #define sem_init(X,Y,Z) semaphore_create(mach_task_self(), X, SYNC_POLICY_FIFO, Z) michael@0: #define sem_wait(sem) (semaphore_wait(*sem) ) michael@0: #define sem_post(sem) semaphore_signal(*sem) michael@0: #define sem_destroy(sem) semaphore_destroy(mach_task_self(),*sem) michael@0: #define thread_sleep(nms) /* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ michael@0: #else michael@0: #include michael@0: #include michael@0: #define thread_sleep(nms) sched_yield();/* {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ michael@0: #endif michael@0: /* Not Windows. Assume pthreads */ michael@0: michael@0: #endif michael@0: michael@0: #if ARCH_X86 || ARCH_X86_64 michael@0: #include "vpx_ports/x86.h" michael@0: #else michael@0: #define x86_pause_hint() michael@0: #endif michael@0: michael@0: #endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */ michael@0: michael@0: #endif