ref: ae0bd3ee024c068787c4da686fb3872a4d246a9c
parent: b6dcd94cb016ebc3a6d93fe9d42f957b23ec7a28
parent: 68f32c3c2916f99e90f30c49fbed219ff5f2724a
author: Ethan Hugg <ethanhugg@gmail.com>
date: Tue Jan 21 05:33:50 EST 2014
Merge pull request #182 from mstorsjo/move-threadlib Move the WelsThreadLib files to the common directory/library
--- a/codec/WelsThreadLib/api/WelsThreadLib.h
+++ /dev/null
@@ -1,152 +1,0 @@
-/*!
- * \copy
- * Copyright (c) 2009-2013, Cisco Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * \file WelsThreadLib.h
- *
- * \brief Interfaces introduced in thread programming
- *
- * \date 11/17/2009 Created
- *
- *************************************************************************************
- */
-
-#ifndef _WELS_THREAD_API_H_
-#define _WELS_THREAD_API_H_
-
-#include "typedefs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(_WIN32)
-
-#include <windows.h>
-
-typedef HANDLE WELS_THREAD_HANDLE;
-typedef LPTHREAD_START_ROUTINE LPWELS_THREAD_ROUTINE;
-
-typedef CRITICAL_SECTION WELS_MUTEX;
-typedef HANDLE WELS_EVENT;
-
-#define WELS_THREAD_ROUTINE_TYPE DWORD WINAPI
-#define WELS_THREAD_ROUTINE_RETURN(rc) return (DWORD)rc;
-
-#else // NON-WINDOWS
-
-#if defined(__GNUC__) // LINUX, MACOS etc
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-
-typedef pthread_t WELS_THREAD_HANDLE;
-typedef void* (*LPWELS_THREAD_ROUTINE) (void*);
-
-typedef pthread_mutex_t WELS_MUTEX;
-typedef sem_t WELS_EVENT;
-
-#define WELS_THREAD_ROUTINE_TYPE void *
-#define WELS_THREAD_ROUTINE_RETURN(rc) return (void*)(intptr_t)rc;
-
-#endif//__GNUC__
-
-#endif//_WIN32
-
-typedef int32_t WELS_THREAD_ERROR_CODE;
-typedef int32_t WELS_THREAD_ATTR;
-
-typedef struct _WelsLogicalProcessorInfo {
- int32_t ProcessorCount;
-} WelsLogicalProcessInfo;
-
-#define WELS_THREAD_ERROR_OK 0
-#define WELS_THREAD_ERROR_GENERAL ((uint32_t)(-1))
-#define WELS_THREAD_ERROR_WAIT_OBJECT_0 0
-#define WELS_THREAD_ERROR_WAIT_TIMEOUT ((uint32_t)0x00000102L)
-#define WELS_THREAD_ERROR_WAIT_FAILED WELS_THREAD_ERROR_GENERAL
-
-void WelsSleep (uint32_t dwMilliseconds);
-WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex);
-WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex);
-WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex);
-WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex);
-
-#ifdef __GNUC__
-WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT** p_event, str_t* event_name);
-WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, str_t* event_name);
-#endif//__GNUC__
-WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event);
-WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event);
-WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event);
-WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event);
-WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event);
-WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds);
-#ifdef _WIN32
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, WELS_EVENT* event_list,
- uint32_t dwMilliseconds);
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT* event_list);
-#else
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, WELS_EVENT** event_list,
- uint32_t dwMilliseconds);
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT** event_list);
-#endif//_WIN32
-
-WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
- void* arg, WELS_THREAD_ATTR attr);
-
-WELS_THREAD_ERROR_CODE WelsSetThreadCancelable();
-
-WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread);
-
-WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread);
-
-WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread);
-
-WELS_THREAD_HANDLE WelsThreadSelf();
-
-WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/codec/WelsThreadLib/src/WelsThreadLib.cpp
+++ /dev/null
@@ -1,513 +1,0 @@
-/*!
- * \copy
- * Copyright (c) 2009-2013, Cisco Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * \file WelsThreadLib.c
- *
- * \brief Interfaces introduced in thread programming
- *
- * \date 11/17/2009 Created
- *
- *************************************************************************************
- */
-
-
-#include "WelsThreadLib.h"
-#include <stdio.h>
-
-#ifdef _WIN32
-
-void WelsSleep (uint32_t dwMilliseconds) {
- Sleep (dwMilliseconds);
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
- InitializeCriticalSection (mutex);
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
- EnterCriticalSection (mutex);
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
- LeaveCriticalSection (mutex);
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
- DeleteCriticalSection (mutex);
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event) {
- WELS_EVENT h = CreateEvent (NULL, FALSE, FALSE, NULL);
-
- if (h == NULL) {
- return WELS_THREAD_ERROR_GENERAL;
- }
- *event = h;
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) {
- if (SetEvent (*event)) {
- return WELS_THREAD_ERROR_OK;
- }
- return WELS_THREAD_ERROR_GENERAL;
-}
-
-WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event) {
- if (ResetEvent (*event))
- return WELS_THREAD_ERROR_OK;
- return WELS_THREAD_ERROR_GENERAL;
-}
-
-WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) {
- return WaitForSingleObject (*event, INFINITE);
-}
-
-WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
- return WaitForSingleObject (*event, dwMilliseconds);
-}
-
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount,
- WELS_EVENT* event_list,
- uint32_t dwMilliseconds) {
- return WaitForMultipleObjects (nCount, event_list, FALSE, dwMilliseconds);
-}
-
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT* event_list) {
- return WaitForMultipleObjects (nCount, event_list, TRUE, (uint32_t) - 1);
-}
-
-WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event) {
- CloseHandle (*event);
-
- *event = NULL;
- return WELS_THREAD_ERROR_OK;
-}
-
-
-WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
- void* arg, WELS_THREAD_ATTR attr) {
- WELS_THREAD_HANDLE h = CreateThread (NULL, 0, routine, arg, 0, NULL);
-
- if (h == NULL) {
- return WELS_THREAD_ERROR_GENERAL;
- }
- * thread = h;
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsSetThreadCancelable() {
- // nil implementation for WIN32
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
- WaitForSingleObject (thread, INFINITE);
-
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread) {
- return WELS_THREAD_ERROR_OK;
-}
-
-
-WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread) {
- if (thread != NULL) {
- CloseHandle (*thread);
- *thread = NULL;
- }
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_HANDLE WelsThreadSelf() {
- return GetCurrentThread();
-}
-
-WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo) {
- SYSTEM_INFO si;
-
- GetSystemInfo (&si);
-
- pInfo->ProcessorCount = si.dwNumberOfProcessors;
-
- return WELS_THREAD_ERROR_OK;
-}
-
-#elif defined(__GNUC__)
-
-#ifdef MACOS
-#include <CoreServices/CoreServices.h>
-//#include <Gestalt.h>
-#endif//MACOS
-
-static int32_t SystemCall (const str_t* pCmd, str_t* pRes, int32_t iSize) {
- int32_t fd[2];
- int32_t iPid;
- int32_t iCount;
- int32_t left;
- str_t* p = NULL;
- int32_t iMaxLen = iSize - 1;
- memset (pRes, 0, iSize);
-
- if (pipe (fd)) {
- return -1;
- }
-
- if ((iPid = fork()) == 0) {
- int32_t fd2[2];
- if (pipe (fd2)) {
- return -1;
- }
- close (STDOUT_FILENO);
- dup2 (fd2[1], STDOUT_FILENO);
- close (fd[0]);
- close (fd2[1]);
- system (pCmd);
- read (fd2[0], pRes, iMaxLen);
- write (fd[1], pRes, strlen (pRes)); // confirmed_safe_unsafe_usage
- close (fd2[0]);
- close (fd[1]);
- exit (0);
- }
- close (fd[1]);
- p = pRes;
- left = iMaxLen;
- while ((iCount = read (fd[0], p, left))) {
- p += iCount;
- left -= iCount;
- if (left <= 0) break;
- }
- close (fd[0]);
- return 0;
-}
-
-void WelsSleep (uint32_t dwMilliseconds) {
- usleep (dwMilliseconds * 1000); // microseconds
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
- void* arg, WELS_THREAD_ATTR attr) {
- WELS_THREAD_ERROR_CODE err = 0;
-
- pthread_attr_t at;
- err = pthread_attr_init (&at);
- if (err)
- return err;
- err = pthread_attr_setscope (&at, PTHREAD_SCOPE_SYSTEM);
- if (err)
- return err;
- err = pthread_attr_setschedpolicy (&at, SCHED_FIFO);
- if (err)
- return err;
- err = pthread_create (thread, &at, routine, arg);
-
- pthread_attr_destroy (&at);
-
- return err;
-
-// return pthread_create(thread, NULL, routine, arg);
-}
-
-WELS_THREAD_ERROR_CODE WelsSetThreadCancelable() {
- WELS_THREAD_ERROR_CODE err = pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
- if (0 == err)
- err = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL);
- return err;
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
- return pthread_join (thread, NULL);
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread) {
- return pthread_cancel (thread);
-}
-
-WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread) {
- return WELS_THREAD_ERROR_OK;
-}
-
-WELS_THREAD_HANDLE WelsThreadSelf() {
- return pthread_self();
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
- return pthread_mutex_init (mutex, NULL);
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
- return pthread_mutex_lock (mutex);
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
- return pthread_mutex_unlock (mutex);
-}
-
-WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
- return pthread_mutex_destroy (mutex);
-}
-
-// unnamed semaphores can not work well for posix threading models under not root users
-
-WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event) {
- return sem_init (event, 0, 0);
-}
-
-WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event) {
- return sem_destroy (event); // match with sem_init
-}
-
-WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT** p_event, str_t* event_name) {
- if (p_event == NULL || event_name == NULL)
- return WELS_THREAD_ERROR_GENERAL;
- *p_event = sem_open (event_name, O_CREAT, (S_IRUSR | S_IWUSR)/*0600*/, 0);
- if (*p_event == (sem_t*)SEM_FAILED) {
- sem_unlink (event_name);
- *p_event = NULL;
- return WELS_THREAD_ERROR_GENERAL;
- } else {
- return WELS_THREAD_ERROR_OK;
- }
-}
-WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, str_t* event_name) {
- WELS_THREAD_ERROR_CODE err = sem_close (event); // match with sem_open
- if (event_name)
- sem_unlink (event_name);
- return err;
-}
-
-WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) {
- WELS_THREAD_ERROR_CODE err = 0;
-// int32_t val = 0;
-// sem_getvalue(event, &val);
-// fprintf( stderr, "before signal it, val= %d..\n",val );
- err = sem_post (event);
-// sem_getvalue(event, &val);
-// fprintf( stderr, "after signal it, val= %d..\n",val );
- return err;
-}
-WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event) {
- // FIXME for posix event reset, seems not be supported for pthread??
- sem_close (event);
- return sem_init (event, 0, 0);
-}
-
-WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) {
- return sem_wait (event); // blocking until signaled
-}
-
-WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
- if (dwMilliseconds != (uint32_t) - 1) {
- return sem_wait (event);
- } else {
-#if defined(MACOS)
- int32_t err = 0;
- int32_t wait_count = 0;
- do {
- err = sem_trywait (event);
- if (WELS_THREAD_ERROR_OK == err)
- break;// WELS_THREAD_ERROR_OK;
- else if (wait_count > 0)
- break;
- usleep (dwMilliseconds * 1000);
- ++ wait_count;
- } while (1);
- return err;
-#else
- struct timespec ts;
- struct timeval tv;
-
- gettimeofday (&tv, 0);
-
- ts.tv_sec = tv.tv_sec + dwMilliseconds / 1000;
- ts.tv_nsec = tv.tv_usec * 1000 + (dwMilliseconds % 1000) * 1000000;
-
- return sem_timedwait (event, &ts);
-#endif//MACOS
- }
-}
-
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount,
- WELS_EVENT** event_list,
- uint32_t dwMilliseconds) {
- // bWaitAll = FALSE && blocking
- uint32_t nIdx = 0;
- const uint32_t kuiAccessTime = 2; // 2 us once
-// uint32_t uiSleepMs = 0;
-
- if (nCount == 0)
- return WELS_THREAD_ERROR_WAIT_FAILED;
-
- while (1) {
- nIdx = 0; // access each event by order
- while (nIdx < nCount) {
- int32_t err = 0;
-//#if defined(MACOS) // clock_gettime(CLOCK_REALTIME) & sem_timedwait not supported on mac, so have below impl
- int32_t wait_count = 0;
-// struct timespec ts;
-// struct timeval tv;
-//
-// gettimeofday(&tv,0);
-// ts.tv_sec = tv.tv_sec/*+ kuiAccessTime / 1000*/; // second
-// ts.tv_nsec = (tv.tv_usec + kuiAccessTime) * 1000; // nano-second
-
- /*
- * although such interface is not used in __GNUC__ like platform, to use
- * pthread_cond_timedwait() might be better choice if need
- */
- do {
- err = sem_trywait (event_list[nIdx]);
- if (WELS_THREAD_ERROR_OK == err)
- return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx;
- else if (wait_count > 0)
- break;
- usleep (kuiAccessTime);
- ++ wait_count;
- } while (1);
-//#else
-// struct timespec ts;
-//
-// if ( clock_gettime(CLOCK_REALTIME, &ts) == -1 )
-// return WELS_THREAD_ERROR_WAIT_FAILED;
-// ts.tv_nsec += kuiAccessTime/*(kuiAccessTime % 1000)*/ * 1000;
-//
-//// fprintf( stderr, "sem_timedwait(): start to wait event %d..\n", nIdx );
-// err = sem_timedwait(event_list[nIdx], &ts);
-//// if ( err == -1 )
-//// {
-//// sem_getvalue(&event_list[nIdx], &val);
-//// fprintf( stderr, "sem_timedwait() errno(%d) semaphore %d..\n", errno, val);
-//// return WELS_THREAD_ERROR_WAIT_FAILED;
-//// }
-//// fprintf( stderr, "sem_timedwait(): wait event %d result %d errno %d..\n", nIdx, err, errno );
-// if ( WELS_THREAD_ERROR_OK == err ) // non-blocking mode
-// {
-//// int32_t val = 0;
-//// sem_getvalue(&event_list[nIdx], &val);
-//// fprintf( stderr, "after sem_timedwait(), event_list[%d] semaphore value= %d..\n", nIdx, val);
-//// fprintf( stderr, "WelsMultipleEventsWaitSingleBlocking sleep %d us\n", uiSleepMs);
-// return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx;
-// }
-//#endif
- // we do need access next event next time
- ++ nIdx;
-// uiSleepMs += kuiAccessTime;
- }
- usleep (1); // switch to working threads
-// ++ uiSleepMs;
- }
-
- return WELS_THREAD_ERROR_WAIT_FAILED;
-}
-
-WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT** event_list) {
- // bWaitAll = TRUE && blocking
- uint32_t nIdx = 0;
-// const uint32_t kuiAccessTime = (uint32_t)-1;// 1 ms once
- uint32_t uiCountSignals = 0;
- uint32_t uiSignalFlag = 0; // UGLY: suppose maximal event number up to 32
-
- if (nCount == 0 || nCount > (sizeof (uint32_t) << 3))
- return WELS_THREAD_ERROR_WAIT_FAILED;
-
- while (1) {
- nIdx = 0; // access each event by order
- while (nIdx < nCount) {
- const uint32_t kuiBitwiseFlag = (1 << nIdx);
-
- if ((uiSignalFlag & kuiBitwiseFlag) != kuiBitwiseFlag) { // non-blocking mode
- int32_t err = 0;
-// fprintf( stderr, "sem_wait(): start to wait event %d..\n", nIdx );
- err = sem_wait (event_list[nIdx]);
-// fprintf( stderr, "sem_wait(): wait event %d result %d errno %d..\n", nIdx, err, errno );
- if (WELS_THREAD_ERROR_OK == err) {
-// int32_t val = 0;
-// sem_getvalue(&event_list[nIdx], &val);
-// fprintf( stderr, "after sem_timedwait(), event_list[%d] semaphore value= %d..\n", nIdx, val);
-
- uiSignalFlag |= kuiBitwiseFlag;
- ++ uiCountSignals;
- if (uiCountSignals >= nCount) {
- return WELS_THREAD_ERROR_OK;
- }
- }
- }
- // we do need access next event next time
- ++ nIdx;
- }
- }
-
- return WELS_THREAD_ERROR_WAIT_FAILED;
-}
-
-WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo) {
-#ifdef LINUX
-
-#define CMD_RES_SIZE 2048
- str_t pBuf[CMD_RES_SIZE];
-
- SystemCall ("cat /proc/cpuinfo | grep \"processor\" | wc -l", pBuf, CMD_RES_SIZE);
-
- pInfo->ProcessorCount = atoi (pBuf);
-
- if (pInfo->ProcessorCount == 0) {
- pInfo->ProcessorCount = 1;
- }
-
- return WELS_THREAD_ERROR_OK;
-#undef CMD_RES_SIZE
-
-#else
-
- SInt32 cpunumber;
- Gestalt (gestaltCountOfCPUs, &cpunumber);
-
- pInfo->ProcessorCount = cpunumber;
-
- return WELS_THREAD_ERROR_OK;
-
-#endif//LINUX
-}
-
-#endif
-
-
-
--- a/codec/build/win32/enc/WelsEncCore.vcproj
+++ b/codec/build/win32/enc/WelsEncCore.vcproj
@@ -52,7 +52,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc,..\..\..\WelsThreadLib\api;"
+ AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;X86_ASM;MT_ENABLED"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -132,7 +132,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc,..\..\..\WelsThreadLib\api;"
+ AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc;"
PreprocessorDefinitions="WIN64;_DEBUG;_LIB;X86_ASM;MT_ENABLED"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -214,7 +214,7 @@
InlineFunctionExpansion="2"
FavorSizeOrSpeed="1"
WholeProgramOptimization="true"
- AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc,..\..\..\WelsThreadLib\api"
+ AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;X86_ASM;MT_ENABLED;"
StringPooling="true"
RuntimeLibrary="2"
@@ -298,7 +298,7 @@
InlineFunctionExpansion="2"
FavorSizeOrSpeed="1"
WholeProgramOptimization="true"
- AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc,..\..\..\WelsThreadLib\api"
+ AdditionalIncludeDirectories="..\..\..\common;..\..\..\encoder\core\inc,..\..\..\api\svc"
PreprocessorDefinitions="WIN64;NDEBUG;_LIB;MT_ENABLED;X86_ASM"
StringPooling="true"
RuntimeLibrary="2"
@@ -1416,7 +1416,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\..\WelsThreadLib\src\WelsThreadLib.cpp"
+ RelativePath="..\..\..\common\WelsThreadLib.cpp"
>
</File>
</Filter>
@@ -1649,7 +1649,7 @@
>
</File>
<File
- RelativePath="..\..\..\WelsThreadLib\api\WelsThreadLib.h"
+ RelativePath="..\..\..\common\WelsThreadLib.h"
>
</File>
</Filter>
--- /dev/null
+++ b/codec/common/WelsThreadLib.cpp
@@ -1,0 +1,516 @@
+/*!
+ * \copy
+ * Copyright (c) 2009-2013, Cisco Systems
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * \file WelsThreadLib.c
+ *
+ * \brief Interfaces introduced in thread programming
+ *
+ * \date 11/17/2009 Created
+ *
+ *************************************************************************************
+ */
+
+
+#include "WelsThreadLib.h"
+#include <stdio.h>
+
+#ifdef MT_ENABLED
+
+#ifdef _WIN32
+
+void WelsSleep (uint32_t dwMilliseconds) {
+ Sleep (dwMilliseconds);
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
+ InitializeCriticalSection (mutex);
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
+ EnterCriticalSection (mutex);
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
+ LeaveCriticalSection (mutex);
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
+ DeleteCriticalSection (mutex);
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event) {
+ WELS_EVENT h = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ if (h == NULL) {
+ return WELS_THREAD_ERROR_GENERAL;
+ }
+ *event = h;
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) {
+ if (SetEvent (*event)) {
+ return WELS_THREAD_ERROR_OK;
+ }
+ return WELS_THREAD_ERROR_GENERAL;
+}
+
+WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event) {
+ if (ResetEvent (*event))
+ return WELS_THREAD_ERROR_OK;
+ return WELS_THREAD_ERROR_GENERAL;
+}
+
+WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) {
+ return WaitForSingleObject (*event, INFINITE);
+}
+
+WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
+ return WaitForSingleObject (*event, dwMilliseconds);
+}
+
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount,
+ WELS_EVENT* event_list,
+ uint32_t dwMilliseconds) {
+ return WaitForMultipleObjects (nCount, event_list, FALSE, dwMilliseconds);
+}
+
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT* event_list) {
+ return WaitForMultipleObjects (nCount, event_list, TRUE, (uint32_t) - 1);
+}
+
+WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event) {
+ CloseHandle (*event);
+
+ *event = NULL;
+ return WELS_THREAD_ERROR_OK;
+}
+
+
+WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
+ void* arg, WELS_THREAD_ATTR attr) {
+ WELS_THREAD_HANDLE h = CreateThread (NULL, 0, routine, arg, 0, NULL);
+
+ if (h == NULL) {
+ return WELS_THREAD_ERROR_GENERAL;
+ }
+ * thread = h;
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsSetThreadCancelable() {
+ // nil implementation for WIN32
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
+ WaitForSingleObject (thread, INFINITE);
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread) {
+ return WELS_THREAD_ERROR_OK;
+}
+
+
+WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread) {
+ if (thread != NULL) {
+ CloseHandle (*thread);
+ *thread = NULL;
+ }
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_HANDLE WelsThreadSelf() {
+ return GetCurrentThread();
+}
+
+WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo) {
+ SYSTEM_INFO si;
+
+ GetSystemInfo (&si);
+
+ pInfo->ProcessorCount = si.dwNumberOfProcessors;
+
+ return WELS_THREAD_ERROR_OK;
+}
+
+#elif defined(__GNUC__)
+
+#ifdef MACOS
+#include <CoreServices/CoreServices.h>
+//#include <Gestalt.h>
+#endif//MACOS
+
+static int32_t SystemCall (const str_t* pCmd, str_t* pRes, int32_t iSize) {
+ int32_t fd[2];
+ int32_t iPid;
+ int32_t iCount;
+ int32_t left;
+ str_t* p = NULL;
+ int32_t iMaxLen = iSize - 1;
+ memset (pRes, 0, iSize);
+
+ if (pipe (fd)) {
+ return -1;
+ }
+
+ if ((iPid = fork()) == 0) {
+ int32_t fd2[2];
+ if (pipe (fd2)) {
+ return -1;
+ }
+ close (STDOUT_FILENO);
+ dup2 (fd2[1], STDOUT_FILENO);
+ close (fd[0]);
+ close (fd2[1]);
+ system (pCmd);
+ read (fd2[0], pRes, iMaxLen);
+ write (fd[1], pRes, strlen (pRes)); // confirmed_safe_unsafe_usage
+ close (fd2[0]);
+ close (fd[1]);
+ exit (0);
+ }
+ close (fd[1]);
+ p = pRes;
+ left = iMaxLen;
+ while ((iCount = read (fd[0], p, left))) {
+ p += iCount;
+ left -= iCount;
+ if (left <= 0) break;
+ }
+ close (fd[0]);
+ return 0;
+}
+
+void WelsSleep (uint32_t dwMilliseconds) {
+ usleep (dwMilliseconds * 1000); // microseconds
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
+ void* arg, WELS_THREAD_ATTR attr) {
+ WELS_THREAD_ERROR_CODE err = 0;
+
+ pthread_attr_t at;
+ err = pthread_attr_init (&at);
+ if (err)
+ return err;
+ err = pthread_attr_setscope (&at, PTHREAD_SCOPE_SYSTEM);
+ if (err)
+ return err;
+ err = pthread_attr_setschedpolicy (&at, SCHED_FIFO);
+ if (err)
+ return err;
+ err = pthread_create (thread, &at, routine, arg);
+
+ pthread_attr_destroy (&at);
+
+ return err;
+
+// return pthread_create(thread, NULL, routine, arg);
+}
+
+WELS_THREAD_ERROR_CODE WelsSetThreadCancelable() {
+ WELS_THREAD_ERROR_CODE err = pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ if (0 == err)
+ err = pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL);
+ return err;
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
+ return pthread_join (thread, NULL);
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread) {
+ return pthread_cancel (thread);
+}
+
+WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread) {
+ return WELS_THREAD_ERROR_OK;
+}
+
+WELS_THREAD_HANDLE WelsThreadSelf() {
+ return pthread_self();
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
+ return pthread_mutex_init (mutex, NULL);
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
+ return pthread_mutex_lock (mutex);
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
+ return pthread_mutex_unlock (mutex);
+}
+
+WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
+ return pthread_mutex_destroy (mutex);
+}
+
+// unnamed semaphores can not work well for posix threading models under not root users
+
+WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event) {
+ return sem_init (event, 0, 0);
+}
+
+WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event) {
+ return sem_destroy (event); // match with sem_init
+}
+
+WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT** p_event, str_t* event_name) {
+ if (p_event == NULL || event_name == NULL)
+ return WELS_THREAD_ERROR_GENERAL;
+ *p_event = sem_open (event_name, O_CREAT, (S_IRUSR | S_IWUSR)/*0600*/, 0);
+ if (*p_event == (sem_t*)SEM_FAILED) {
+ sem_unlink (event_name);
+ *p_event = NULL;
+ return WELS_THREAD_ERROR_GENERAL;
+ } else {
+ return WELS_THREAD_ERROR_OK;
+ }
+}
+WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, str_t* event_name) {
+ WELS_THREAD_ERROR_CODE err = sem_close (event); // match with sem_open
+ if (event_name)
+ sem_unlink (event_name);
+ return err;
+}
+
+WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event) {
+ WELS_THREAD_ERROR_CODE err = 0;
+// int32_t val = 0;
+// sem_getvalue(event, &val);
+// fprintf( stderr, "before signal it, val= %d..\n",val );
+ err = sem_post (event);
+// sem_getvalue(event, &val);
+// fprintf( stderr, "after signal it, val= %d..\n",val );
+ return err;
+}
+WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event) {
+ // FIXME for posix event reset, seems not be supported for pthread??
+ sem_close (event);
+ return sem_init (event, 0, 0);
+}
+
+WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event) {
+ return sem_wait (event); // blocking until signaled
+}
+
+WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
+ if (dwMilliseconds != (uint32_t) - 1) {
+ return sem_wait (event);
+ } else {
+#if defined(MACOS)
+ int32_t err = 0;
+ int32_t wait_count = 0;
+ do {
+ err = sem_trywait (event);
+ if (WELS_THREAD_ERROR_OK == err)
+ break;// WELS_THREAD_ERROR_OK;
+ else if (wait_count > 0)
+ break;
+ usleep (dwMilliseconds * 1000);
+ ++ wait_count;
+ } while (1);
+ return err;
+#else
+ struct timespec ts;
+ struct timeval tv;
+
+ gettimeofday (&tv, 0);
+
+ ts.tv_sec = tv.tv_sec + dwMilliseconds / 1000;
+ ts.tv_nsec = tv.tv_usec * 1000 + (dwMilliseconds % 1000) * 1000000;
+
+ return sem_timedwait (event, &ts);
+#endif//MACOS
+ }
+}
+
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount,
+ WELS_EVENT** event_list,
+ uint32_t dwMilliseconds) {
+ // bWaitAll = FALSE && blocking
+ uint32_t nIdx = 0;
+ const uint32_t kuiAccessTime = 2; // 2 us once
+// uint32_t uiSleepMs = 0;
+
+ if (nCount == 0)
+ return WELS_THREAD_ERROR_WAIT_FAILED;
+
+ while (1) {
+ nIdx = 0; // access each event by order
+ while (nIdx < nCount) {
+ int32_t err = 0;
+//#if defined(MACOS) // clock_gettime(CLOCK_REALTIME) & sem_timedwait not supported on mac, so have below impl
+ int32_t wait_count = 0;
+// struct timespec ts;
+// struct timeval tv;
+//
+// gettimeofday(&tv,0);
+// ts.tv_sec = tv.tv_sec/*+ kuiAccessTime / 1000*/; // second
+// ts.tv_nsec = (tv.tv_usec + kuiAccessTime) * 1000; // nano-second
+
+ /*
+ * although such interface is not used in __GNUC__ like platform, to use
+ * pthread_cond_timedwait() might be better choice if need
+ */
+ do {
+ err = sem_trywait (event_list[nIdx]);
+ if (WELS_THREAD_ERROR_OK == err)
+ return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx;
+ else if (wait_count > 0)
+ break;
+ usleep (kuiAccessTime);
+ ++ wait_count;
+ } while (1);
+//#else
+// struct timespec ts;
+//
+// if ( clock_gettime(CLOCK_REALTIME, &ts) == -1 )
+// return WELS_THREAD_ERROR_WAIT_FAILED;
+// ts.tv_nsec += kuiAccessTime/*(kuiAccessTime % 1000)*/ * 1000;
+//
+//// fprintf( stderr, "sem_timedwait(): start to wait event %d..\n", nIdx );
+// err = sem_timedwait(event_list[nIdx], &ts);
+//// if ( err == -1 )
+//// {
+//// sem_getvalue(&event_list[nIdx], &val);
+//// fprintf( stderr, "sem_timedwait() errno(%d) semaphore %d..\n", errno, val);
+//// return WELS_THREAD_ERROR_WAIT_FAILED;
+//// }
+//// fprintf( stderr, "sem_timedwait(): wait event %d result %d errno %d..\n", nIdx, err, errno );
+// if ( WELS_THREAD_ERROR_OK == err ) // non-blocking mode
+// {
+//// int32_t val = 0;
+//// sem_getvalue(&event_list[nIdx], &val);
+//// fprintf( stderr, "after sem_timedwait(), event_list[%d] semaphore value= %d..\n", nIdx, val);
+//// fprintf( stderr, "WelsMultipleEventsWaitSingleBlocking sleep %d us\n", uiSleepMs);
+// return WELS_THREAD_ERROR_WAIT_OBJECT_0 + nIdx;
+// }
+//#endif
+ // we do need access next event next time
+ ++ nIdx;
+// uiSleepMs += kuiAccessTime;
+ }
+ usleep (1); // switch to working threads
+// ++ uiSleepMs;
+ }
+
+ return WELS_THREAD_ERROR_WAIT_FAILED;
+}
+
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT** event_list) {
+ // bWaitAll = TRUE && blocking
+ uint32_t nIdx = 0;
+// const uint32_t kuiAccessTime = (uint32_t)-1;// 1 ms once
+ uint32_t uiCountSignals = 0;
+ uint32_t uiSignalFlag = 0; // UGLY: suppose maximal event number up to 32
+
+ if (nCount == 0 || nCount > (sizeof (uint32_t) << 3))
+ return WELS_THREAD_ERROR_WAIT_FAILED;
+
+ while (1) {
+ nIdx = 0; // access each event by order
+ while (nIdx < nCount) {
+ const uint32_t kuiBitwiseFlag = (1 << nIdx);
+
+ if ((uiSignalFlag & kuiBitwiseFlag) != kuiBitwiseFlag) { // non-blocking mode
+ int32_t err = 0;
+// fprintf( stderr, "sem_wait(): start to wait event %d..\n", nIdx );
+ err = sem_wait (event_list[nIdx]);
+// fprintf( stderr, "sem_wait(): wait event %d result %d errno %d..\n", nIdx, err, errno );
+ if (WELS_THREAD_ERROR_OK == err) {
+// int32_t val = 0;
+// sem_getvalue(&event_list[nIdx], &val);
+// fprintf( stderr, "after sem_timedwait(), event_list[%d] semaphore value= %d..\n", nIdx, val);
+
+ uiSignalFlag |= kuiBitwiseFlag;
+ ++ uiCountSignals;
+ if (uiCountSignals >= nCount) {
+ return WELS_THREAD_ERROR_OK;
+ }
+ }
+ }
+ // we do need access next event next time
+ ++ nIdx;
+ }
+ }
+
+ return WELS_THREAD_ERROR_WAIT_FAILED;
+}
+
+WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo) {
+#ifdef LINUX
+
+#define CMD_RES_SIZE 2048
+ str_t pBuf[CMD_RES_SIZE];
+
+ SystemCall ("cat /proc/cpuinfo | grep \"processor\" | wc -l", pBuf, CMD_RES_SIZE);
+
+ pInfo->ProcessorCount = atoi (pBuf);
+
+ if (pInfo->ProcessorCount == 0) {
+ pInfo->ProcessorCount = 1;
+ }
+
+ return WELS_THREAD_ERROR_OK;
+#undef CMD_RES_SIZE
+
+#else
+
+ SInt32 cpunumber;
+ Gestalt (gestaltCountOfCPUs, &cpunumber);
+
+ pInfo->ProcessorCount = cpunumber;
+
+ return WELS_THREAD_ERROR_OK;
+
+#endif//LINUX
+}
+
+#endif
+
+
+#endif // MT_ENABLED
+
--- /dev/null
+++ b/codec/common/WelsThreadLib.h
@@ -1,0 +1,152 @@
+/*!
+ * \copy
+ * Copyright (c) 2009-2013, Cisco Systems
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * \file WelsThreadLib.h
+ *
+ * \brief Interfaces introduced in thread programming
+ *
+ * \date 11/17/2009 Created
+ *
+ *************************************************************************************
+ */
+
+#ifndef _WELS_THREAD_API_H_
+#define _WELS_THREAD_API_H_
+
+#include "typedefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_WIN32)
+
+#include <windows.h>
+
+typedef HANDLE WELS_THREAD_HANDLE;
+typedef LPTHREAD_START_ROUTINE LPWELS_THREAD_ROUTINE;
+
+typedef CRITICAL_SECTION WELS_MUTEX;
+typedef HANDLE WELS_EVENT;
+
+#define WELS_THREAD_ROUTINE_TYPE DWORD WINAPI
+#define WELS_THREAD_ROUTINE_RETURN(rc) return (DWORD)rc;
+
+#else // NON-WINDOWS
+
+#if defined(__GNUC__) // LINUX, MACOS etc
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+typedef pthread_t WELS_THREAD_HANDLE;
+typedef void* (*LPWELS_THREAD_ROUTINE) (void*);
+
+typedef pthread_mutex_t WELS_MUTEX;
+typedef sem_t WELS_EVENT;
+
+#define WELS_THREAD_ROUTINE_TYPE void *
+#define WELS_THREAD_ROUTINE_RETURN(rc) return (void*)(intptr_t)rc;
+
+#endif//__GNUC__
+
+#endif//_WIN32
+
+typedef int32_t WELS_THREAD_ERROR_CODE;
+typedef int32_t WELS_THREAD_ATTR;
+
+typedef struct _WelsLogicalProcessorInfo {
+ int32_t ProcessorCount;
+} WelsLogicalProcessInfo;
+
+#define WELS_THREAD_ERROR_OK 0
+#define WELS_THREAD_ERROR_GENERAL ((uint32_t)(-1))
+#define WELS_THREAD_ERROR_WAIT_OBJECT_0 0
+#define WELS_THREAD_ERROR_WAIT_TIMEOUT ((uint32_t)0x00000102L)
+#define WELS_THREAD_ERROR_WAIT_FAILED WELS_THREAD_ERROR_GENERAL
+
+void WelsSleep (uint32_t dwMilliseconds);
+WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex);
+WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex);
+WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex);
+WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex);
+
+#ifdef __GNUC__
+WELS_THREAD_ERROR_CODE WelsEventOpen (WELS_EVENT** p_event, str_t* event_name);
+WELS_THREAD_ERROR_CODE WelsEventClose (WELS_EVENT* event, str_t* event_name);
+#endif//__GNUC__
+WELS_THREAD_ERROR_CODE WelsEventInit (WELS_EVENT* event);
+WELS_THREAD_ERROR_CODE WelsEventDestroy (WELS_EVENT* event);
+WELS_THREAD_ERROR_CODE WelsEventSignal (WELS_EVENT* event);
+WELS_THREAD_ERROR_CODE WelsEventReset (WELS_EVENT* event);
+WELS_THREAD_ERROR_CODE WelsEventWait (WELS_EVENT* event);
+WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds);
+#ifdef _WIN32
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, WELS_EVENT* event_list,
+ uint32_t dwMilliseconds);
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT* event_list);
+#else
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitSingleBlocking (uint32_t nCount, WELS_EVENT** event_list,
+ uint32_t dwMilliseconds);
+WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WELS_EVENT** event_list);
+#endif//_WIN32
+
+WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
+ void* arg, WELS_THREAD_ATTR attr);
+
+WELS_THREAD_ERROR_CODE WelsSetThreadCancelable();
+
+WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread);
+
+WELS_THREAD_ERROR_CODE WelsThreadCancel (WELS_THREAD_HANDLE thread);
+
+WELS_THREAD_ERROR_CODE WelsThreadDestroy (WELS_THREAD_HANDLE* thread);
+
+WELS_THREAD_HANDLE WelsThreadSelf();
+
+WELS_THREAD_ERROR_CODE WelsQueryLogicalProcessInfo (WelsLogicalProcessInfo* pInfo);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- a/codec/common/targets.mk
+++ b/codec/common/targets.mk
@@ -4,6 +4,7 @@
$(COMMON_SRCDIR)/./cpu.cpp\
$(COMMON_SRCDIR)/./deblocking_common.cpp\
$(COMMON_SRCDIR)/./logging.cpp\
+ $(COMMON_SRCDIR)/./WelsThreadLib.cpp\
COMMON_OBJS += $(COMMON_CPP_SRCS:.cpp=.o)
ifeq ($(USE_ASM), Yes)