source: rtems/cpukit/score/src/corerwlockrelease.c @ 1d56a7a

4.104.114.9
Last change on this file since 1d56a7a was 1d56a7a, checked in by Glenn Humphrey <glenn.humphrey@…>, on Nov 27, 2007 at 6:38:18 PM

2007-11-27 Glenn Humphrey <glenn.humphrey@…>

  • posix/src/prwlocktimedrdlock.c, posix/src/prwlocktimedwrlock.c, rtems/include/rtems/rtems/barrier.h, score/src/corerwlockobtainread.c, score/src/corerwlockobtainwrite.c, score/src/corerwlockrelease.c: Fixed several implementation errors.
  • 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
44  /*
45   *  If unlocked, then OK to read.
46   *  Otherwise, we have to block.
47   *  If locked for reading and no waiters, then OK to read.
48   *  If any thread is waiting, then we wait.
49   */
50
51  _ISR_Disable( level );
52    switch ( the_rwlock->current_state ) {
53      case CORE_RWLOCK_UNLOCKED:
54        _ISR_Enable( level );
55        executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
56        return CORE_RWLOCK_SUCCESSFUL;
57
58      case CORE_RWLOCK_LOCKED_FOR_READING:
59        the_rwlock->number_of_readers -= 1;
60        if ( the_rwlock->number_of_readers != 0 ) {
61          /* must be unlocked again */
62          _ISR_Enable( level );
63          return CORE_RWLOCK_SUCCESSFUL;
64        }
65        executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
66        break;
67      case CORE_RWLOCK_LOCKED_FOR_WRITING:
68        executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
69        break;
70    }
71
72    /*
73     * Implicitly transition to "unlocked" and find another thread interested
74     * in obtaining this rwlock.
75     */
76    the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
77    _ISR_Enable( level );
78
79    next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue );
80   
81    if ( next ) {
82      if ( next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
83        the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
84        return CORE_RWLOCK_SUCCESSFUL;
85      }
86
87      /*
88       * Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING
89       */
90      the_rwlock->number_of_readers += 1;
91      the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
92
93      /*
94       * Now see if more readers can be let go.
95       */
96      while ( 1 ) {
97        next = _Thread_queue_First( &the_rwlock->Wait_queue );
98        if ( !next || 
99             next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE )
100          return CORE_RWLOCK_SUCCESSFUL;
101        the_rwlock->number_of_readers += 1;
102        _Thread_queue_Extract( &the_rwlock->Wait_queue, next );
103      }
104    }
105  /* indentation is to match _ISR_Disable at top */
106
107  return CORE_RWLOCK_SUCCESSFUL;
108}
Note: See TracBrowser for help on using the repository browser.