gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

ptimedsem.cxx (2111B)


      1 /*
      2  *
      3  *  C++ Portable Types Library (PTypes)
      4  *  Version 2.1.1  Released 27-Jun-2007
      5  *
      6  *  Copyright (C) 2001-2007 Hovik Melikyan
      7  *
      8  *  http://www.melikyan.com/ptypes/
      9  *
     10  */
     11 
     12 #ifdef WIN32
     13 #  include <windows.h>
     14 #else
     15 #  include <sys/time.h>
     16 #  include <pthread.h>
     17 #  include <errno.h>
     18 #endif
     19 
     20 #include "pasync.h"
     21 
     22 
     23 namespace ptypes {
     24 
     25 
     26 static void tsem_fail()
     27 {
     28     fatal(CRIT_FIRST + 41, "Timed semaphore failed");
     29 }
     30 
     31 
     32 #ifdef WIN32
     33 
     34 
     35 timedsem::timedsem(int initvalue)
     36 {
     37     handle = CreateSemaphore(nil, initvalue, 65535, nil);
     38     if (handle == 0)
     39         tsem_fail();
     40 }
     41 
     42 
     43 timedsem::~timedsem() 
     44 {
     45     CloseHandle(handle);
     46 }
     47 
     48 
     49 bool timedsem::wait(int timeout)
     50 {
     51     uint r = WaitForSingleObject(handle, timeout);
     52     if (r == WAIT_FAILED)
     53         tsem_fail();
     54     return r != WAIT_TIMEOUT;
     55 }
     56 
     57 
     58 void timedsem::post()
     59 {
     60     if (ReleaseSemaphore(handle, 1, nil) == 0)
     61         tsem_fail();
     62 }
     63 
     64 
     65 #else
     66 
     67 
     68 inline void tsem_syscheck(int r)
     69 {
     70     if (r != 0)
     71         tsem_fail();
     72 }
     73 
     74 
     75 timedsem::timedsem(int initvalue)
     76     : unknown(), count(initvalue)
     77 {
     78     tsem_syscheck(pthread_mutex_init(&mtx, 0));
     79     tsem_syscheck(pthread_cond_init(&cond, 0));
     80 }
     81 
     82 
     83 timedsem::~timedsem()
     84 {
     85     pthread_cond_destroy(&cond);
     86     pthread_mutex_destroy(&mtx);
     87 }
     88 
     89 
     90 bool timedsem::wait(int timeout)
     91 {
     92     pthread_mutex_lock(&mtx);
     93     while (count <= 0)
     94     { 
     95         if (timeout >= 0)
     96         {
     97             timespec abs_ts; 
     98             timeval cur_tv;
     99             gettimeofday(&cur_tv, NULL);
    100             abs_ts.tv_sec = cur_tv.tv_sec + timeout / 1000; 
    101             abs_ts.tv_nsec = cur_tv.tv_usec * 1000
    102                 + (timeout % 1000) * 1000000;
    103             int rc = pthread_cond_timedwait(&cond, &mtx, &abs_ts);
    104             if (rc == ETIMEDOUT) { 
    105                 pthread_mutex_unlock(&mtx);
    106                 return false;
    107             }
    108         }
    109         else
    110             pthread_cond_wait(&cond, &mtx);
    111     } 
    112     count--;
    113     pthread_mutex_unlock(&mtx);
    114     return true;
    115 } 
    116 
    117 
    118 void timedsem::post()
    119 {
    120     pthread_mutex_lock(&mtx);
    121     count++; 
    122     pthread_cond_signal(&cond);
    123     pthread_mutex_unlock(&mtx);
    124 }
    125 
    126 
    127 #endif
    128 
    129 
    130 }