11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann 111b362b15af34006e6a11974088a46d42b903418eJohann 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#ifndef VP8_COMMON_THREADING_H_ 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VP8_COMMON_THREADING_H_ 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#ifdef __cplusplus 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianextern "C" { 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif 181b362b15af34006e6a11974088a46d42b903418eJohann 191b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD 201b362b15af34006e6a11974088a46d42b903418eJohann 211b362b15af34006e6a11974088a46d42b903418eJohann/* Thread management macros */ 221b362b15af34006e6a11974088a46d42b903418eJohann#ifdef _WIN32 231b362b15af34006e6a11974088a46d42b903418eJohann/* Win32 */ 241b362b15af34006e6a11974088a46d42b903418eJohann#include <process.h> 251b362b15af34006e6a11974088a46d42b903418eJohann#include <windows.h> 261b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION DWORD WINAPI 271b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION_RETURN DWORD 281b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_SPECIFIC_INDEX DWORD 291b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_t HANDLE 301b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_attr_t DWORD 311b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_create(thhandle,attr,thfunc,tharg) (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))thfunc,tharg,0,NULL))==NULL) 321b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_join(thread, result) ((WaitForSingleObject((thread),INFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread)) 331b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_detach(thread) if(thread!=NULL)CloseHandle(thread) 341b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) Sleep(nms) 351b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_cancel(thread) terminate_thread(thread,0) 361b362b15af34006e6a11974088a46d42b903418eJohann#define ts_key_create(ts_key, destructor) {ts_key = TlsAlloc();}; 371b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_getspecific(ts_key) TlsGetValue(ts_key) 381b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_setspecific(ts_key, value) TlsSetValue(ts_key, (void *)value) 391b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_self() GetCurrentThreadId() 401b362b15af34006e6a11974088a46d42b903418eJohann 411b362b15af34006e6a11974088a46d42b903418eJohann#elif defined(__OS2__) 421b362b15af34006e6a11974088a46d42b903418eJohann/* OS/2 */ 431b362b15af34006e6a11974088a46d42b903418eJohann#define INCL_DOS 441b362b15af34006e6a11974088a46d42b903418eJohann#include <os2.h> 451b362b15af34006e6a11974088a46d42b903418eJohann 461b362b15af34006e6a11974088a46d42b903418eJohann#include <stdlib.h> 471b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION void 481b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION_RETURN void 491b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_SPECIFIC_INDEX PULONG 501b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_t TID 511b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_attr_t ULONG 521b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_create(thhandle,attr,thfunc,tharg) \ 531b362b15af34006e6a11974088a46d42b903418eJohann ((int)((*(thhandle)=_beginthread(thfunc,NULL,1024*1024,tharg))==-1)) 541b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_join(thread, result) ((int)DosWaitThread(&(thread),0)) 551b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_detach(thread) 0 561b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) DosSleep(nms) 571b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_cancel(thread) DosKillThread(thread) 581b362b15af34006e6a11974088a46d42b903418eJohann#define ts_key_create(ts_key, destructor) \ 591b362b15af34006e6a11974088a46d42b903418eJohann DosAllocThreadLocalMemory(1, &(ts_key)); 601b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_getspecific(ts_key) ((void *)(*(ts_key))) 611b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_setspecific(ts_key, value) (*(ts_key)=(ULONG)(value)) 621b362b15af34006e6a11974088a46d42b903418eJohann#define pthread_self() _gettid() 631b362b15af34006e6a11974088a46d42b903418eJohann#else 641b362b15af34006e6a11974088a46d42b903418eJohann#ifdef __APPLE__ 651b362b15af34006e6a11974088a46d42b903418eJohann#include <mach/mach_init.h> 661b362b15af34006e6a11974088a46d42b903418eJohann#include <mach/semaphore.h> 671b362b15af34006e6a11974088a46d42b903418eJohann#include <mach/task.h> 681b362b15af34006e6a11974088a46d42b903418eJohann#include <time.h> 691b362b15af34006e6a11974088a46d42b903418eJohann#include <unistd.h> 701b362b15af34006e6a11974088a46d42b903418eJohann 711b362b15af34006e6a11974088a46d42b903418eJohann#else 721b362b15af34006e6a11974088a46d42b903418eJohann#include <semaphore.h> 731b362b15af34006e6a11974088a46d42b903418eJohann#endif 741b362b15af34006e6a11974088a46d42b903418eJohann 751b362b15af34006e6a11974088a46d42b903418eJohann#include <pthread.h> 761b362b15af34006e6a11974088a46d42b903418eJohann/* pthreads */ 771b362b15af34006e6a11974088a46d42b903418eJohann/* Nearly everything is already defined */ 781b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION void * 791b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_FUNCTION_RETURN void * 801b362b15af34006e6a11974088a46d42b903418eJohann#define THREAD_SPECIFIC_INDEX pthread_key_t 811b362b15af34006e6a11974088a46d42b903418eJohann#define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor); 821b362b15af34006e6a11974088a46d42b903418eJohann#endif 831b362b15af34006e6a11974088a46d42b903418eJohann 841b362b15af34006e6a11974088a46d42b903418eJohann/* Syncrhronization macros: Win32 and Pthreads */ 851b362b15af34006e6a11974088a46d42b903418eJohann#ifdef _WIN32 861b362b15af34006e6a11974088a46d42b903418eJohann#define sem_t HANDLE 871b362b15af34006e6a11974088a46d42b903418eJohann#define pause(voidpara) __asm PAUSE 881b362b15af34006e6a11974088a46d42b903418eJohann#define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateSemaphore(NULL,0,32768,NULL))==NULL) 891b362b15af34006e6a11974088a46d42b903418eJohann#define sem_wait(sem) (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem,INFINITE)) 901b362b15af34006e6a11974088a46d42b903418eJohann#define sem_post(sem) ReleaseSemaphore(*sem,1,NULL) 911b362b15af34006e6a11974088a46d42b903418eJohann#define sem_destroy(sem) if(*sem)((int)(CloseHandle(*sem))==TRUE) 921b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) Sleep(nms) 931b362b15af34006e6a11974088a46d42b903418eJohann 941b362b15af34006e6a11974088a46d42b903418eJohann#elif defined(__OS2__) 951b362b15af34006e6a11974088a46d42b903418eJohanntypedef struct 961b362b15af34006e6a11974088a46d42b903418eJohann{ 971b362b15af34006e6a11974088a46d42b903418eJohann HEV event; 981b362b15af34006e6a11974088a46d42b903418eJohann HMTX wait_mutex; 991b362b15af34006e6a11974088a46d42b903418eJohann HMTX count_mutex; 1001b362b15af34006e6a11974088a46d42b903418eJohann int count; 1011b362b15af34006e6a11974088a46d42b903418eJohann} sem_t; 1021b362b15af34006e6a11974088a46d42b903418eJohann 1031b362b15af34006e6a11974088a46d42b903418eJohannstatic inline int sem_init(sem_t *sem, int pshared, unsigned int value) 1041b362b15af34006e6a11974088a46d42b903418eJohann{ 1051b362b15af34006e6a11974088a46d42b903418eJohann DosCreateEventSem(NULL, &sem->event, pshared ? DC_SEM_SHARED : 0, 1061b362b15af34006e6a11974088a46d42b903418eJohann value > 0 ? TRUE : FALSE); 1071b362b15af34006e6a11974088a46d42b903418eJohann DosCreateMutexSem(NULL, &sem->wait_mutex, 0, FALSE); 1081b362b15af34006e6a11974088a46d42b903418eJohann DosCreateMutexSem(NULL, &sem->count_mutex, 0, FALSE); 1091b362b15af34006e6a11974088a46d42b903418eJohann 1101b362b15af34006e6a11974088a46d42b903418eJohann sem->count = value; 1111b362b15af34006e6a11974088a46d42b903418eJohann 1121b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1131b362b15af34006e6a11974088a46d42b903418eJohann} 1141b362b15af34006e6a11974088a46d42b903418eJohann 1151b362b15af34006e6a11974088a46d42b903418eJohannstatic inline int sem_wait(sem_t * sem) 1161b362b15af34006e6a11974088a46d42b903418eJohann{ 1171b362b15af34006e6a11974088a46d42b903418eJohann DosRequestMutexSem(sem->wait_mutex, -1); 1181b362b15af34006e6a11974088a46d42b903418eJohann 1191b362b15af34006e6a11974088a46d42b903418eJohann DosWaitEventSem(sem->event, -1); 1201b362b15af34006e6a11974088a46d42b903418eJohann 1211b362b15af34006e6a11974088a46d42b903418eJohann DosRequestMutexSem(sem->count_mutex, -1); 1221b362b15af34006e6a11974088a46d42b903418eJohann 1231b362b15af34006e6a11974088a46d42b903418eJohann sem->count--; 1241b362b15af34006e6a11974088a46d42b903418eJohann if (sem->count == 0) 1251b362b15af34006e6a11974088a46d42b903418eJohann { 1261b362b15af34006e6a11974088a46d42b903418eJohann ULONG post_count; 1271b362b15af34006e6a11974088a46d42b903418eJohann 1281b362b15af34006e6a11974088a46d42b903418eJohann DosResetEventSem(sem->event, &post_count); 1291b362b15af34006e6a11974088a46d42b903418eJohann } 1301b362b15af34006e6a11974088a46d42b903418eJohann 1311b362b15af34006e6a11974088a46d42b903418eJohann DosReleaseMutexSem(sem->count_mutex); 1321b362b15af34006e6a11974088a46d42b903418eJohann 1331b362b15af34006e6a11974088a46d42b903418eJohann DosReleaseMutexSem(sem->wait_mutex); 1341b362b15af34006e6a11974088a46d42b903418eJohann 1351b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1361b362b15af34006e6a11974088a46d42b903418eJohann} 1371b362b15af34006e6a11974088a46d42b903418eJohann 1381b362b15af34006e6a11974088a46d42b903418eJohannstatic inline int sem_post(sem_t * sem) 1391b362b15af34006e6a11974088a46d42b903418eJohann{ 1401b362b15af34006e6a11974088a46d42b903418eJohann DosRequestMutexSem(sem->count_mutex, -1); 1411b362b15af34006e6a11974088a46d42b903418eJohann 1421b362b15af34006e6a11974088a46d42b903418eJohann if (sem->count < 32768) 1431b362b15af34006e6a11974088a46d42b903418eJohann { 1441b362b15af34006e6a11974088a46d42b903418eJohann sem->count++; 1451b362b15af34006e6a11974088a46d42b903418eJohann DosPostEventSem(sem->event); 1461b362b15af34006e6a11974088a46d42b903418eJohann } 1471b362b15af34006e6a11974088a46d42b903418eJohann 1481b362b15af34006e6a11974088a46d42b903418eJohann DosReleaseMutexSem(sem->count_mutex); 1491b362b15af34006e6a11974088a46d42b903418eJohann 1501b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1511b362b15af34006e6a11974088a46d42b903418eJohann} 1521b362b15af34006e6a11974088a46d42b903418eJohann 1531b362b15af34006e6a11974088a46d42b903418eJohannstatic inline int sem_destroy(sem_t * sem) 1541b362b15af34006e6a11974088a46d42b903418eJohann{ 1551b362b15af34006e6a11974088a46d42b903418eJohann DosCloseEventSem(sem->event); 1561b362b15af34006e6a11974088a46d42b903418eJohann DosCloseMutexSem(sem->wait_mutex); 1571b362b15af34006e6a11974088a46d42b903418eJohann DosCloseMutexSem(sem->count_mutex); 1581b362b15af34006e6a11974088a46d42b903418eJohann 1591b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1601b362b15af34006e6a11974088a46d42b903418eJohann} 1611b362b15af34006e6a11974088a46d42b903418eJohann 1621b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) DosSleep(nms) 1631b362b15af34006e6a11974088a46d42b903418eJohann 1641b362b15af34006e6a11974088a46d42b903418eJohann#else 1651b362b15af34006e6a11974088a46d42b903418eJohann 1661b362b15af34006e6a11974088a46d42b903418eJohann#ifdef __APPLE__ 1671b362b15af34006e6a11974088a46d42b903418eJohann#define sem_t semaphore_t 1681b362b15af34006e6a11974088a46d42b903418eJohann#define sem_init(X,Y,Z) semaphore_create(mach_task_self(), X, SYNC_POLICY_FIFO, Z) 1691b362b15af34006e6a11974088a46d42b903418eJohann#define sem_wait(sem) (semaphore_wait(*sem) ) 1701b362b15af34006e6a11974088a46d42b903418eJohann#define sem_post(sem) semaphore_signal(*sem) 1711b362b15af34006e6a11974088a46d42b903418eJohann#define sem_destroy(sem) semaphore_destroy(mach_task_self(),*sem) 1721b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) /* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ 1731b362b15af34006e6a11974088a46d42b903418eJohann#else 1741b362b15af34006e6a11974088a46d42b903418eJohann#include <unistd.h> 1751b362b15af34006e6a11974088a46d42b903418eJohann#include <sched.h> 1761b362b15af34006e6a11974088a46d42b903418eJohann#define thread_sleep(nms) sched_yield();/* {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ 1771b362b15af34006e6a11974088a46d42b903418eJohann#endif 1781b362b15af34006e6a11974088a46d42b903418eJohann/* Not Windows. Assume pthreads */ 1791b362b15af34006e6a11974088a46d42b903418eJohann 1801b362b15af34006e6a11974088a46d42b903418eJohann#endif 1811b362b15af34006e6a11974088a46d42b903418eJohann 1821b362b15af34006e6a11974088a46d42b903418eJohann#if ARCH_X86 || ARCH_X86_64 1831b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_ports/x86.h" 1841b362b15af34006e6a11974088a46d42b903418eJohann#else 1851b362b15af34006e6a11974088a46d42b903418eJohann#define x86_pause_hint() 1861b362b15af34006e6a11974088a46d42b903418eJohann#endif 1871b362b15af34006e6a11974088a46d42b903418eJohann 1881b362b15af34006e6a11974088a46d42b903418eJohann#endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */ 1891b362b15af34006e6a11974088a46d42b903418eJohann 190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#ifdef __cplusplus 191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} // extern "C" 1921b362b15af34006e6a11974088a46d42b903418eJohann#endif 193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#endif // VP8_COMMON_THREADING_H_ 195