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

Last change on this file since d17c114 was d17c114, checked in by Joel Sherrill <joel.sherrill@…>, on 07/24/08 at 20:43:24

2008-07-24 Joel Sherrill <joel.sherrill@…>

PR 1291/cpukit

  • posix/src/posixtimespecabsolutetimeout.c: New file.
  • itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/Makefile.am, posix/include/mqueue.h, posix/include/rtems/posix/mqueue.h, posix/include/rtems/posix/semaphore.h, posix/include/rtems/posix/time.h, posix/src/condtimedwait.c, posix/src/mqueuereceive.c, posix/src/mqueuerecvsupp.c, posix/src/mqueuesend.c, posix/src/mqueuesendsupp.c, posix/src/mqueuetimedreceive.c, posix/src/mqueuetimedsend.c, posix/src/mutexfromcorestatus.c, posix/src/mutextimedlock.c, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semtrywait.c, posix/src/semwait.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coresem.h, score/src/coremsgseize.c, score/src/coresemseize.c: This patch addresses issues on implementation of the timeout on the following POSIX services. Some of these services incorrectly took a timeout as a relative time. Others would compute a 0 delta to timeout if the absolute time and the current time were equal and thus incorrectly block the caller forever. The root of the confusion is that POSIX specifies that if the timeout is incorrect (e.g. in the past, is now, or is numerically invalid), that it does not matter if the call would succeed without blocking. This is in contrast to RTEMS programming style where all errors are checked before any critical sections are entered. This fix implemented a more uniform way of handling POSIX absolute time timeouts.

+ pthread_cond_timedwait - could block forever
+ mq_timedreceive - used relative not absolute time
+ mq_timedsend - used relative not absolute time
+ pthread_mutex_timedlock - used relative not absolute time
+ pthread_rwlock_timedrdlock- used relative not absolute time
+ pthread_rwlock_timedwrlock- used relative not absolute time
+ sem_timedwait - could block forever

  • Property mode set to 100644
File size: 2.2 KB
Line 
1/*
2 *  $Id$
3 */
4
5#if HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include <stdarg.h>
10
11#include <errno.h>
12#include <fcntl.h>
13#include <pthread.h>
14#include <semaphore.h>
15#include <limits.h>
16
17#include <rtems/system.h>
18#include <rtems/score/object.h>
19#include <rtems/posix/semaphore.h>
20#include <rtems/posix/time.h>
21#include <rtems/seterr.h>
22
23/*PAGE
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                 *sem,
32  const struct timespec *abstime
33)
34{
35  Watchdog_Interval                            ticks;
36  boolean                                      do_wait = TRUE;
37  POSIX_Absolute_timeout_conversion_results_t  status;
38  int                                          lock_status;
39
40  /*
41   *  POSIX requires that blocking calls with timeouts that take
42   *  an absolute timeout must ignore issues with the absolute
43   *  time provided if the operation would otherwise succeed.
44   *  So we check the abstime provided, and hold on to whether it
45   *  is valid or not.  If it isn't correct and in the future,
46   *  then we do a polling operation and convert the UNSATISFIED
47   *  status into the appropriate error.
48   */
49  status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks );
50  switch ( status ) {
51    case POSIX_ABSOLUTE_TIMEOUT_INVALID:
52    case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
53    case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
54      do_wait = FALSE;
55      break;
56    case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
57      do_wait = TRUE;
58      break;
59  }
60
61  lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks );
62
63  /*
64   *  This service only gives us the option to block.  We used a polling
65   *  attempt to obtain if the abstime was not in the future.  If we did
66   *  not obtain the semaphore, then not look at the status immediately,
67   *  make sure the right reason is returned.
68   */
69  if ( !do_wait && (lock_status == EBUSY) ) {
70    switch (lock_status) {
71      case POSIX_ABSOLUTE_TIMEOUT_INVALID:
72        return EINVAL;
73      case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
74      case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
75        return ETIMEDOUT;
76      case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
77        break;
78    }
79  }
80
81  return lock_status;
82}
Note: See TracBrowser for help on using the repository browser.