summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/semtrywait.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-12 08:09:16 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-05 14:29:01 +0200
commitc090db7405b72ce6d0b726c0a39fb1c1aebab7ea (patch)
tree099a887f445115e9b40d25cd6a2b2b11908d347d /cpukit/posix/src/semtrywait.c
parentposix: Optimize pthread_once_t (diff)
downloadrtems-c090db7405b72ce6d0b726c0a39fb1c1aebab7ea.tar.bz2
posix: Implement self-contained POSIX semaphores
For semaphore object pointer and object validation see POSIX_SEMAPHORE_VALIDATE_OBJECT(). Destruction or close of a busy semaphore returns an error status. The object is not flushed. POSIX semaphores are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3116.
Diffstat (limited to 'cpukit/posix/src/semtrywait.c')
-rw-r--r--cpukit/posix/src/semtrywait.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/cpukit/posix/src/semtrywait.c b/cpukit/posix/src/semtrywait.c
index a6836d8eaf..673343d4b4 100644
--- a/cpukit/posix/src/semtrywait.c
+++ b/cpukit/posix/src/semtrywait.c
@@ -18,21 +18,29 @@
#include "config.h"
#endif
-#include <stdarg.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <limits.h>
-
-#include <rtems/system.h>
#include <rtems/posix/semaphoreimpl.h>
-#include <rtems/seterr.h>
-int sem_trywait(
- sem_t *sem
-)
+int sem_trywait( sem_t *_sem )
{
- return _POSIX_Semaphore_Wait_support(sem, false, WATCHDOG_NO_TIMEOUT);
+ Sem_Control *sem;
+ Thread_queue_Context queue_context;
+ ISR_Level level;
+ unsigned int count;
+
+ POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
+
+ sem = _Sem_Get( &_sem->_Semaphore );
+ _Thread_queue_Context_initialize( &queue_context );
+ _Thread_queue_Context_ISR_disable( &queue_context, level );
+ _Sem_Queue_acquire_critical( sem, &queue_context );
+
+ count = sem->count;
+ if ( __predict_true( count > 0 ) ) {
+ sem->count = count - 1;
+ _Sem_Queue_release( sem, level, &queue_context );
+ return 0;
+ } else {
+ _Sem_Queue_release( sem, level, &queue_context );
+ rtems_set_errno_and_return_minus_one( EAGAIN );
+ }
}