source: rtems/cpukit/score/src/corerwlockrelease.c @ e5200d5

4.104.114.84.9
Last change on this file since e5200d5 was e5200d5, checked in by Joel Sherrill <joel.sherrill@…>, on May 22, 2007 at 3:02:02 PM

2007-05-22 Joel Sherrill <joel.sherrill@…>

  • score/src/corerwlockrelease.c: Do not dereference NULL.
  • Property mode set to 100644
File size: 2.8 KB
Line 
1/*
2 *  SuperCore RWLock Handler -- Release a RWLock
3 *
4 *  COPYRIGHT (c) 1989-2006.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/score/corerwlock.h>
20#include <rtems/score/states.h>
21#include <rtems/score/thread.h>
22#include <rtems/score/watchdog.h>
23
24/*PAGE
25 *
26 *  _CORE_RWLock_Release
27 *
28 *  This function releases the rwlock.
29 *
30 *  Input parameters:
31 *    the_rwlock    - the rwlock control block to initialize
32 *
33 *  Output parameters:  NONE
34 */
35
36CORE_RWLock_Status _CORE_RWLock_Release(
37  CORE_RWLock_Control  *the_rwlock
38)
39{
40  ISR_Level       level;
41  Thread_Control *executing = _Thread_Executing;
42  Thread_Control *next;
43  uint32_t        rwmode;
44
45  /*
46   *  If unlocked, then OK to read.
47   *  Otherwise, we have to block.
48   *  If locked for reading and no waiters, then OK to read.
49   *  If any thread is waiting, then we wait.
50   */
51
52  _ISR_Disable( level );
53    switch ( the_rwlock->current_state ) {
54      case CORE_RWLOCK_UNLOCKED:
55        _ISR_Enable( level );
56        executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
57        return CORE_RWLOCK_SUCCESSFUL;
58
59      case CORE_RWLOCK_LOCKED_FOR_READING:
60        the_rwlock->number_of_readers -= 1;
61        if ( the_rwlock->number_of_readers != 0 ) {
62          /* must be unlocked again */
63          _ISR_Enable( level );
64          return CORE_RWLOCK_SUCCESSFUL;
65        }
66        executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
67        break;
68      case CORE_RWLOCK_LOCKED_FOR_WRITING:
69        executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
70        break;
71    }
72
73    /*
74     * Implicitly transition to "unlocked" and find another thread interested
75     * in obtaining this rwlock.
76     */
77    the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
78    _ISR_Enable( level );
79
80    next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue );
81   
82    if ( next ) {
83      rwmode = next->Wait.option;
84      if ( rwmode == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
85       the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
86       return CORE_RWLOCK_SUCCESSFUL;
87     } 
88
89     /*
90      * Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING now see if more
91      * readers can be let go.
92      */
93
94     while ( 1 ) {
95       next = _Thread_queue_First( &the_rwlock->Wait_queue );
96       if ( !next ) 
97         return CORE_RWLOCK_SUCCESSFUL;
98       if ( next->Wait.option != CORE_RWLOCK_THREAD_WAITING_FOR_READ )
99         return CORE_RWLOCK_SUCCESSFUL;
100
101       /* it is definitely wanting to read */
102       the_rwlock->number_of_readers += 1;
103       _Thread_queue_Extract( &the_rwlock->Wait_queue, next );
104     }
105
106    /* XXX need to put read/write lock request indicator in Wait info */
107
108  }
109
110  return CORE_RWLOCK_SUCCESSFUL;
111}
Note: See TracBrowser for help on using the repository browser.