1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef VP8_COMMON_THREADING_H_ 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define VP8_COMMON_THREADING_H_ 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __cplusplus 16233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern "C" { 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Thread management macros */ 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef _WIN32 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Win32 */ 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <process.h> 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <windows.h> 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION DWORD WINAPI 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION_RETURN DWORD 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_SPECIFIC_INDEX DWORD 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_t HANDLE 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_attr_t DWORD 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_create(thhandle,attr,thfunc,tharg) (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))thfunc,tharg,0,NULL))==NULL) 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_join(thread, result) ((WaitForSingleObject((thread),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread)) 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_detach(thread) if(thread!=NULL)CloseHandle(thread) 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) Sleep(nms) 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_cancel(thread) terminate_thread(thread,0) 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ts_key_create(ts_key, destructor) {ts_key = TlsAlloc();}; 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_getspecific(ts_key) TlsGetValue(ts_key) 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_setspecific(ts_key, value) TlsSetValue(ts_key, (void *)value) 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_self() GetCurrentThreadId() 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan#elif defined(__OS2__) 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* OS/2 */ 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define INCL_DOS 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <os2.h> 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION void 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION_RETURN void 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_SPECIFIC_INDEX PULONG 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_t TID 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_attr_t ULONG 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_create(thhandle,attr,thfunc,tharg) \ 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((int)((*(thhandle)=_beginthread(thfunc,NULL,1024*1024,tharg))==-1)) 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_join(thread, result) ((int)DosWaitThread(&(thread),0)) 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_detach(thread) 0 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) DosSleep(nms) 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_cancel(thread) DosKillThread(thread) 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ts_key_create(ts_key, destructor) \ 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosAllocThreadLocalMemory(1, &(ts_key)); 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_getspecific(ts_key) ((void *)(*(ts_key))) 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_setspecific(ts_key, value) (*(ts_key)=(ULONG)(value)) 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pthread_self() _gettid() 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __APPLE__ 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <mach/mach_init.h> 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <mach/semaphore.h> 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <mach/task.h> 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <time.h> 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <unistd.h> 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <semaphore.h> 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <pthread.h> 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* pthreads */ 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Nearly everything is already defined */ 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION void * 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_FUNCTION_RETURN void * 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define THREAD_SPECIFIC_INDEX pthread_key_t 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor); 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Syncrhronization macros: Win32 and Pthreads */ 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef _WIN32 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_t HANDLE 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define pause(voidpara) __asm PAUSE 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateSemaphore(NULL,0,32768,NULL))==NULL) 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_wait(sem) (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem,INFINITE)) 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_post(sem) ReleaseSemaphore(*sem,1,NULL) 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_destroy(sem) if(*sem)((int)(CloseHandle(*sem))==TRUE) 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) Sleep(nms) 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan#elif defined(__OS2__) 95233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan HEV event; 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan HMTX wait_mutex; 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan HMTX count_mutex; 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count; 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan} sem_t; 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 103233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic inline int sem_init(sem_t *sem, int pshared, unsigned int value) 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCreateEventSem(NULL, &sem->event, pshared ? DC_SEM_SHARED : 0, 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan value > 0 ? TRUE : FALSE); 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCreateMutexSem(NULL, &sem->wait_mutex, 0, FALSE); 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCreateMutexSem(NULL, &sem->count_mutex, 0, FALSE); 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan sem->count = value; 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan 115233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic inline int sem_wait(sem_t * sem) 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosRequestMutexSem(sem->wait_mutex, -1); 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosWaitEventSem(sem->event, -1); 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosRequestMutexSem(sem->count_mutex, -1); 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan sem->count--; 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sem->count == 0) 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan ULONG post_count; 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosResetEventSem(sem->event, &post_count); 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosReleaseMutexSem(sem->count_mutex); 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosReleaseMutexSem(sem->wait_mutex); 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan 138233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic inline int sem_post(sem_t * sem) 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosRequestMutexSem(sem->count_mutex, -1); 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sem->count < 32768) 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan sem->count++; 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosPostEventSem(sem->event); 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosReleaseMutexSem(sem->count_mutex); 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan 153233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic inline int sem_destroy(sem_t * sem) 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCloseEventSem(sem->event); 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCloseMutexSem(sem->wait_mutex); 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan DosCloseMutexSem(sem->count_mutex); 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) DosSleep(nms) 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __APPLE__ 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_t semaphore_t 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_init(X,Y,Z) semaphore_create(mach_task_self(), X, SYNC_POLICY_FIFO, Z) 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_wait(sem) (semaphore_wait(*sem) ) 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_post(sem) semaphore_signal(*sem) 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define sem_destroy(sem) semaphore_destroy(mach_task_self(),*sem) 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) /* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <unistd.h> 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <sched.h> 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define thread_sleep(nms) sched_yield();/* {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Not Windows. Assume pthreads */ 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if ARCH_X86_32 || ARCH_X86_64 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_ports/x86.h" 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define x86_pause_hint() 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */ 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __cplusplus 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan} // extern "C" 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // VP8_COMMON_THREADING_H_ 195