inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time) { #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS timespec tspec = detail::ptime_to_timespec(abs_time); for (;;){ int res = sem_timedwait(handle, &tspec); if(res == 0) return true; if (res > 0){ //buggy glibc, copy the returned error code to errno errno = res; } if(system_error_code() == ETIMEDOUT){ return false; } throw interprocess_exception(system_error_code()); } return false; #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS boost::posix_time::ptime now; while((now = microsec_clock::universal_time()) < abs_time){ if(semaphore_try_wait(handle)) return true; thread_yield(); } return false; #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS }
DECLARE_TEST( semaphore, initialize ) { semaphore_t sem; semaphore_initialize( &sem, 0 ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 1 ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 2 ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); return 0; }
DECLARE_TEST( semaphore, postwait ) { semaphore_t sem; tick_t start, end; semaphore_initialize( &sem, 0 ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_post( &sem ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_post( &sem ); semaphore_post( &sem ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); start = time_current(); semaphore_try_wait( &sem, 0 ); end = time_current(); EXPECT_LT( end - start, time_ticks_per_second() / 1000 ); start = time_current(); semaphore_try_wait( &sem, 500 ); end = time_current(); EXPECT_GE( end - start, time_ticks_per_second() / 2 ); semaphore_destroy( &sem ); return 0; }
bool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data) { assert(queue != NULL); assert(data != NULL); if (!semaphore_try_wait(queue->enqueue_sem)) return false; pthread_mutex_lock(&queue->lock); list_append(queue->list, data); pthread_mutex_unlock(&queue->lock); semaphore_post(queue->dequeue_sem); return true; }
DECLARE_TEST( semaphore, threaded ) { object_t thread[32]; int ith; int failed_waits; semaphore_test_t test; semaphore_initialize( &test.read, 0 ); semaphore_initialize( &test.write, 0 ); test.loopcount = 128; test.counter = 0; for( ith = 0; ith < 32; ++ith ) { thread[ith] = thread_create( semaphore_waiter, "semaphore_waiter", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread[ith], &test ); } test_wait_for_threads_startup( thread, 32 ); failed_waits = 0; for( ith = 0; ith < test.loopcount * 32; ++ith ) { semaphore_post( &test.read ); thread_yield(); if( !semaphore_try_wait( &test.write, 200 ) ) { failed_waits++; EXPECT_TRUE( semaphore_wait( &test.write ) ); } } for( ith = 0; ith < 32; ++ith ) { thread_terminate( thread[ith] ); thread_destroy( thread[ith] ); thread_yield(); } test_wait_for_threads_exit( thread, 32 ); EXPECT_EQ( test.counter, test.loopcount * 32 ); EXPECT_EQ( failed_waits, 0 ); semaphore_destroy( &test.read ); semaphore_destroy( &test.write ); return 0; }
void *fixed_queue_try_dequeue(fixed_queue_t *queue) { assert(queue != NULL); if (!semaphore_try_wait(queue->dequeue_sem)) return NULL; pthread_mutex_lock(&queue->lock); void *ret = list_front(queue->list); list_remove(queue->list, ret); pthread_mutex_unlock(&queue->lock); semaphore_post(queue->enqueue_sem); return ret; }
bool lua_acquire_execution_right(lua_t* env, bool force) { uint64_t self = thread_id(); if (atomic_load64(&env->executing_thread) == self) { ++env->executing_count; return true; } if (force) { semaphore_wait(&env->execution_right); atomic_store64(&env->executing_thread, self); FOUNDATION_ASSERT(env->executing_count == 0); ++env->executing_count; return true; } if (semaphore_try_wait(&env->execution_right, 0)) { atomic_store64(&env->executing_thread, self); FOUNDATION_ASSERT(env->executing_count == 0); ++env->executing_count; return true; } return false; }
bool try_wait() { return semaphore_try_wait(&m_sem); }
bool try_wait() { return semaphore_try_wait(m_handle); }