LCOV - code coverage report
Current view: top level - src/jthread/pthread - jsemaphore.cpp (source / functions) Hit Total Coverage
Test: report Lines: 26 30 86.7 %
Date: 2015-07-11 18:23:49 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 sapier, < sapier AT gmx DOT net >
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : #include <assert.h>
      20             : #include <errno.h>
      21             : #include <sys/time.h>
      22             : #include "jthread/jsemaphore.h"
      23             : #if defined(__MACH__) && defined(__APPLE__)
      24             : #include <unistd.h>
      25             : #endif
      26             : 
      27             : #define UNUSED(expr) do { (void)(expr); } while (0)
      28             : 
      29             : #if defined(__MACH__) && defined(__APPLE__)
      30             : #undef sem_t
      31             : #undef sem_init
      32             : #undef sem_wait
      33             : #undef sem_post
      34             : #undef sem_destroy
      35             : #define sem_t             semaphore_t
      36             : #define sem_init(s, p, c) semaphore_create(mach_task_self(), (s), 0, (c))
      37             : #define sem_wait(s)       semaphore_wait(*(s))
      38             : #define sem_post(s)       semaphore_signal(*(s))
      39             : #define sem_destroy(s)    semaphore_destroy(mach_task_self(), *(s))
      40             : pthread_mutex_t semcount_mutex;
      41             : #endif
      42             : 
      43          12 : JSemaphore::JSemaphore() {
      44          12 :         int sem_init_retval = sem_init(&m_semaphore,0,0);
      45             :         assert(sem_init_retval == 0);
      46             :         UNUSED(sem_init_retval);
      47             : #if defined(__MACH__) && defined(__APPLE__)
      48             :         semcount = 0;
      49             : #endif
      50          12 : }
      51             : 
      52          22 : JSemaphore::~JSemaphore() {
      53          11 :         int sem_destroy_retval = sem_destroy(&m_semaphore);
      54             : #ifdef __ANDROID__
      55             : // WORKAROUND for broken bionic semaphore implementation!
      56             :         assert(
      57             :                         (sem_destroy_retval == 0) ||
      58             :                         (errno == EBUSY)
      59             :                 );
      60             : #else
      61             :         assert(sem_destroy_retval == 0);
      62             : #endif
      63             :         UNUSED(sem_destroy_retval);
      64          11 : }
      65             : 
      66           0 : JSemaphore::JSemaphore(int initval) {
      67           0 :         int sem_init_retval = sem_init(&m_semaphore,0,initval);
      68             :         assert(sem_init_retval == 0);
      69             :         UNUSED(sem_init_retval);
      70           0 : }
      71             : 
      72       22801 : void JSemaphore::Post() {
      73       22801 :         int sem_post_retval = sem_post(&m_semaphore);
      74             :         assert(sem_post_retval == 0);
      75             :         UNUSED(sem_post_retval);
      76             : #if defined(__MACH__) && defined(__APPLE__)
      77             :         pthread_mutex_lock(&semcount_mutex);
      78             :         semcount++;
      79             :         pthread_mutex_unlock(&semcount_mutex);
      80             : #endif
      81       22801 : }
      82             : 
      83        7688 : void JSemaphore::Wait() {
      84        7688 :         int sem_wait_retval = sem_wait(&m_semaphore);
      85             :         assert(sem_wait_retval == 0);
      86             :         UNUSED(sem_wait_retval);
      87             : #if defined(__MACH__) && defined(__APPLE__)
      88             :         pthread_mutex_lock(&semcount_mutex);
      89             :         semcount--;
      90             :         pthread_mutex_unlock(&semcount_mutex);
      91             : #endif
      92        7686 : }
      93             : 
      94       23174 : bool JSemaphore::Wait(unsigned int time_ms) {
      95             : #if defined(__MACH__) && defined(__APPLE__)
      96             :         mach_timespec_t waittime;
      97             :         waittime.tv_sec = time_ms / 1000;
      98             :         waittime.tv_nsec = 1000000 * (time_ms % 1000);
      99             : #else
     100             :         struct timespec waittime;
     101             : #endif
     102             :         struct timeval now;
     103             : 
     104       23174 :         if (gettimeofday(&now, NULL) == -1) {
     105             :                 assert("Unable to get time by clock_gettime!" == 0);
     106           0 :                 return false;
     107             :         }
     108             : 
     109             : #if !(defined(__MACH__) && defined(__APPLE__))
     110       23174 :         waittime.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
     111       23174 :         waittime.tv_sec  = (time_ms / 1000) + (waittime.tv_nsec / (1000*1000*1000)) + now.tv_sec;
     112       23174 :         waittime.tv_nsec %= 1000*1000*1000;
     113             : #endif
     114             : 
     115       23174 :         errno = 0;
     116             : #if defined(__MACH__) && defined(__APPLE__)
     117             :         int sem_wait_retval = semaphore_timedwait(m_semaphore, waittime);
     118             :         if (sem_wait_retval == KERN_OPERATION_TIMED_OUT) {
     119             :                 errno = ETIMEDOUT;
     120             :         } else if (sem_wait_retval == KERN_ABORTED) {
     121             :                 errno = EINTR;
     122             :         } else if (sem_wait_retval != 0) {
     123             :                 errno = EINVAL;
     124             :         }
     125             : #else
     126       23174 :         int sem_wait_retval = sem_timedwait(&m_semaphore, &waittime);
     127             : #endif
     128             : 
     129       23174 :         if (sem_wait_retval == 0)
     130             :         {
     131             : #if defined(__MACH__) && defined(__APPLE__)
     132             :                 pthread_mutex_lock(&semcount_mutex);
     133             :                 semcount--;
     134             :                 pthread_mutex_unlock(&semcount_mutex);
     135             : #endif
     136       14821 :                 return true;
     137             :         }
     138             :         else {
     139             :                 assert((errno == ETIMEDOUT) || (errno == EINTR));
     140        8353 :                 return false;
     141             :         }
     142             :         return sem_wait_retval == 0 ? true : false;
     143             : }
     144             : 
     145        5542 : int JSemaphore::GetValue() {
     146        5542 :         int retval = 0;
     147             : #if defined(__MACH__) && defined(__APPLE__)
     148             :         pthread_mutex_lock(&semcount_mutex);
     149             :         retval = semcount;
     150             :         pthread_mutex_unlock(&semcount_mutex);
     151             : #else
     152        5542 :         sem_getvalue(&m_semaphore, &retval);
     153             : #endif
     154        5542 :         return retval;
     155             : }
     156             : 

Generated by: LCOV version 1.11