source: rtems/cpukit/posix/src/semtimedwait.c @ c090db7

5
Last change on this file since c090db7 was c090db7, checked in by Sebastian Huber <sebastian.huber@…>, on 09/12/17 at 06:09:16

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.

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Lock a Semaphore
5 * @ingroup POSIX_SEMAPHORE POSIX Semaphores Support
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/posix/semaphoreimpl.h>
22#include <rtems/score/todimpl.h>
23
24/*
25 *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
26 *
27 *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
28 */
29
30int sem_timedwait(
31  sem_t                 *__restrict _sem,
32  const struct timespec *__restrict abstime
33)
34{
35  Sem_Control          *sem;
36  Thread_queue_Context  queue_context;
37  ISR_Level             level;
38  Thread_Control       *executing;
39  unsigned int          count;
40
41  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
42
43  sem = _Sem_Get( &_sem->_Semaphore );
44  _Thread_queue_Context_initialize( &queue_context );
45  _Thread_queue_Context_ISR_disable( &queue_context, level );
46  executing = _Sem_Queue_acquire_critical( sem, &queue_context );
47
48  count = sem->count;
49  if ( __predict_true( count > 0 ) ) {
50    sem->count = count - 1;
51    _Sem_Queue_release( sem, level, &queue_context );
52    return 0;
53  } else {
54    Watchdog_Interval ticks;
55    Status_Control    status;
56
57    switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
58      case TOD_ABSOLUTE_TIMEOUT_INVALID:
59        _Sem_Queue_release( sem, level, &queue_context );
60        rtems_set_errno_and_return_minus_one( EINVAL );
61        break;
62      case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
63      case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
64        _Sem_Queue_release( sem, level, &queue_context );
65        rtems_set_errno_and_return_minus_one( ETIMEDOUT );
66        break;
67      default:
68        break;
69    }
70
71    _Thread_queue_Context_set_thread_state(
72      &queue_context,
73      STATES_WAITING_FOR_SEMAPHORE
74    );
75    _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context );
76    _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
77    _Thread_queue_Context_set_ISR_level( &queue_context, level );
78    _Thread_queue_Enqueue(
79      &sem->Queue.Queue,
80      SEMAPHORE_TQ_OPERATIONS,
81      executing,
82      &queue_context
83    );
84    status = _Thread_Wait_get_status( executing );
85    return _POSIX_Zero_or_minus_one_plus_errno( status );
86  }
87}
Note: See TracBrowser for help on using the repository browser.