source: rtems/cpukit/posix/src/prwlocktimedwrlock.c @ 84a53988

5
Last change on this file since 84a53988 was 84a53988, checked in by Sebastian Huber <sebastian.huber@…>, on 04/21/16 at 04:32:16

score: Avoid Giant lock for CORE rwlock

Update #2555.

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Function applies a Write lock to RWLock referenced by rwlock
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  POSIX RWLock Manager -- Attempt to Obtain a Write Lock on a RWLock Instance
10 *
11 *  COPYRIGHT (c) 1989-2008.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <rtems/posix/rwlockimpl.h>
24#include <rtems/score/todimpl.h>
25
26int pthread_rwlock_timedwrlock(
27  pthread_rwlock_t      *rwlock,
28  const struct timespec *abstime
29)
30{
31  POSIX_RWLock_Control                    *the_rwlock;
32  ISR_lock_Context                         lock_context;
33  Watchdog_Interval                        ticks;
34  bool                                     do_wait;
35  TOD_Absolute_timeout_conversion_results  status;
36  Thread_Control                          *executing;
37
38  /*
39   *  POSIX requires that blocking calls with timeouts that take
40   *  an absolute timeout must ignore issues with the absolute
41   *  time provided if the operation would otherwise succeed.
42   *  So we check the abstime provided, and hold on to whether it
43   *  is valid or not.  If it isn't correct and in the future,
44   *  then we do a polling operation and convert the UNSATISFIED
45   *  status into the appropriate error.
46   *
47   *  If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
48   *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
49   *  then we should not wait.
50   */
51  status = _TOD_Absolute_timeout_to_ticks( abstime, &ticks );
52  do_wait = ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
53
54  the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );
55
56  if ( the_rwlock == NULL ) {
57    return EINVAL;
58  }
59
60  executing = _Thread_Executing;
61  _CORE_RWLock_Seize_for_writing(
62    &the_rwlock->RWLock,
63    executing,
64    do_wait,
65    ticks,
66    &lock_context
67  );
68
69  if (
70    !do_wait
71      && ( executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE )
72  ) {
73    if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
74      return EINVAL;
75    }
76
77    if (
78      status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
79        || status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
80    ) {
81      return ETIMEDOUT;
82    }
83  }
84
85  return _POSIX_RWLock_Translate_core_RWLock_return_code(
86    (CORE_RWLock_Status) executing->Wait.return_code
87  );
88}
Note: See TracBrowser for help on using the repository browser.