Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.19 KB | None | 0 0
  1. #include <windows.h>
  2. #include <tchar.h>
  3. #include <errno.h>
  4. #include "pthread.h"
  5.  
  6. typedef BOOL (WINAPI *LPINIT_CSEX)(LPCRITICAL_SECTION pCS, DWORD dwSpinCount, DWORD Flags);
  7. typedef void (WINAPI *LPINIT_CS)(LPCRITICAL_SECTION pCS);
  8. static LPINIT_CSEX pInitializeCriticalSectionEx;
  9. #define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO         0x01000000
  10. #define CRITICAL_SECTION_NO_DEBUG_INFO  RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO
  11.  
  12. typedef struct
  13. {
  14.     CRITICAL_SECTION BroadcastLock;
  15.     CRITICAL_SECTION WaiterCountLock;
  16.     int iWaiterCount;  
  17.  
  18.     HANDLE hSemaphore; 
  19.     HANDLE hWaitersDone;
  20.     BOOL bNowBroadcast;
  21. } cond_handle;
  22.  
  23.  
  24. static void WINAPI InitCriticalSectionXP(LPCRITICAL_SECTION pCS)
  25. {
  26.     InitializeCriticalSection(pCS);
  27. }
  28.  
  29. static void WINAPI InitCriticalSectionVista(LPCRITICAL_SECTION pCS)
  30. {
  31.     pInitializeCriticalSectionEx(pCS, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
  32. }
  33.  
  34. static LPINIT_CS InitCriticalSection = InitCriticalSectionXP;
  35.  
  36. #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
  37. static pthread_t defMutex;
  38.  
  39. void pthread_initialize(void)
  40. {
  41.     BOOL VistaSupport = FALSE;
  42.     OSVERSIONINFOEX infoex = {};
  43.     infoex.dwOSVersionInfoSize = sizeof(infoex);
  44.     if(!GetVersionEx((LPOSVERSIONINFO) &infoex))
  45.     {
  46.         OSVERSIONINFO info = {};
  47.         info.dwOSVersionInfoSize = sizeof(info);
  48.         if(GetVersionEx(&info))
  49.         {
  50.             if(info.dwMajorVersion >= 6)
  51.                 VistaSupport = TRUE;
  52.         }
  53.     }
  54.     else
  55.     {
  56.         if(infoex.dwMajorVersion >= 6)
  57.         {
  58.             VistaSupport = TRUE;
  59.         }
  60.     }
  61.     if(VistaSupport)
  62.     {
  63.         InitCriticalSection = InitCriticalSectionVista;
  64.         pInitializeCriticalSectionEx = (LPINIT_CSEX) GetProcAddress( GetModuleHandle(_T("Kernel32.dll")), "InitializeCriticalSectionEx");
  65.     }
  66.     pthread_mutex_init(&defMutex, NULL);
  67. }
  68.  
  69. void pthread_finalize(void)
  70. {
  71.     pthread_mutex_destroy(&defMutex);
  72. }
  73.  
  74. struct func_convert_param
  75. {
  76.     HANDLE hEvent;
  77.     void *(*start_routine)(void *);
  78.     void* arg;
  79. };
  80.  
  81. unsigned int __stdcall func_convert(void* ptr)
  82. {
  83.     struct func_convert_param Param = *((struct func_convert_param*) ptr);
  84.     SetEvent(Param.hEvent);
  85.     Param.start_routine(Param.arg);
  86.     return 0;
  87. }
  88.  
  89. int pthread_create(
  90.     pthread_t *thread,
  91.     const pthread_attr_t *attr,
  92.     void *(*start_routine)(void *),
  93.     void *arg
  94.     )
  95. {
  96.     struct func_convert_param param;
  97.     param.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  98.     param.arg = arg;
  99.     param.start_routine = start_routine;
  100.     unsigned int x = _beginthreadex(NULL, 0, func_convert, &param, 0, NULL);
  101.     if(x == 0)
  102.     {
  103.         return errno;
  104.     }
  105.     WaitForSingleObject(param.hEvent, INFINITE);
  106.     CloseHandle(param.hEvent);
  107.     *thread = (pthread_t) x;
  108.     return 0;
  109. }
  110.  
  111. int pthread_join(
  112.     pthread_t thread,
  113.     void** value_ptr
  114.     )
  115. {
  116.     HANDLE hv = (HANDLE) thread;
  117.     DWORD dwRet = WaitForSingleObject(thread, INFINITE);
  118.     if(WAIT_OBJECT_0)
  119.     {
  120.         CloseHandle(hv);
  121.         return 0;
  122.     }
  123.     return EINVAL;
  124. }
  125.  
  126. int pthread_detach(
  127.     pthread_t thread
  128.     )
  129. {
  130.     HANDLE hv = (HANDLE) thread;
  131.     CloseHandle(hv);
  132.     return 0;
  133. }
  134.  
  135. pthread_t pthread_self(void)
  136. {
  137.     return (pthread_t) GetCurrentThread();
  138. }
  139.  
  140. int pthread_setschedparam(
  141.     pthread_t target_thread,
  142.     int policy,
  143.     const struct sched_param *param
  144.     )
  145. {
  146.     return 0;
  147. }
  148.  
  149. int pthread_getschedparam(
  150.     pthread_t target_thread,
  151.     int *policy,
  152.     struct sched_param *param
  153.     )
  154. {
  155.     param->sched_priority = 0;
  156.     return 0;
  157. }
  158.  
  159. int pthread_attr_init(
  160.     pthread_attr_t *attr
  161.     )
  162. {
  163.     return 0;
  164. }
  165.  
  166. int pthread_attr_destroy(
  167.     pthread_attr_t *attr
  168.     )
  169. {
  170.     return 0;
  171. }
  172.  
  173. // mutex
  174. int pthread_mutex_init(
  175.     pthread_mutex_t *mutex,
  176.     const pthread_mutexattr_t *attr
  177.     )
  178. {
  179.     HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
  180.     *mutex = (pthread_mutex_t*) hMutex;
  181.     return 0;
  182. }
  183. int pthread_mutex_destroy(
  184.     pthread_mutex_t *mutex
  185.     )
  186. {
  187.     HANDLE hMutex = (HANDLE) *mutex;
  188.     CloseHandle(hMutex);
  189.     return 0;
  190. }
  191. int pthread_mutex_lock(
  192.     pthread_mutex_t *mutex
  193.     )
  194. {
  195.     if(*mutex == PTHREAD_MUTEX_INITIALIZER)
  196.     {
  197.         *mutex = defMutex;
  198.     }
  199.     HANDLE hMutex = (HANDLE) *mutex;
  200.     WaitForSingleObject(hMutex, INFINITE);
  201.     return 0;
  202. }
  203. int pthread_mutex_trylock(
  204.     pthread_mutex_t *mutex
  205.     )
  206. {
  207.     if(*mutex == PTHREAD_MUTEX_INITIALIZER)
  208.     {
  209.         *mutex = defMutex;
  210.     }
  211.     HANDLE hMutex = (HANDLE) *mutex;
  212.     if(WaitForSingleObject(hMutex, 0) == WAIT_OBJECT_0) return 0;
  213.     return 1;
  214. }
  215. int pthread_mutex_unlock(
  216.     pthread_mutex_t *mutex
  217.     )
  218. {
  219.     if(*mutex == PTHREAD_MUTEX_INITIALIZER)
  220.     {
  221.         *mutex = defMutex;
  222.     }
  223.     HANDLE hMutex = (HANDLE) *mutex;
  224.     ReleaseMutex(hMutex);
  225.     return 0;
  226. }
  227.  
  228.  
  229. int pthread_cond_init(
  230.     pthread_cond_t *cond,
  231.     const pthread_condattr_t *attr
  232.     )
  233. {
  234.     cond_handle* x;
  235.     x = malloc(sizeof(cond_handle));
  236.  
  237.     x->iWaiterCount = 0;
  238.     x->bNowBroadcast = FALSE;
  239.     x->hSemaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
  240.     if(x->hSemaphore == NULL)
  241.     {
  242.         free(x);
  243.         return ENOMEM;
  244.     }
  245.     InitCriticalSection(&(x->WaiterCountLock));
  246.     InitCriticalSection(&(x->BroadcastLock));
  247.     x->hWaitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
  248.     if(x->hWaitersDone == NULL)
  249.     {
  250.         CloseHandle(x->hWaitersDone);
  251.         free(x);
  252.         return ENOMEM;
  253.     }
  254.     *cond = (pthread_cond_t) x;
  255.     return 0;
  256. }
  257.  
  258. int pthread_cond_destroy(
  259.     pthread_cond_t *cond
  260.     )
  261. {
  262.     cond_handle* x = (cond_handle*) *cond;
  263.     CloseHandle(x->hSemaphore);
  264.     CloseHandle(x->hWaitersDone);
  265.     DeleteCriticalSection(&(x->WaiterCountLock));
  266.     free(x);
  267.     return 0;
  268. }
  269.  
  270. int pthread_cond_signal(
  271.     pthread_cond_t *cond
  272.     )
  273. {
  274.     cond_handle* x = (cond_handle*) *cond;
  275.     EnterCriticalSection(&(x->WaiterCountLock));
  276.         BOOL bHaveWaiters = x->iWaiterCount > 0;
  277.     LeaveCriticalSection(&(x->WaiterCountLock));
  278.  
  279.     if (bHaveWaiters)
  280.     {
  281.         ReleaseSemaphore(x->hSemaphore, 1, 0);
  282.     }
  283.     return 0;
  284. }
  285.  
  286. int pthread_cond_broadcast(
  287.     pthread_cond_t *cond
  288.     )
  289. {
  290.     cond_handle* x = (cond_handle*) *cond;
  291.     EnterCriticalSection(&(x->BroadcastLock));
  292.     EnterCriticalSection(&(x->WaiterCountLock));
  293.     BOOL bHaveWaiter = FALSE;
  294.  
  295.     if (x->iWaiterCount > 0) {
  296.         x->bNowBroadcast = TRUE;
  297.         bHaveWaiter = TRUE;
  298.     }
  299.  
  300.     if (bHaveWaiter) {
  301.         ReleaseSemaphore(x->hSemaphore, x->iWaiterCount, 0);
  302.         LeaveCriticalSection(&(x->WaiterCountLock));
  303.         WaitForSingleObject(x->hWaitersDone, INFINITE);
  304.         x->bNowBroadcast = FALSE;
  305.     }
  306.     else
  307.     {
  308.         LeaveCriticalSection(&(x->WaiterCountLock));
  309.     }
  310.     LeaveCriticalSection(&(x->BroadcastLock));
  311.     return 0;
  312. }
  313.  
  314. int pthread_cond_wait(
  315.     pthread_cond_t *cond,
  316.     pthread_mutex_t *mutex
  317.     )
  318. {
  319.     cond_handle* x = (cond_handle*) *cond;
  320.     HANDLE y = (HANDLE) *mutex;
  321.  
  322.     EnterCriticalSection(&(x->BroadcastLock));
  323.     LeaveCriticalSection(&(x->BroadcastLock));
  324.  
  325.     EnterCriticalSection(&(x->WaiterCountLock));
  326.         x->iWaiterCount++;
  327.     LeaveCriticalSection(&(x->WaiterCountLock));
  328.  
  329.     SignalObjectAndWait(y, x->hSemaphore, INFINITE, FALSE);
  330.  
  331.     EnterCriticalSection(&(x->WaiterCountLock));
  332.         x->iWaiterCount--;
  333.         BOOL bLastWaiter = x->bNowBroadcast && x->iWaiterCount == 0;
  334.     LeaveCriticalSection(&(x->WaiterCountLock));
  335.  
  336.     if(bLastWaiter)
  337.     {
  338.         SignalObjectAndWait(x->hWaitersDone, y, INFINITE, FALSE);
  339.     }
  340.     else
  341.     {
  342.         WaitForSingleObject(y, INFINITE);
  343.     }
  344.     return 0;
  345. }
  346.  
  347. int pthread_num_processors_np(void)
  348. {
  349.     DWORD_PTR mask ;
  350.     DWORD_PTR unused ;
  351.     DWORD_PTR bit ;
  352.     int num = 0;
  353.  
  354.     GetProcessAffinityMask( GetCurrentProcess(), &mask, &unused ) ;
  355.  
  356.     for ( bit = 1; bit != 0 ; bit <<= 1)
  357.     {
  358.         if ( mask & bit )
  359.         {
  360.             ++num;
  361.         }
  362.     }
  363.     return num ;
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement