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