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

4.10
Last change on this file since e3f6d35 was 28352fae, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/29/09 at 13:51:53

Whitespace removal.

  • 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    if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){
53      _ISR_Enable( level );
54      executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
55      return CORE_RWLOCK_SUCCESSFUL;
56    }
57    if ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING ) {
58        the_rwlock->number_of_readers -= 1;
59        if ( the_rwlock->number_of_readers != 0 ) {
60          /* must be unlocked again */
61          _ISR_Enable( level );
62          return CORE_RWLOCK_SUCCESSFUL;
63        }
64    }
65
66    /* CORE_RWLOCK_LOCKED_FOR_WRITING or READING with readers */
67    executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
68
69    /*
70     * Implicitly transition to "unlocked" and find another thread interested
71     * in obtaining this rwlock.
72     */
73    the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
74  _ISR_Enable( level );
75
76  next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue );
77
78  if ( next ) {
79    if ( next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
80      the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
81      return CORE_RWLOCK_SUCCESSFUL;
82    }
83
84    /*
85     * Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING
86     */
87    the_rwlock->number_of_readers += 1;
88    the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
89
90    /*
91     * Now see if more readers can be let go.
92     */
93    while ( 1 ) {
94      next = _Thread_queue_First( &the_rwlock->Wait_queue );
95      if ( !next ||
96           next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE )
97        return CORE_RWLOCK_SUCCESSFUL;
98      the_rwlock->number_of_readers += 1;
99      _Thread_queue_Extract( &the_rwlock->Wait_queue, next );
100    }
101  }
102
103  /* indentation is to match _ISR_Disable at top */
104
105  return CORE_RWLOCK_SUCCESSFUL;
106}
Note: See TracBrowser for help on using the repository browser.