190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifndef _PTHREAD_EMULATION
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define _PTHREAD_EMULATION
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1576e0247ec867fcc232fc79f21e9bf85d3c3a5a3fAndreas Huber#define VPXINFINITE 10000       /* 10second. */
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* Thread management macros */
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef _WIN32
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* Win32 */
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define _WIN32_WINNT 0x500 /* WINBASE.H - Enable signal_object_and_wait */
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <process.h>
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <windows.h>
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_FUNCTION DWORD WINAPI
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_FUNCTION_RETURN DWORD
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_SPECIFIC_INDEX DWORD
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_t HANDLE
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_attr_t DWORD
2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_create(thhandle,attr,thfunc,tharg) (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))thfunc,tharg,0,NULL))==NULL)
2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_join(thread, result) ((WaitForSingleObject((thread),VPXINFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread))
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_detach(thread) if(thread!=NULL)CloseHandle(thread)
3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define thread_sleep(nms) Sleep(nms)
3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_cancel(thread) terminate_thread(thread,0)
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define ts_key_create(ts_key, destructor) {ts_key = TlsAlloc();};
3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_getspecific(ts_key) TlsGetValue(ts_key)
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_setspecific(ts_key, value) TlsSetValue(ts_key, (void *)value)
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pthread_self() GetCurrentThreadId()
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef __APPLE__
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <mach/semaphore.h>
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <mach/task.h>
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <time.h>
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <unistd.h>
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <semaphore.h>
4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <pthread.h>
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* pthreads */
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* Nearly everything is already defined */
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_FUNCTION void *
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_FUNCTION_RETURN void *
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define THREAD_SPECIFIC_INDEX pthread_key_t
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor);
5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* Syncrhronization macros: Win32 and Pthreads */
5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef _WIN32
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_t HANDLE
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define pause(voidpara) __asm PAUSE
6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateEvent(NULL,FALSE,FALSE,NULL))==NULL)
6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_wait(sem) (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem,VPXINFINITE))
6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_post(sem) SetEvent(*sem)
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_destroy(sem) if(*sem)((int)(CloseHandle(*sem))==TRUE)
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define thread_sleep(nms) Sleep(nms)
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef __APPLE__
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_t semaphore_t
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_init(X,Y,Z) semaphore_create(mach_task_self(), X, SYNC_POLICY_FIFO, Z)
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_wait(sem) (semaphore_wait(*sem) )
7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_post(sem) semaphore_signal(*sem)
7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define sem_destroy(sem) semaphore_destroy(mach_task_self(),*sem)
7576e0247ec867fcc232fc79f21e9bf85d3c3a5a3fAndreas Huber#define thread_sleep(nms) /* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */
7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <unistd.h>
78f71323e297a928af368937089d3ed71239786f86Andreas Huber#include <sched.h>
7976e0247ec867fcc232fc79f21e9bf85d3c3a5a3fAndreas Huber#define thread_sleep(nms) sched_yield();/* {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */
8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* Not Windows. Assume pthreads */
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if ARCH_X86 || ARCH_X86_64
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_ports/x86.h"
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define x86_pause_hint()
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
92