Changeset c3105894 in rtems


Ignore:
Timestamp:
Oct 19, 2017, 11:47:57 AM (17 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
4c70110
Parents:
1666ffe5
git-author:
Sebastian Huber <sebastian.huber@…> (10/19/17 11:47:57)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/24/17 08:19:05)
Message:

score: Move thread queue timeout handling

Update #3117.
Update #3182.

Files:
1 added
1 deleted
48 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libnetworking/rtems/rtems_glue.c

    r1666ffe5 rc3105894  
    377377        _Thread_queue_Context_initialize(&queue_context);
    378378        _ISR_lock_ISR_disable(&queue_context.Lock_context.Lock_context);
    379         _Thread_queue_Context_set_no_timeout( &queue_context );
     379        _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    380380        status = _CORE_recursive_mutex_Seize (
    381381                &the_networkSemaphore->Core_control.Mutex.Recursive,
  • cpukit/posix/include/rtems/posix/mqueueimpl.h

    r1666ffe5 rc3105894  
    2323#include <rtems/posix/posixapi.h>
    2424#include <rtems/score/coremsgimpl.h>
     25#include <rtems/score/threadqimpl.h>
    2526
    2627#include <rtems/seterr.h>
     
    6465 */
    6566ssize_t _POSIX_Message_queue_Receive_support(
    66   mqd_t               mqdes,
    67   char               *msg_ptr,
    68   size_t              msg_len,
    69   unsigned int       *msg_prio,
    70   bool                wait,
    71   Watchdog_Interval   timeout
     67  mqd_t                         mqdes,
     68  char                         *msg_ptr,
     69  size_t                        msg_len,
     70  unsigned int                 *msg_prio,
     71  const struct timespec        *abstime,
     72  Thread_queue_Enqueue_callout  enqueue_callout
    7273);
    7374
     
    7879 */
    7980int _POSIX_Message_queue_Send_support(
    80   mqd_t               mqdes,
    81   const char         *msg_ptr,
    82   size_t              msg_len,
    83   unsigned int        msg_prio,
    84   bool                wait,
    85   Watchdog_Interval   timeout
     81  mqd_t                         mqdes,
     82  const char                   *msg_ptr,
     83  size_t                        msg_len,
     84  unsigned int                  msg_prio,
     85  const struct timespec        *abstime,
     86  Thread_queue_Enqueue_callout  enqueue_callout
    8687);
    8788
  • cpukit/posix/include/rtems/posix/muteximpl.h

    r1666ffe5 rc3105894  
    133133  const Thread_queue_Operations *operations,
    134134  Thread_Control                *executing,
    135   bool                           wait,
     135  const struct timespec         *abstime,
    136136  Thread_queue_Context          *queue_context
    137137);
     
    172172  const Thread_queue_Operations *operations,
    173173  Thread_Control                *executing,
    174   bool                           wait,
     174  const struct timespec         *abstime,
    175175  Thread_queue_Context          *queue_context
    176176)
     
    199199    operations,
    200200    executing,
    201     wait,
     201    abstime,
    202202    queue_context
    203203  );
     
    330330
    331331RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize(
    332   POSIX_Mutex_Control  *the_mutex,
    333   unsigned long         flags,
    334   Thread_Control       *executing,
    335   bool                  wait,
    336   Thread_queue_Context *queue_context
     332  POSIX_Mutex_Control   *the_mutex,
     333  unsigned long          flags,
     334  Thread_Control        *executing,
     335  const struct timespec *abstime,
     336  Thread_queue_Context  *queue_context
    337337)
    338338{
     
    372372    POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS,
    373373    executing,
    374     wait,
     374    abstime,
    375375    queue_context
    376376  );
     
    445445}
    446446
    447 /**
    448  *  @brief POSIX Mutex Lock Support Method
    449  *
    450  *  A support routine which implements guts of the blocking, non-blocking, and
    451  *  timed wait version of mutex lock.
    452  */
     447#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1)
     448
    453449int _POSIX_Mutex_Lock_support(
    454   pthread_mutex_t           *mutex,
    455   bool                       blocking,
    456   Watchdog_Interval          timeout
     450  pthread_mutex_t              *mutex,
     451  const struct timespec        *abstime,
     452  Thread_queue_Enqueue_callout  enqueue_callout
    457453);
    458454
  • cpukit/posix/src/condwaitsupp.c

    r1666ffe5 rc3105894  
    2626#include <rtems/score/threaddispatch.h>
    2727
    28 static void _POSIX_Condition_variables_Enqueue_callout(
     28static void _POSIX_Condition_variables_Mutex_unlock(
    2929  Thread_queue_Queue   *queue,
    3030  Thread_Control       *the_thread,
     
    4545     */
    4646    _Assert( mutex_error == EINVAL || mutex_error == EPERM );
    47     _Thread_queue_Extract( the_thread );
    48     the_thread->Wait.return_code= STATUS_NOT_OWNER;
     47    _Thread_Continue( the_thread, STATUS_NOT_OWNER );
    4948  }
     49}
     50
     51static void _POSIX_Condition_variables_Enqueue_no_timeout(
     52  Thread_queue_Queue   *queue,
     53  Thread_Control       *the_thread,
     54  Per_CPU_Control      *cpu_self,
     55  Thread_queue_Context *queue_context
     56)
     57{
     58  _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
     59}
     60
     61static void _POSIX_Condition_variables_Enqueue_with_timeout_monotonic(
     62  Thread_queue_Queue   *queue,
     63  Thread_Control       *the_thread,
     64  Per_CPU_Control      *cpu_self,
     65  Thread_queue_Context *queue_context
     66)
     67{
     68  _Thread_queue_Add_timeout_monotonic_timespec(
     69    queue,
     70    the_thread,
     71    cpu_self,
     72    queue_context
     73  );
     74  _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
     75}
     76
     77static void _POSIX_Condition_variables_Enqueue_with_timeout_realtime(
     78  Thread_queue_Queue   *queue,
     79  Thread_Control       *the_thread,
     80  Per_CPU_Control      *cpu_self,
     81  Thread_queue_Context *queue_context
     82)
     83{
     84  _Thread_queue_Add_timeout_realtime_timespec(
     85    queue,
     86    the_thread,
     87    cpu_self,
     88    queue_context
     89  );
     90  _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
    5091}
    5192
     
    60101  Thread_queue_Context               queue_context;
    61102  int                                error;
    62   int                                mutex_error;
    63103  Thread_Control                    *executing;
    64   Watchdog_Interval                  timeout;
    65   bool                               already_timedout;
    66   TOD_Absolute_timeout_conversion_results  status;
    67104
    68105  the_cond = _POSIX_Condition_variables_Get( cond );
     
    70107
    71108  _Thread_queue_Context_initialize( &queue_context );
    72   already_timedout = false;
    73109
    74110  if ( abstime != NULL ) {
    75     /*
    76      *  POSIX requires that blocking calls with timeouts that take
    77      *  an absolute timeout must ignore issues with the absolute
    78      *  time provided if the operation would otherwise succeed.
    79      *  So we check the abstime provided, and hold on to whether it
    80      *  is valid or not.  If it isn't correct and in the future,
    81      *  then we do a polling operation and convert the UNSATISFIED
    82      *  status into the appropriate error.
    83      */
    84     status = _TOD_Absolute_timeout_to_ticks(
    85       abstime,
    86       _POSIX_Condition_variables_Get_clock( flags ),
    87       &timeout
    88     );
    89     if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
    90       return EINVAL;
     111    _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
    91112
    92     if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
    93         status == TOD_ABSOLUTE_TIMEOUT_IS_NOW ) {
    94       already_timedout = true;
     113    if ( _POSIX_Condition_variables_Get_clock( flags ) == CLOCK_MONOTONIC ) {
     114      _Thread_queue_Context_set_enqueue_callout(
     115        &queue_context,
     116        _POSIX_Condition_variables_Enqueue_with_timeout_monotonic
     117      );
    95118    } else {
    96       _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
     119      _Thread_queue_Context_set_enqueue_callout(
     120        &queue_context,
     121        _POSIX_Condition_variables_Enqueue_with_timeout_realtime
     122      );
    97123    }
    98124  } else {
    99     _Thread_queue_Context_set_no_timeout( &queue_context );
     125    _Thread_queue_Context_set_enqueue_callout(
     126      &queue_context,
     127      _POSIX_Condition_variables_Enqueue_no_timeout
     128    );
    100129  }
    101130
     
    112141  the_cond->mutex = mutex;
    113142
    114   if ( !already_timedout ) {
    115     _Thread_queue_Context_set_thread_state(
    116       &queue_context,
    117       STATES_WAITING_FOR_CONDITION_VARIABLE
    118     );
    119     _Thread_queue_Context_set_enqueue_callout(
    120       &queue_context,
    121       _POSIX_Condition_variables_Enqueue_callout
    122     );
    123     _Thread_queue_Enqueue(
    124       &the_cond->Queue.Queue,
    125       POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
    126       executing,
    127       &queue_context
    128     );
    129     error = _POSIX_Get_error_after_wait( executing );
    130   } else {
    131     _POSIX_Condition_variables_Release( the_cond, &queue_context );
    132 
    133     mutex_error = pthread_mutex_unlock( the_cond->mutex );
    134     if ( mutex_error != 0 ) {
    135       error = EPERM;
    136     } else {
    137       error = ETIMEDOUT;
    138     }
    139   }
     143  _Thread_queue_Context_set_thread_state(
     144    &queue_context,
     145    STATES_WAITING_FOR_CONDITION_VARIABLE
     146  );
     147  _Thread_queue_Enqueue(
     148    &the_cond->Queue.Queue,
     149    POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
     150    executing,
     151    &queue_context
     152  );
     153  error = _POSIX_Get_error_after_wait( executing );
    140154
    141155  /*
     
    156170
    157171  if ( error != EPERM ) {
     172    int mutex_error;
     173
    158174    mutex_error = pthread_mutex_lock( mutex );
    159175    if ( mutex_error != 0 ) {
  • cpukit/posix/src/mqueuereceive.c

    r1666ffe5 rc3105894  
    1919#endif
    2020
    21 #include <stdarg.h>
    22 
    23 #include <pthread.h>
    24 #include <limits.h>
    25 #include <errno.h>
    26 #include <fcntl.h>
    27 #include <mqueue.h>
    28 
    29 #include <rtems/system.h>
    30 #include <rtems/score/watchdog.h>
    31 #include <rtems/seterr.h>
    3221#include <rtems/posix/mqueueimpl.h>
    3322
     
    4433    msg_len,
    4534    msg_prio,
    46     true,
    47     WATCHDOG_NO_TIMEOUT
     35    NULL,
     36    _Thread_queue_Enqueue_do_nothing_extra
    4837  );
    4938}
  • cpukit/posix/src/mqueuerecvsupp.c

    r1666ffe5 rc3105894  
    3737
    3838ssize_t _POSIX_Message_queue_Receive_support(
    39   mqd_t               mqdes,
    40   char               *msg_ptr,
    41   size_t              msg_len,
    42   unsigned int       *msg_prio,
    43   bool                wait,
    44   Watchdog_Interval   timeout
     39  mqd_t                         mqdes,
     40  char                         *msg_ptr,
     41  size_t                        msg_len,
     42  unsigned int                 *msg_prio,
     43  const struct timespec        *abstime,
     44  Thread_queue_Enqueue_callout  enqueue_callout
    4545)
    4646{
     
    4848  Thread_queue_Context         queue_context;
    4949  size_t                       length_out;
    50   bool                         do_wait;
    5150  Thread_Control              *executing;
    5251  Status_Control               status;
     
    6867  }
    6968
     69  _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout );
     70  _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
     71
    7072  /*
    7173   *  Now if something goes wrong, we return a "length" of -1
    7274   *  to indicate an error.
    7375   */
    74 
    7576  length_out = -1;
    76 
    77   /*
    78    *  A timed receive with a bad time will do a poll regardless.
    79    */
    80   if ( wait ) {
    81     do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0;
    82   } else {
    83     do_wait = wait;
    84   }
    8577
    8678  _CORE_message_queue_Acquire_critical(
     
    9890   */
    9991  executing = _Thread_Executing;
    100   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
    10192  status = _CORE_message_queue_Seize(
    10293    &the_mq->Message_queue,
     
    10495    msg_ptr,
    10596    &length_out,
    106     do_wait,
     97    ( the_mq->oflag & O_NONBLOCK ) == 0,
    10798    &queue_context
    10899  );
  • cpukit/posix/src/mqueuesend.c

    r1666ffe5 rc3105894  
    6262    msg_len,
    6363    msg_prio,
    64     true,
    65     WATCHDOG_NO_TIMEOUT
     64    NULL,
     65    _Thread_queue_Enqueue_do_nothing_extra
    6666  );
    6767}
  • cpukit/posix/src/mqueuesendsupp.c

    r1666ffe5 rc3105894  
    3636
    3737int _POSIX_Message_queue_Send_support(
    38   mqd_t               mqdes,
    39   const char         *msg_ptr,
    40   size_t              msg_len,
    41   unsigned int        msg_prio,
    42   bool                wait,
    43   Watchdog_Interval   timeout
     38  mqd_t                         mqdes,
     39  const char                   *msg_ptr,
     40  size_t                        msg_len,
     41  unsigned int                  msg_prio,
     42  const struct timespec        *abstime,
     43  Thread_queue_Enqueue_callout  enqueue_callout
    4444)
    4545{
     
    4747  Thread_queue_Context         queue_context;
    4848  Status_Control               status;
    49   bool                         do_wait;
    5049  Thread_Control              *executing;
    5150
     
    7069  }
    7170
    72   /*
    73    *  A timed receive with a bad time will do a poll regardless.
    74    */
    75   if ( wait ) {
    76     do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0;
    77   } else {
    78     do_wait = wait;
    79   }
     71  _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout );
     72  _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
    8073
    8174  _CORE_message_queue_Acquire_critical(
     
    9386   */
    9487  executing = _Thread_Executing;
    95   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
    9688  status = _CORE_message_queue_Submit(
    9789    &the_mq->Message_queue,
     
    10092    msg_len,
    10193    _POSIX_Message_queue_Priority_to_core( msg_prio ),
    102     do_wait,
     94    ( the_mq->oflag & O_NONBLOCK ) == 0,
    10395    &queue_context
    10496  );
  • cpukit/posix/src/mqueuetimedreceive.c

    r1666ffe5 rc3105894  
    3333#endif
    3434
    35 #include <stdarg.h>
    36 
    37 #include <pthread.h>
    38 #include <limits.h>
    39 #include <errno.h>
    40 #include <fcntl.h>
    41 #include <mqueue.h>
    42 
    43 #include <rtems/system.h>
    44 #include <rtems/score/todimpl.h>
    45 #include <rtems/seterr.h>
    4635#include <rtems/posix/mqueueimpl.h>
    4736
     
    6049)
    6150{
    62   Watchdog_Interval                            ticks;
    63   bool                                         do_wait = true;
    64   TOD_Absolute_timeout_conversion_results  status;
    65 
    66   /*
    67    *  POSIX requires that blocking calls with timeouts that take
    68    *  an absolute timeout must ignore issues with the absolute
    69    *  time provided if the operation would otherwise succeed.
    70    *  So we check the abstime provided, and hold on to whether it
    71    *  is valid or not.  If it isn't correct and in the future,
    72    *  then we do a polling operation and convert the UNSATISFIED
    73    *  status into the appropriate error.
    74    *
    75    *  If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    76    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    77    *  then we should not wait.
    78    */
    79   status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    80   if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
    81     do_wait = false;
    82 
    8351  return _POSIX_Message_queue_Receive_support(
    8452    mqdes,
     
    8654    msg_len,
    8755    msg_prio,
    88     do_wait,
    89     ticks
     56    abstime,
     57    _Thread_queue_Add_timeout_realtime_timespec
    9058  );
    9159}
  • cpukit/posix/src/mqueuetimedsend.c

    r1666ffe5 rc3105894  
    1919#endif
    2020
    21 #include <stdarg.h>
    22 
    23 #include <pthread.h>
    24 #include <limits.h>
    25 #include <errno.h>
    26 #include <fcntl.h>
    27 #include <mqueue.h>
    28 
    29 #include <rtems/system.h>
    30 #include <rtems/score/todimpl.h>
    31 #include <rtems/seterr.h>
    3221#include <rtems/posix/mqueueimpl.h>
    3322
     
    4029)
    4130{
    42   Watchdog_Interval                            ticks;
    43   bool                                         do_wait = true;
    44   TOD_Absolute_timeout_conversion_results  status;
    45 
    46   /*
    47    *  POSIX requires that blocking calls with timeouts that take
    48    *  an absolute timeout must ignore issues with the absolute
    49    *  time provided if the operation would otherwise succeed.
    50    *  So we check the abstime provided, and hold on to whether it
    51    *  is valid or not.  If it isn't correct and in the future,
    52    *  then we do a polling operation and convert the UNSATISFIED
    53    *  status into the appropriate error.
    54    *
    55    *  If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    56    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    57    *  then we should not wait.
    58    */
    59   status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    60   if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
    61     do_wait = false;
    62 
    6331  return _POSIX_Message_queue_Send_support(
    6432    mqdes,
     
    6634    msg_len,
    6735    msg_prio,
    68     do_wait,
    69     ticks
     36    abstime,
     37    _Thread_queue_Add_timeout_realtime_timespec
    7038  );
    7139}
  • cpukit/posix/src/mutexlock.c

    r1666ffe5 rc3105894  
    1919#endif
    2020
    21 #include <errno.h>
    22 #include <pthread.h>
    23 
    24 #include <rtems/system.h>
    25 #include <rtems/score/coremuteximpl.h>
    26 #include <rtems/score/watchdog.h>
    2721#include <rtems/posix/muteximpl.h>
    28 #include <rtems/posix/priorityimpl.h>
    2922
    3023/*
     
    3831)
    3932{
    40   return _POSIX_Mutex_Lock_support( mutex, true, WATCHDOG_NO_TIMEOUT );
     33  return _POSIX_Mutex_Lock_support(
     34    mutex,
     35    NULL,
     36    _Thread_queue_Enqueue_do_nothing_extra
     37  );
    4138}
  • cpukit/posix/src/mutexlocksupp.c

    r1666ffe5 rc3105894  
    2626  const Thread_queue_Operations *operations,
    2727  Thread_Control                *executing,
    28   bool                           wait,
     28  const struct timespec         *abstime,
    2929  Thread_queue_Context          *queue_context
    3030)
    3131{
    32   if ( wait ) {
     32  if ( (uintptr_t) abstime != POSIX_MUTEX_ABSTIME_TRY_LOCK ) {
    3333    _Thread_queue_Context_set_thread_state(
    3434      queue_context,
    3535      STATES_WAITING_FOR_MUTEX
    3636    );
    37     _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    3837    _Thread_queue_Context_set_deadlock_callout(
    3938      queue_context,
     
    5453
    5554int _POSIX_Mutex_Lock_support(
    56   pthread_mutex_t   *mutex,
    57   bool               wait,
    58   Watchdog_Interval  timeout
     55  pthread_mutex_t              *mutex,
     56  const struct timespec        *abstime,
     57  Thread_queue_Enqueue_callout  enqueue_callout
    5958)
    6059{
     
    6968
    7069  executing = _POSIX_Mutex_Acquire( the_mutex, &queue_context );
    71   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
     70  _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout);
     71  _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
    7272
    7373  switch ( _POSIX_Mutex_Get_protocol( flags ) ) {
     
    7777        flags,
    7878        executing,
    79         wait,
     79        abstime,
    8080        &queue_context
    8181      );
     
    8787        POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
    8888        executing,
    89         wait,
     89        abstime,
    9090        &queue_context
    9191      );
     
    100100        POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS,
    101101        executing,
    102         wait,
     102        abstime,
    103103        &queue_context
    104104      );
  • cpukit/posix/src/mutextimedlock.c

    r1666ffe5 rc3105894  
    1919#endif
    2020
    21 #include <errno.h>
    22 #include <pthread.h>
    23 
    24 #include <rtems/system.h>
    25 #include <rtems/score/coremuteximpl.h>
    26 #include <rtems/score/todimpl.h>
    2721#include <rtems/posix/muteximpl.h>
    28 #include <rtems/posix/priorityimpl.h>
    2922
    3023/**
     
    3831)
    3932{
    40   Watchdog_Interval                            ticks;
    41   bool                                         do_wait = true;
    42   TOD_Absolute_timeout_conversion_results  status;
    43   int                                          lock_status;
    44 
    45   /*
    46    *  POSIX requires that blocking calls with timeouts that take
    47    *  an absolute timeout must ignore issues with the absolute
    48    *  time provided if the operation would otherwise succeed.
    49    *  So we check the abstime provided, and hold on to whether it
    50    *  is valid or not.  If it isn't correct and in the future,
    51    *  then we do a polling operation and convert the UNSATISFIED
    52    *  status into the appropriate error.
    53    *
    54    *  If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    55    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    56    *  then we should not wait.
    57    */
    58   status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    59   if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
    60     do_wait = false;
    61 
    62   lock_status = _POSIX_Mutex_Lock_support( mutex, do_wait, ticks );
    63   /*
    64    *  This service only gives us the option to block.  We used a polling
    65    *  attempt to lock if the abstime was not in the future.  If we did
    66    *  not obtain the mutex, then not look at the status immediately,
    67    *  make sure the right reason is returned.
    68    */
    69   if ( !do_wait && (lock_status == EBUSY) ) {
    70     if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
    71       return EINVAL;
    72     if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
    73          status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
    74       return ETIMEDOUT;
    75   }
    76 
    77   return lock_status;
     33  return _POSIX_Mutex_Lock_support(
     34    mutex,
     35    abstime,
     36    _Thread_queue_Add_timeout_realtime_timespec
     37  );
    7838}
  • cpukit/posix/src/mutextrylock.c

    r1666ffe5 rc3105894  
    1919#endif
    2020
    21 #include <errno.h>
    22 #include <pthread.h>
    23 
    24 #include <rtems/system.h>
    25 #include <rtems/score/coremuteximpl.h>
    26 #include <rtems/score/watchdog.h>
    2721#include <rtems/posix/muteximpl.h>
    28 #include <rtems/posix/priorityimpl.h>
    2922
    3023/**
     
    3730)
    3831{
    39   int r = _POSIX_Mutex_Lock_support( mutex, false, WATCHDOG_NO_TIMEOUT );
    40   if ( r == EDEADLK )
    41     r = EBUSY;
    42   return r;
     32  int eno;
     33
     34  eno = _POSIX_Mutex_Lock_support(
     35    mutex,
     36    (const struct timespec *) POSIX_MUTEX_ABSTIME_TRY_LOCK,
     37    NULL
     38  );
     39
     40  if ( eno == EDEADLK ) {
     41    eno = EBUSY;
     42  }
     43
     44  return eno;
    4345}
  • cpukit/posix/src/nanosleep.c

    r1666ffe5 rc3105894  
    2222
    2323#include <time.h>
    24 #include <errno.h>
    2524
    26 #include <rtems/seterr.h>
    2725#include <rtems/score/threadimpl.h>
    2826#include <rtems/score/threadqimpl.h>
    2927#include <rtems/score/timespec.h>
     28#include <rtems/score/todimpl.h>
    3029#include <rtems/score/watchdogimpl.h>
     30#include <rtems/posix/posixapi.h>
     31#include <rtems/seterr.h>
    3132
    3233static Thread_queue_Control _Nanosleep_Pseudo_queue =
    3334  THREAD_QUEUE_INITIALIZER( "Nanosleep" );
    34 
    35 static inline int nanosleep_helper(
    36   clockid_t             clock_id,
    37   uint64_t              ticks,
    38   struct timespec      *timeout,
    39   struct timespec      *rmtp,
    40   Watchdog_Discipline   discipline
    41 )
    42 {
    43   Thread_queue_Context queue_context;
    44   struct timespec      stop;
    45   int                  err;
    46 
    47   err = 0;
    48 
    49   _Thread_queue_Context_initialize( &queue_context );
    50   _Thread_queue_Context_set_thread_state(
    51     &queue_context,
    52     STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
    53   );
    54   _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    55 
    56   if ( discipline == WATCHDOG_ABSOLUTE ) {
    57     _Thread_queue_Context_set_absolute_timeout( &queue_context, ticks );
    58   } else {
    59     _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
    60   }
    61 
    62   /*
    63    *  Block for the desired amount of time
    64    */
    65   _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
    66   _Thread_queue_Enqueue(
    67     &_Nanosleep_Pseudo_queue.Queue,
    68     &_Thread_queue_Operations_FIFO,
    69     _Thread_Executing,
    70     &queue_context
    71   );
    72 
    73   clock_gettime( clock_id, &stop );
    74   /*
    75    * If the user wants the time remaining, do the conversion.
    76    */
    77   if ( _Timespec_Less_than( &stop, timeout ) ) {
    78     /*
    79      *  If there is time remaining, then we were interrupted by a signal.
    80      */
    81     err = EINTR;
    82     if ( rmtp != NULL ) {
    83       _Timespec_Subtract( &stop, timeout, rmtp );
    84     }
    85   } else if ( rmtp != NULL ) {
    86     /* no time remaining */
    87     _Timespec_Set_to_zero( rmtp );
    88   }
    89 
    90   return err;
    91 }
    92 
    93 /*
    94  * A nanosleep for zero time is implemented as a yield.
    95  * This behavior is also beyond the POSIX specification but is
    96  * consistent with the RTEMS API and yields desirable behavior.
    97  */
    98 static inline int nanosleep_yield( struct timespec *rmtp )
    99 {
    100   /*
    101    * It is critical to obtain the executing thread after thread dispatching is
    102    * disabled on SMP configurations.
    103    */
    104   Thread_Control  *executing;
    105   Per_CPU_Control *cpu_self;
    106 
    107   executing = _Thread_Get_executing();
    108   cpu_self = _Thread_Dispatch_disable();
    109   _Thread_Yield( executing );
    110   _Thread_Dispatch_direct( cpu_self );
    111   if ( rmtp ) {
    112     rmtp->tv_sec = 0;
    113     rmtp->tv_nsec = 0;
    114   }
    115   return 0;
    116 }
    11735
    11836/*
     
    12442)
    12543{
    126   int err;
    127   struct timespec now;
    128   uint64_t ticks;
    129   Watchdog_Interval relative_interval;
     44  int eno;
    13045
    131   /*
    132    *  Return EINVAL if the delay interval is negative.
    133    *
    134    *  NOTE:  This behavior is beyond the POSIX specification.
    135    *         FSU and GNU/Linux pthreads shares this behavior.
    136    */
    137   if ( !_Timespec_Is_valid( rqtp ) ) {
    138     rtems_set_errno_and_return_minus_one( EINVAL );
     46  eno = clock_nanosleep( CLOCK_REALTIME, 0, rqtp, rmtp );
     47
     48  if ( eno != 0 ) {
     49    rtems_set_errno_and_return_minus_one( eno );
    13950  }
    14051
    141   relative_interval = _Timespec_To_ticks( rqtp );
    142   if ( relative_interval == 0 )
    143     return nanosleep_yield( rmtp );
    144 
    145  /* CLOCK_REALTIME can be adjusted during the timeout,
    146   * so convert to an absolute timeout value and put the
    147   * thread on the WATCHDOG_ABSOLUTE threadq. */
    148   err = clock_gettime( CLOCK_REALTIME, &now );
    149   if ( err != 0 )
    150     return -1;
    151   _Timespec_Add_to( &now, rqtp );
    152   ticks = _Watchdog_Realtime_from_timespec( &now );
    153   err = nanosleep_helper( CLOCK_REALTIME,
    154       ticks,
    155       &now,
    156       rmtp,
    157       WATCHDOG_ABSOLUTE
    158   );
    159   if ( err != 0 ) {
    160     rtems_set_errno_and_return_minus_one( err );
    161   }
    162   return 0;
     52  return eno;
    16353}
    16454
     
    17363)
    17464{
    175   int err = 0;
    176   struct timespec timeout;
    177   uint64_t ticks;
    178   Watchdog_Interval relative_interval;
    179   TOD_Absolute_timeout_conversion_results status;
     65  Thread_queue_Context   queue_context;
     66  struct timespec        spare_end;
     67  const struct timespec *end;
     68  Thread_Control        *executing;
     69  int                    eno;
    18070
    181   if ( !_Timespec_Is_valid( rqtp ) )
    182     return EINVAL;
     71  if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
     72    return ENOTSUP;
     73  }
    18374
    184   /* get relative ticks of the requested timeout */
    185   if ( flags & TIMER_ABSTIME ) {
    186     /* See if absolute time already passed */
    187     status = _TOD_Absolute_timeout_to_ticks(rqtp, clock_id, &relative_interval);
    188     if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
     75  _Thread_queue_Context_initialize( &queue_context );
     76  _Thread_queue_Context_set_thread_state(
     77    &queue_context,
     78    STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
     79  );
     80
     81  if ( ( flags & TIMER_ABSTIME ) != 0 ) {
     82    end = rqtp;
     83
     84    if ( clock_id == CLOCK_REALTIME ) {
     85      _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     86        &queue_context,
     87        end
     88      );
     89    } else {
     90      _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
     91        &queue_context,
     92        end
     93      );
     94    }
     95  } else {
     96    if ( !_Watchdog_Is_valid_interval_timespec( rqtp ) ) {
    18997      return EINVAL;
    190     if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST )
    191       return 0;
    192     if ( status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
    193       return nanosleep_yield( NULL );
    194     rmtp = NULL; /* Do not touch rmtp when using absolute time */
    195     timeout.tv_sec = 0;
    196     timeout.tv_nsec = 0;
    197   } else {
    198     /* prepare to convert relative ticks to absolute timeout */
    199     err = clock_gettime( clock_id, &timeout );
    200     if ( err != 0 )
    201       return EINVAL;
    202     relative_interval = _Timespec_To_ticks( rqtp );
     98    }
     99
     100    _TOD_Get_zero_based_uptime_as_timespec( &spare_end );
     101
     102    /* In case this overflows, then the enqueue callout will reject it */
     103    _Timespec_Add_to( &spare_end, rqtp );
     104
     105    end = &spare_end;
     106    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
     107      &queue_context,
     108      end
     109    );
    203110  }
    204   if ( relative_interval == 0 )
    205     return nanosleep_yield( rmtp );
    206111
    207   _Timespec_Add_to( &timeout, rqtp );
    208   if ( clock_id == CLOCK_REALTIME ) {
    209     ticks = _Watchdog_Realtime_from_timespec( &timeout );
    210     err = nanosleep_helper(
    211         clock_id,
    212         ticks,
    213         &timeout,
    214         rmtp,
    215         WATCHDOG_ABSOLUTE
    216     );
    217   } else if ( clock_id == CLOCK_MONOTONIC ) {
    218     /* use the WATCHDOG_RELATIVE to ignore changes in wall time */
    219     err = nanosleep_helper(
    220         clock_id,
    221         relative_interval,
    222         &timeout,
    223         rmtp,
    224         WATCHDOG_RELATIVE
    225     );
    226   } else {
    227     err = ENOTSUP;
     112  _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
     113  executing = _Thread_Executing;
     114  _Thread_queue_Enqueue(
     115    &_Nanosleep_Pseudo_queue.Queue,
     116    &_Thread_queue_Operations_FIFO,
     117    executing,
     118    &queue_context
     119  );
     120  eno = _POSIX_Get_error_after_wait( executing );
     121
     122  if ( eno == ETIMEDOUT ) {
     123    eno = 0;
    228124  }
    229   return err;
     125
     126  if ( rmtp != NULL && ( flags & TIMER_ABSTIME ) == 0 ) {
     127    if ( eno == EINTR ) {
     128      struct timespec actual_end;
     129
     130      _TOD_Get_zero_based_uptime_as_timespec( &actual_end );
     131
     132      if ( _Timespec_Less_than( &actual_end, end ) ) {
     133        _Timespec_Subtract( &actual_end, end, rmtp );
     134      } else {
     135        _Timespec_Set_to_zero( rmtp );
     136      }
     137    } else {
     138      _Timespec_Set_to_zero( rmtp );
     139    }
     140  }
     141
     142  return eno;
    230143}
  • cpukit/posix/src/pbarrierwait.c

    r1666ffe5 rc3105894  
    5555    );
    5656    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    57     _Thread_queue_Context_set_no_timeout( &queue_context );
    5857    _Thread_queue_Enqueue(
    5958      &barrier->Queue.Queue,
  • cpukit/posix/src/prwlockrdlock.c

    r1666ffe5 rc3105894  
    3434
    3535  _Thread_queue_Context_initialize( &queue_context );
    36   _Thread_queue_Context_set_no_timeout( &queue_context );
     36  _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    3737  status = _CORE_RWLock_Seize_for_reading(
    3838    &the_rwlock->RWLock,
  • cpukit/posix/src/prwlocktimedrdlock.c

    r1666ffe5 rc3105894  
    2121#include <rtems/posix/rwlockimpl.h>
    2222#include <rtems/posix/posixapi.h>
    23 #include <rtems/score/todimpl.h>
    2423
    2524int pthread_rwlock_timedrdlock(
     
    2827)
    2928{
    30   POSIX_RWLock_Control                    *the_rwlock;
    31   Thread_queue_Context                     queue_context;
    32   Watchdog_Interval                        ticks;
    33   bool                                     do_wait;
    34   TOD_Absolute_timeout_conversion_results  timeout_status;
    35   Status_Control                           status;
    36 
    37   /*
    38    *  POSIX requires that blocking calls with timeouts that take
    39    *  an absolute timeout must ignore issues with the absolute
    40    *  time provided if the operation would otherwise succeed.
    41    *  So we check the abstime provided, and hold on to whether it
    42    *  is valid or not.  If it isn't correct and in the future,
    43    *  then we do a polling operation and convert the STATUS_UNAVAILABLE
    44    *  status into the appropriate error.
    45    *
    46    *  If the timeout status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    47    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    48    *  then we should not wait.
    49    */
    50   timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    51   do_wait = ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
     29  POSIX_RWLock_Control *the_rwlock;
     30  Thread_queue_Context  queue_context;
     31  Status_Control        status;
    5232
    5333  the_rwlock = _POSIX_RWLock_Get( rwlock );
     
    5535
    5636  _Thread_queue_Context_initialize( &queue_context );
    57   _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     37  _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     38    &queue_context,
     39    abstime
     40  );
    5841  status = _CORE_RWLock_Seize_for_reading(
    5942    &the_rwlock->RWLock,
    60     do_wait,
     43    true,
    6144    &queue_context
    6245  );
    63 
    64   if ( !do_wait && status == STATUS_UNAVAILABLE ) {
    65     if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
    66       return EINVAL;
    67     }
    68 
    69     if (
    70       timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
    71         || timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
    72     ) {
    73       return ETIMEDOUT;
    74     }
    75   }
    76 
    7746  return _POSIX_Get_error( status );
    7847}
  • cpukit/posix/src/prwlocktimedwrlock.c

    r1666ffe5 rc3105894  
    2323#include <rtems/posix/rwlockimpl.h>
    2424#include <rtems/posix/posixapi.h>
    25 #include <rtems/score/todimpl.h>
    2625
    2726int pthread_rwlock_timedwrlock(
     
    3029)
    3130{
    32   POSIX_RWLock_Control                    *the_rwlock;
    33   Thread_queue_Context                     queue_context;
    34   Watchdog_Interval                        ticks;
    35   bool                                     do_wait;
    36   TOD_Absolute_timeout_conversion_results  timeout_status;
    37   Status_Control                           status;
    38 
    39   /*
    40    *  POSIX requires that blocking calls with timeouts that take
    41    *  an absolute timeout must ignore issues with the absolute
    42    *  time provided if the operation would otherwise succeed.
    43    *  So we check the abstime provided, and hold on to whether it
    44    *  is valid or not.  If it isn't correct and in the future,
    45    *  then we do a polling operation and convert the STATUS_UNAVAILABLE
    46    *  status into the appropriate error.
    47    *
    48    *  If the timeout status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    49    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    50    *  then we should not wait.
    51    */
    52   timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    53   do_wait = ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
     31  POSIX_RWLock_Control *the_rwlock;
     32  Thread_queue_Context  queue_context;
     33  Status_Control        status;
    5434
    5535  the_rwlock = _POSIX_RWLock_Get( rwlock );
     
    5737
    5838  _Thread_queue_Context_initialize( &queue_context );
    59   _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     39  _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     40    &queue_context,
     41    abstime
     42  );
    6043  status = _CORE_RWLock_Seize_for_writing(
    6144    &the_rwlock->RWLock,
    62     do_wait,
     45    true,
    6346    &queue_context
    6447  );
    65 
    66   if ( !do_wait && status == STATUS_UNAVAILABLE ) {
    67     if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
    68       return EINVAL;
    69     }
    70 
    71     if (
    72       timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
    73         || timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
    74     ) {
    75       return ETIMEDOUT;
    76     }
    77   }
    78 
    7948  return _POSIX_Get_error( status );
    8049}
  • cpukit/posix/src/prwlockwrlock.c

    r1666ffe5 rc3105894  
    3636
    3737  _Thread_queue_Context_initialize( &queue_context );
    38   _Thread_queue_Context_set_no_timeout( &queue_context );
     38  _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    3939  status = _CORE_RWLock_Seize_for_writing(
    4040    &the_rwlock->RWLock,
  • cpukit/posix/src/pthreadjoin.c

    r1666ffe5 rc3105894  
    4141  _Thread_queue_Context_initialize( &queue_context );
    4242  _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    43   _Thread_queue_Context_set_no_timeout( &queue_context );
    4443  the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );
    4544
  • cpukit/posix/src/semtimedwait.c

    r1666ffe5 rc3105894  
    5252    return 0;
    5353  } 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     }
     54    Status_Control status;
    7055
    7156    _Thread_queue_Context_set_thread_state(
     
    7358      STATES_WAITING_FOR_SEMAPHORE
    7459    );
    75     _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    76     _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     60    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     61      &queue_context,
     62      abstime
     63    );
    7764    _Thread_queue_Context_set_ISR_level( &queue_context, level );
    7865    _Thread_queue_Enqueue(
  • cpukit/posix/src/sigtimedwait.c

    r1666ffe5 rc3105894  
    2525#include <rtems/posix/posixapi.h>
    2626#include <rtems/score/threadqimpl.h>
     27#include <rtems/score/todimpl.h>
     28#include <rtems/score/watchdogimpl.h>
    2729#include <rtems/score/isr.h>
    2830
     
    9092   */
    9193
    92   if ( timeout ) {
    93     Watchdog_Interval interval;
    94 
    95     if ( !_Timespec_Is_valid( timeout ) )
    96       rtems_set_errno_and_return_minus_one( EINVAL );
    97 
    98     interval = _Timespec_To_ticks( timeout );
    99 
    100     if ( !interval )
    101       rtems_set_errno_and_return_minus_one( EINVAL );
    102 
    103     _Thread_queue_Context_set_relative_timeout( &queue_context, interval );
     94  if ( timeout != NULL ) {
     95    struct timespec end;
     96
     97    if ( !_Watchdog_Is_valid_interval_timespec( timeout ) ) {
     98      return EINVAL;
     99    }
     100
     101    _TOD_Get_zero_based_uptime_as_timespec( &end );
     102
     103    /* In case this overflows, then the enqueue callout will reject it */
     104    _Timespec_Add_to( &end, timeout );
     105
     106    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
     107      &queue_context,
     108      &end
     109    );
    104110  } else {
    105     _Thread_queue_Context_set_no_timeout( &queue_context );
     111    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    106112  }
    107113
     
    161167    STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL
    162168  );
    163   _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    164169  _Thread_queue_Enqueue(
    165170    &_POSIX_signals_Wait_queue.Queue,
  • cpukit/rtems/src/barrierwait.c

    r1666ffe5 rc3105894  
    3939  }
    4040
    41   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
     41  _Thread_queue_Context_set_enqueue_timeout_ticks( &queue_context, timeout );
    4242  status = _CORE_barrier_Seize(
    4343    &the_barrier->Barrier,
  • cpukit/rtems/src/msgqreceive.c

    r1666ffe5 rc3105894  
    6262
    6363  executing = _Thread_Executing;
    64   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
     64  _Thread_queue_Context_set_enqueue_timeout_ticks( &queue_context, timeout );
    6565  status = _CORE_message_queue_Seize(
    6666    &the_message_queue->message_queue,
  • cpukit/rtems/src/regiongetsegment.c

    r1666ffe5 rc3105894  
    2828  Thread_queue_Queue   *queue,
    2929  Thread_Control       *the_thread,
     30  Per_CPU_Control      *cpu_self,
    3031  Thread_queue_Context *queue_context
    3132)
    3233{
    3334  Region_Control *the_region;
     35
     36  _Thread_queue_Add_timeout_ticks(
     37    queue,
     38    the_thread,
     39    cpu_self,
     40    queue_context
     41  );
    3442
    3543  the_region = REGION_OF_THREAD_QUEUE_QUEUE( queue );
     
    92100        STATES_WAITING_FOR_SEGMENT
    93101      );
     102      _Thread_queue_Context_set_timeout_ticks( &queue_context, timeout );
    94103      _Thread_queue_Context_set_enqueue_callout(
    95104        &queue_context,
    96105        _Region_Enqueue_callout
    97106      );
    98       _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
    99107      _Thread_queue_Enqueue(
    100108        &the_region->Wait_queue.Queue,
  • cpukit/rtems/src/semobtain.c

    r1666ffe5 rc3105894  
    7070  wait = !_Options_Is_no_wait( option_set );
    7171
    72   _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
     72  if ( wait ) {
     73    _Thread_queue_Context_set_enqueue_timeout_ticks( &queue_context, timeout );
     74  } else {
     75    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
     76  }
    7377
    7478  switch ( the_semaphore->variant ) {
  • cpukit/score/Makefile.am

    r1666ffe5 rc3105894  
    306306    src/threadqflush.c
    307307libscore_a_SOURCES += src/threadqops.c
     308libscore_a_SOURCES += src/threadqtimeout.c
    308309
    309310## TIMESPEC_C_FILES
     
    317318    src/coretodtickspersec.c \
    318319    src/coretodadjust.c
    319 libscore_a_SOURCES += src/coretodabsolutetimeout.c
    320320
    321321## WATCHDOG_C_FILES
  • cpukit/score/include/rtems/score/coresemimpl.h

    r1666ffe5 rc3105894  
    189189    STATES_WAITING_FOR_SEMAPHORE
    190190  );
    191   _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    192191  _Thread_queue_Enqueue(
    193192    &the_semaphore->Wait_queue.Queue,
  • cpukit/score/include/rtems/score/threadq.h

    r1666ffe5 rc3105894  
    5858 * @param[in] queue The actual thread queue.
    5959 * @param[in] the_thread The thread to enqueue.
     60 * @param[in] cpu_self The current processor.
    6061 * @param[in] queue_context The thread queue context of the lock acquire.
    6162 *
     
    6364 */
    6465typedef void ( *Thread_queue_Enqueue_callout )(
    65   Thread_queue_Queue   *queue,
    66   Thread_Control       *the_thread,
    67   Thread_queue_Context *queue_context
     66  Thread_queue_Queue     *queue,
     67  Thread_Control         *the_thread,
     68  struct Per_CPU_Control *cpu_self,
     69  Thread_queue_Context   *queue_context
    6870);
    6971
     
    203205   *
    204206   * The callout is invoked after the release of the thread queue lock with
    205    * thread dispatching disabled.  Afterwards the thread is blocked.
     207   * thread dispatching disabled.  Afterwards the thread is blocked.  This
     208   * callout must be used to install the thread watchdog for timeout handling.
    206209   *
    207210   * @see _Thread_queue_Enqueue_do_nothing_extra().
     211   *   _Thread_queue_Add_timeout_ticks(), and
     212   *   _Thread_queue_Add_timeout_realtime_timespec().
    208213   */
    209214  Thread_queue_Enqueue_callout enqueue_callout;
    210215
    211216  /**
    212    * @brief The clock discipline for the interval timeout.
    213    * Use WATCHDOG_NO_TIMEOUT to block indefinitely.
    214    */
    215   Watchdog_Discipline timeout_discipline;
    216 
    217   /**
    218217   * @brief Interval to wait.
    219    */
    220   uint64_t timeout;
     218   *
     219   * May be used by the enqueue callout to register a timeout handler.
     220   */
     221  union {
     222    /**
     223     * @brief The timeout in ticks.
     224     */
     225    Watchdog_Interval ticks;
     226
     227    /**
     228     * @brief The timeout argument, e.g. pointer to struct timespec.
     229     */
     230    const void *arg;
     231  } Timeout;
    221232
    222233#if defined(RTEMS_SMP)
  • cpukit/score/include/rtems/score/threadqimpl.h

    r1666ffe5 rc3105894  
    6666  Thread_queue_Queue   *queue,
    6767  Thread_Control       *the_thread,
     68  Per_CPU_Control      *cpu_self,
     69  Thread_queue_Context *queue_context
     70);
     71
     72void _Thread_queue_Add_timeout_ticks(
     73  Thread_queue_Queue   *queue,
     74  Thread_Control       *the_thread,
     75  Per_CPU_Control      *cpu_self,
     76  Thread_queue_Context *queue_context
     77);
     78
     79void _Thread_queue_Add_timeout_monotonic_timespec(
     80  Thread_queue_Queue   *queue,
     81  Thread_Control       *the_thread,
     82  Per_CPU_Control      *cpu_self,
     83  Thread_queue_Context *queue_context
     84);
     85
     86void _Thread_queue_Add_timeout_realtime_timespec(
     87  Thread_queue_Queue   *queue,
     88  Thread_Control       *the_thread,
     89  Per_CPU_Control      *cpu_self,
    6890  Thread_queue_Context *queue_context
    6991);
     
    119141
    120142/**
     143 * @brief Sets the timeout ticks in the thread queue context.
     144 *
     145 * @param queue_context The thread queue context.
     146 * @param ticks The timeout in ticks.
     147 *
     148 * @see _Thread_queue_Enqueue().
     149 */
     150RTEMS_INLINE_ROUTINE void
     151_Thread_queue_Context_set_timeout_ticks(
     152  Thread_queue_Context *queue_context,
     153  Watchdog_Interval     ticks
     154)
     155{
     156  queue_context->Timeout.ticks = ticks;
     157}
     158
     159/**
     160 * @brief Sets the timeout argument in the thread queue context.
     161 *
     162 * @param queue_context The thread queue context.
     163 * @param arg The timeout argument.
     164 *
     165 * @see _Thread_queue_Enqueue().
     166 */
     167RTEMS_INLINE_ROUTINE void
     168_Thread_queue_Context_set_timeout_argument(
     169  Thread_queue_Context *queue_context,
     170  const void           *arg
     171)
     172{
     173  queue_context->Timeout.arg = arg;
     174}
     175
     176/**
    121177 * @brief Sets the enqueue callout in the thread queue context.
    122178 *
     
    151207
    152208/**
    153  * @brief Sets an indefinite timeout interval in the thread queue context.
     209 * @brief Sets the enqueue callout to add a relative monotonic timeout in
     210 * ticks.
    154211 *
    155212 * @param queue_context The thread queue context.
    156  * @param timeout The new timeout.
     213 * @param ticks The timeout in ticks.
    157214 *
    158215 * @see _Thread_queue_Enqueue().
    159216 */
    160217RTEMS_INLINE_ROUTINE void
    161 _Thread_queue_Context_set_no_timeout(
    162   Thread_queue_Context *queue_context
    163 )
    164 {
    165   queue_context->timeout_discipline = WATCHDOG_NO_TIMEOUT;
    166 }
    167 
    168 /**
    169  * @brief Sets a relative timeout in the thread queue context.
     218_Thread_queue_Context_set_enqueue_timeout_ticks(
     219  Thread_queue_Context *queue_context,
     220  Watchdog_Interval     ticks
     221)
     222{
     223  queue_context->Timeout.ticks = ticks;
     224  queue_context->enqueue_callout = _Thread_queue_Add_timeout_ticks;
     225}
     226
     227/**
     228 * @brief Sets the enqueue callout to add an absolute monotonic timeout in
     229 * timespec format.
    170230 *
    171231 * @param queue_context The thread queue context.
    172  * @param discipline The clock discipline to use for the timeout.
     232 * @param abstime The absolute monotonic timeout.
    173233 *
    174234 * @see _Thread_queue_Enqueue().
    175235 */
    176236RTEMS_INLINE_ROUTINE void
    177 _Thread_queue_Context_set_relative_timeout(
    178   Thread_queue_Context *queue_context,
    179   Watchdog_Interval     timeout
    180 )
    181 {
    182   queue_context->timeout_discipline = WATCHDOG_RELATIVE;
    183   queue_context->timeout = timeout;
    184 }
    185 
    186 /**
    187  * @brief Sets an absolute timeout in the thread queue context.
     237_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
     238  Thread_queue_Context  *queue_context,
     239  const struct timespec *abstime
     240)
     241{
     242  queue_context->Timeout.arg = abstime;
     243  queue_context->enqueue_callout =
     244    _Thread_queue_Add_timeout_monotonic_timespec;
     245}
     246
     247/**
     248 * @brief Sets the enqueue callout to add an absolute realtime timeout in
     249 * timespec format.
    188250 *
    189251 * @param queue_context The thread queue context.
    190  * @param discipline The clock discipline to use for the timeout.
     252 * @param abstime The absolute realtime timeout.
    191253 *
    192254 * @see _Thread_queue_Enqueue().
    193255 */
    194256RTEMS_INLINE_ROUTINE void
    195 _Thread_queue_Context_set_absolute_timeout(
    196   Thread_queue_Context *queue_context,
    197   uint64_t              timeout
    198 )
    199 {
    200   queue_context->timeout_discipline = WATCHDOG_ABSOLUTE;
    201   queue_context->timeout = timeout;
     257_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     258  Thread_queue_Context  *queue_context,
     259  const struct timespec *abstime
     260)
     261{
     262  queue_context->Timeout.arg = abstime;
     263  queue_context->enqueue_callout = _Thread_queue_Add_timeout_realtime_timespec;
    202264}
    203265
     
    616678 *
    617679 * - _Thread_queue_Context_set_enqueue_callout() or
    618  *   _Thread_queue_Context_set_enqueue_do_nothing_extra(),
    619  *
    620  * - _Thread_queue_Context_set_no_timeout() or
    621  *   _Thread_queue_Context_set_relative_timeout() or
    622  *   _Thread_queue_Context_set_absolute_timeout(), and
     680 *   _Thread_queue_Context_set_enqueue_do_nothing_extra() or
     681 *   _Thread_queue_Context_set_enqueue_timeout_ticks() or
     682 *   _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec() or
     683 *   _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(),
    623684 *
    624685 * - _Thread_queue_Context_set_deadlock_callout().
     
    653714 *     );
    654715 *     _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    655  *     _Thread_queue_Context_set_no_timeout( &queue_context );
    656716 *     _Thread_queue_Context_set_deadlock_callout(
    657717 *       queue_context,
  • cpukit/score/include/rtems/score/todimpl.h

    r1666ffe5 rc3105894  
    299299}
    300300
    301 /**
    302  * @brief Absolute timeout conversion results.
    303  *
    304  * This enumeration defines the possible results of converting
    305  * an absolute time used for timeouts to POSIX blocking calls to
    306  * a number of ticks for example.
    307  */
    308 typedef enum {
    309   /** The timeout is invalid. */
    310   TOD_ABSOLUTE_TIMEOUT_INVALID,
    311   /** The timeout represents a time that is in the past. */
    312   TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST,
    313   /** The timeout represents a time that is equal to the current time. */
    314   TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    315   /** The timeout represents a time that is in the future. */
    316   TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE,
    317 } TOD_Absolute_timeout_conversion_results;
    318 
    319 /**
    320  * @brief Convert absolute timeout to ticks.
    321  *
    322  * This method takes an absolute time being used as a timeout
    323  * to a blocking directive, validates it and returns the number
    324  * of corresponding clock ticks for use by the SuperCore.
    325  *
    326  * @param[in] abstime is a pointer to the timeout
    327  * @param[in] clock is the time source to use for the timeout
    328  * @param[out] ticks_out will contain the number of ticks
    329  *
    330  * @return This method returns the number of ticks in @a ticks_out
    331  *         and a status value indicating whether the absolute time
    332  *         is valid, in the past, equal to the current time or in
    333  *         the future as it should be.
    334  */
    335 TOD_Absolute_timeout_conversion_results _TOD_Absolute_timeout_to_ticks(
    336   const struct timespec *abstime,
    337   clockid_t              clock,
    338   Watchdog_Interval     *ticks_out
    339 );
    340 
    341301/**@}*/
    342302
  • cpukit/score/include/rtems/score/watchdog.h

    r1666ffe5 rc3105894  
    5454
    5555/**
    56  *  @brief The clock discipline to use for the Watchdog timeout interval.
     56 * @brief Special watchdog ticks value to indicate an infinite wait.
    5757 */
    58 typedef enum {
    59 
    60   /**
    61    * @brief Indefinite wait.
    62    *
    63    * This is to indicate there is no timeout and not to use a watchdog. It
    64    * must be equal to 0, which is an illegal relative clock interval, so that
    65    * it may be used as a Watchdog_Interval value with WATCHDOG_RELATIVE to
    66    * express an indefinite wait.
    67    */
    68   WATCHDOG_NO_TIMEOUT = 0,
    69 
    70   /**
    71    * @brief Relative clock.
    72    *
    73    * The reference time point for the watchdog is current ticks value
    74    * during insert.  Time is measured in clock ticks.
    75    */
    76   WATCHDOG_RELATIVE,
    77 
    78   /**
    79    * @brief Absolute clock.
    80    *
    81    * The reference time point for this header is the POSIX Epoch.  Time is
    82    * measured in nanoseconds since POSIX Epoch.
    83    */
    84   WATCHDOG_ABSOLUTE
    85 } Watchdog_Discipline;
     58#define WATCHDOG_NO_TIMEOUT 0
    8659
    8760/**
  • cpukit/score/include/rtems/score/watchdogimpl.h

    r1666ffe5 rc3105894  
    285285}
    286286
     287/**
     288 * @brief The maximum watchdog ticks value for the far future.
     289 */
     290#define WATCHDOG_MAXIMUM_TICKS UINT64_MAX
     291
    287292#define WATCHDOG_NANOSECONDS_PER_SECOND 1000000000
    288293
  • cpukit/score/src/apimutexlock.c

    r1666ffe5 rc3105894  
    3434  _Thread_queue_Context_initialize( &queue_context );
    3535  _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
    36   _Thread_queue_Context_set_no_timeout( &queue_context );
     36  _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    3737  _CORE_recursive_mutex_Seize(
    3838    &the_mutex->Mutex,
  • cpukit/score/src/condition.c

    r1666ffe5 rc3105894  
    8585} Condition_Enqueue_context;
    8686
    87 static void _Condition_Enqueue_callout(
     87static void _Condition_Mutex_release( Thread_queue_Context *queue_context )
     88{
     89  Condition_Enqueue_context *context;
     90
     91  context = (Condition_Enqueue_context *) queue_context;
     92  _Mutex_Release( context->mutex );
     93}
     94
     95static void _Condition_Enqueue_no_timeout(
    8896  Thread_queue_Queue   *queue,
    8997  Thread_Control       *the_thread,
    90   Thread_queue_Context *queue_context
    91 )
    92 {
    93   Condition_Enqueue_context *context;
    94 
    95   context = (Condition_Enqueue_context *) queue_context;
    96   _Mutex_Release( context->mutex );
     98  Per_CPU_Control      *cpu_self,
     99  Thread_queue_Context *queue_context
     100)
     101{
     102  _Condition_Mutex_release( queue_context );
     103}
     104
     105static void _Condition_Enqueue_with_timeout(
     106  Thread_queue_Queue   *queue,
     107  Thread_Control       *the_thread,
     108  Per_CPU_Control      *cpu_self,
     109  Thread_queue_Context *queue_context
     110)
     111{
     112  _Thread_queue_Add_timeout_realtime_timespec(
     113    queue,
     114    the_thread,
     115    cpu_self,
     116    queue_context
     117  );
     118  _Condition_Mutex_release( queue_context );
    97119}
    98120
     
    108130  context->mutex = _mutex;
    109131  condition = _Condition_Get( _condition );
     132  _ISR_lock_ISR_disable( &context->Base.Lock_context.Lock_context );
    110133  executing = _Condition_Queue_acquire_critical( condition, &context->Base );
    111134  _Thread_queue_Context_set_thread_state(
    112135    &context->Base,
    113136    STATES_WAITING_FOR_CONDITION_VARIABLE
    114   );
    115   _Thread_queue_Context_set_enqueue_callout(
    116     &context->Base,
    117     _Condition_Enqueue_callout
    118137  );
    119138  _Thread_queue_Enqueue(
     
    135154
    136155  _Thread_queue_Context_initialize( &context.Base );
    137   _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context );
    138   _Thread_queue_Context_set_no_timeout( &context.Base );
     156  _Thread_queue_Context_set_enqueue_callout(
     157    &context.Base,
     158    _Condition_Enqueue_no_timeout
     159  );
    139160  _Condition_Do_wait( _condition, _mutex, &context );
    140161  _Mutex_Acquire( _mutex );
     
    150171  Thread_Control            *executing;
    151172  int                        eno;
    152   Watchdog_Interval          ticks;
    153 
    154   _Thread_queue_Context_initialize( &context.Base );
    155   _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context );
    156 
    157   switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
    158     case TOD_ABSOLUTE_TIMEOUT_INVALID:
    159       _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context );
    160       return EINVAL;
    161     case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
    162     case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
    163       _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context );
    164       return ETIMEDOUT;
    165     default:
    166       break;
    167   }
    168 
    169   _Thread_queue_Context_set_relative_timeout( &context.Base, ticks );
     173
     174  _Thread_queue_Context_initialize( &context.Base );
     175  _Thread_queue_Context_set_enqueue_callout(
     176    &context.Base,
     177    _Condition_Enqueue_with_timeout
     178  );
     179  _Thread_queue_Context_set_timeout_argument( &context.Base, abstime );
    170180  executing = _Condition_Do_wait( _condition, _mutex, &context );
    171181  eno = STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) );
     
    196206
    197207  _Thread_queue_Context_initialize( &context.Base );
    198   _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context );
    199   _Thread_queue_Context_set_no_timeout( &context.Base );
     208  _Thread_queue_Context_set_enqueue_callout(
     209    &context.Base,
     210    _Condition_Enqueue_no_timeout
     211  );
    200212  nest_level = _Condition_Unnest_mutex( _mutex );
    201213  _Condition_Do_wait( _condition, &_mutex->_Mutex, &context );
     
    214226  int                        eno;
    215227  unsigned int               nest_level;
    216   Watchdog_Interval          ticks;
    217 
    218   _Thread_queue_Context_initialize( &context.Base );
    219   _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context );
    220 
    221   switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
    222     case TOD_ABSOLUTE_TIMEOUT_INVALID:
    223       _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context );
    224       return EINVAL;
    225     case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
    226     case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
    227       _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context );
    228       return ETIMEDOUT;
    229     default:
    230       break;
    231   }
    232   _Thread_queue_Context_set_relative_timeout( &context.Base, ticks );
     228
     229  _Thread_queue_Context_initialize( &context.Base );
     230  _Thread_queue_Context_set_enqueue_callout(
     231    &context.Base,
     232    _Condition_Enqueue_with_timeout
     233  );
     234  _Thread_queue_Context_set_timeout_argument( &context.Base, abstime );
    233235  nest_level = _Condition_Unnest_mutex( _mutex );
    234236  executing = _Condition_Do_wait( _condition, &_mutex->_Mutex, &context );
  • cpukit/score/src/corebarrierwait.c

    r1666ffe5 rc3105894  
    4949      STATES_WAITING_FOR_BARRIER
    5050    );
    51     _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    5251    _Thread_queue_Enqueue(
    5352      &the_barrier->Wait_queue.Queue,
  • cpukit/score/src/coremsgseize.c

    r1666ffe5 rc3105894  
    118118    STATES_WAITING_FOR_MESSAGE
    119119  );
    120   _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    121120  _Thread_queue_Enqueue(
    122121    &the_message_queue->Wait_queue.Queue,
  • cpukit/score/src/coremsgsubmit.c

    r1666ffe5 rc3105894  
    136136      STATES_WAITING_FOR_MESSAGE
    137137    );
    138     _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    139138    _Thread_queue_Enqueue(
    140139      &the_message_queue->Wait_queue.Queue,
  • cpukit/score/src/coremutexseize.c

    r1666ffe5 rc3105894  
    3737      STATES_WAITING_FOR_MUTEX
    3838    );
    39     _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    4039    _Thread_queue_Context_set_deadlock_callout(
    4140      queue_context,
  • cpukit/score/src/corerwlockobtainread.c

    r1666ffe5 rc3105894  
    7878   STATES_WAITING_FOR_RWLOCK
    7979  );
    80   _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    8180  _Thread_queue_Enqueue(
    8281     &the_rwlock->Queue.Queue,
  • cpukit/score/src/corerwlockobtainwrite.c

    r1666ffe5 rc3105894  
    7272    STATES_WAITING_FOR_RWLOCK
    7373  );
    74   _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    7574  _Thread_queue_Enqueue(
    7675     &the_rwlock->Queue.Queue,
  • cpukit/score/src/futex.c

    r1666ffe5 rc3105894  
    9696    );
    9797    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    98     _Thread_queue_Context_set_no_timeout( &queue_context );
    9998    _Thread_queue_Context_set_ISR_level( &queue_context, level );
    10099    _Thread_queue_Enqueue(
  • cpukit/score/src/mutex.c

    r1666ffe5 rc3105894  
    103103    STATES_WAITING_FOR_MUTEX
    104104  );
    105   _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
    106105  _Thread_queue_Context_set_deadlock_callout(
    107106    queue_context,
     
    164163    _Mutex_Queue_release( mutex, level, &queue_context );
    165164  } else {
    166     _Thread_queue_Context_set_no_timeout( &queue_context );
     165    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    167166    _Mutex_Acquire_slow( mutex, owner, executing, level, &queue_context );
    168167  }
     
    194193    return 0;
    195194  } else {
    196     Watchdog_Interval ticks;
    197 
    198     switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
    199       case TOD_ABSOLUTE_TIMEOUT_INVALID:
    200         _Mutex_Queue_release( mutex, level, &queue_context );
    201         return EINVAL;
    202       case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
    203       case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
    204         _Mutex_Queue_release( mutex, level, &queue_context );
    205         return ETIMEDOUT;
    206       default:
    207         break;
    208     }
    209 
    210     _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     195    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     196      &queue_context,
     197      abstime
     198    );
    211199    _Mutex_Acquire_slow( mutex, owner, executing, level, &queue_context );
    212200
     
    291279    _Mutex_Queue_release( &mutex->Mutex, level, &queue_context );
    292280  } else {
    293     _Thread_queue_Context_set_no_timeout( &queue_context );
     281    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    294282    _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context );
    295283  }
     
    326314    return 0;
    327315  } else {
    328     Watchdog_Interval ticks;
    329 
    330     switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
    331       case TOD_ABSOLUTE_TIMEOUT_INVALID:
    332         _Mutex_Queue_release( &mutex->Mutex, level, &queue_context );
    333         return EINVAL;
    334       case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
    335       case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
    336         _Mutex_Queue_release( &mutex->Mutex, level, &queue_context );
    337         return ETIMEDOUT;
    338       default:
    339         break;
    340     }
    341 
    342     _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     316    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
     317      &queue_context,
     318      abstime
     319    );
    343320    _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context );
    344321
  • cpukit/score/src/semaphore.c

    r1666ffe5 rc3105894  
    6262    );
    6363    _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
    64     _Thread_queue_Context_set_no_timeout( &queue_context );
    6564    _Thread_queue_Context_set_ISR_level( &queue_context, level );
    6665    _Thread_queue_Enqueue(
  • cpukit/score/src/threadqenqueue.c

    r1666ffe5 rc3105894  
    360360  Thread_queue_Queue   *queue,
    361361  Thread_Control       *the_thread,
    362   Thread_queue_Context *queue_context
    363 )
    364 {
    365   /* Do nothing */
    366 }
    367 
    368 void _Thread_queue_Deadlock_status( Thread_Control *the_thread )
    369 {
    370   the_thread->Wait.return_code = STATUS_DEADLOCK;
    371 }
    372 
    373 void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread )
    374 {
    375   _Internal_error( INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK );
    376 }
    377 
    378 static void _Thread_queue_Timeout(
    379   Thread_Control       *the_thread,
    380362  Per_CPU_Control      *cpu_self,
    381363  Thread_queue_Context *queue_context
    382364)
    383365{
    384   switch ( queue_context->timeout_discipline ) {
    385     case WATCHDOG_RELATIVE:
    386       /* A relative timeout of 0 is a special case indefinite (no) timeout */
    387       if ( queue_context->timeout != 0 ) {
    388         _Thread_Add_timeout_ticks(
    389           the_thread,
    390           cpu_self,
    391           (Watchdog_Interval) queue_context->timeout
    392         );
    393       }
    394       break;
    395     case WATCHDOG_ABSOLUTE:
    396       _Thread_Timer_insert_realtime(
    397         the_thread,
    398         cpu_self,
    399         _Thread_Timeout,
    400         queue_context->timeout
    401       );
    402       break;
    403     default:
    404       break;
    405   }
     366  /* Do nothing */
     367}
     368
     369void _Thread_queue_Deadlock_status( Thread_Control *the_thread )
     370{
     371  the_thread->Wait.return_code = STATUS_DEADLOCK;
     372}
     373
     374void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread )
     375{
     376  _Internal_error( INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK );
    406377}
    407378
     
    417388
    418389  _Assert( queue_context->enqueue_callout != NULL );
    419   _Assert( (uint8_t) queue_context->timeout_discipline != 0x7f );
    420390
    421391#if defined(RTEMS_MULTIPROCESSING)
     
    448418  _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
    449419
    450   ( *queue_context->enqueue_callout )( queue, the_thread, queue_context );
     420  ( *queue_context->enqueue_callout )(
     421    queue,
     422    the_thread,
     423    cpu_self,
     424    queue_context
     425  );
    451426
    452427  /*
     
    454429   */
    455430  _Thread_Set_state( the_thread, queue_context->thread_state );
    456 
    457   /*
    458    *  If the thread wants to timeout, then schedule its timer.
    459    */
    460   _Thread_queue_Timeout( the_thread, cpu_self, queue_context );
    461431
    462432  /*
     
    492462  Per_CPU_Control *cpu_self;
    493463
     464  _Assert( queue_context->enqueue_callout != NULL );
     465
    494466  _Thread_Wait_claim( the_thread, queue );
    495467
     
    520492  }
    521493
    522   _Thread_queue_Timeout( the_thread, cpu_self, queue_context );
     494  ( *queue_context->enqueue_callout )(
     495    queue,
     496    the_thread,
     497    cpu_self,
     498    queue_context
     499  );
     500
    523501  _Thread_Priority_update( queue_context );
    524502  _Thread_Priority_and_sticky_update( the_thread, 1 );
  • cpukit/score/src/threadrestart.c

    r1666ffe5 rc3105894  
    515515  Thread_queue_Queue   *queue,
    516516  Thread_Control       *the_thread,
     517  Per_CPU_Control      *cpu_self,
    517518  Thread_queue_Context *queue_context
    518519)
     
    535536    _Thread_Close_enqueue_callout
    536537  );
    537   _Thread_queue_Context_set_no_timeout( &context->Base );
    538538  _Thread_State_acquire_critical(
    539539    the_thread,
  • testsuites/psxtests/psx12/init.c

    r1666ffe5 rc3105894  
    211211
    212212  /* Align with clock tick */
    213   usleep( 1 );
     213  sleep( 1 );
    214214
    215215  ctx->start = now();
Note: See TracChangeset for help on using the changeset viewer.