Optimize semaphore wait with zero timeout on POSIX
authorsfan5 <sfan5@live.de>
Thu, 14 Nov 2019 16:58:07 +0000 (17:58 +0100)
committersfan5 <sfan5@live.de>
Thu, 14 Nov 2019 19:20:14 +0000 (20:20 +0100)
src/threading/semaphore.cpp

index 77ceff509cb9c3172c8acab6c23891b0bf676798..ce22dcd05d46eeb95cdde7b5c70c09956c32426e 100644 (file)
@@ -140,22 +140,27 @@ bool Semaphore::wait(unsigned int time_ms)
                        errno = EINVAL;
        }
 # else
-       struct timespec wait_time;
-       struct timeval now;
+       int ret;
+       if (time_ms > 0) {
+               struct timespec wait_time;
+               struct timeval now;
 
-       if (gettimeofday(&now, NULL) == -1) {
-               std::cerr << "Semaphore::wait(ms): Unable to get time with gettimeofday!" << std::endl;
-               abort();
-       }
+               if (gettimeofday(&now, NULL) == -1) {
+                       std::cerr << "Semaphore::wait(ms): Unable to get time with gettimeofday!" << std::endl;
+                       abort();
+               }
 
-       wait_time.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
-       wait_time.tv_sec  = (time_ms / 1000) + (wait_time.tv_nsec / (1000 * 1000 * 1000)) + now.tv_sec;
-       wait_time.tv_nsec %= 1000 * 1000 * 1000;
+               wait_time.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
+               wait_time.tv_sec  = (time_ms / 1000) + (wait_time.tv_nsec / (1000 * 1000 * 1000)) + now.tv_sec;
+               wait_time.tv_nsec %= 1000 * 1000 * 1000;
 
-       int ret = sem_timedwait(&semaphore, &wait_time);
+               ret = sem_timedwait(&semaphore, &wait_time);
+       } else {
+               ret = sem_trywait(&semaphore);
+       }
 # endif
 
-       assert(!ret || (errno == ETIMEDOUT || errno == EINTR));
+       assert(!ret || (errno == ETIMEDOUT || errno == EINTR || errno == EAGAIN));
        return !ret;
 #endif
 }