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

5
Last change on this file since 1506658c was 22788bc, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/15 at 11:01:05

score: _Thread_queue_Extract()

Remove thread queue parameter from _Thread_queue_Extract() since the
current thread queue is stored in the thread control block.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Releases the RWLock
5 *
6 * @ingroup ScoreRWLock
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2006.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/system.h>
23#include <rtems/score/corerwlockimpl.h>
24#include <rtems/score/threadqimpl.h>
25#include <rtems/score/watchdog.h>
26
27CORE_RWLock_Status _CORE_RWLock_Release(
28  CORE_RWLock_Control *the_rwlock,
29  Thread_Control      *executing
30)
31{
32  ISR_Level       level;
33  Thread_Control *next;
34
35  /*
36   *  If unlocked, then OK to read.
37   *  Otherwise, we have to block.
38   *  If locked for reading and no waiters, then OK to read.
39   *  If any thread is waiting, then we wait.
40   */
41
42  _ISR_Disable( level );
43    if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){
44      _ISR_Enable( level );
45      executing->Wait.return_code = CORE_RWLOCK_UNAVAILABLE;
46      return CORE_RWLOCK_SUCCESSFUL;
47    }
48    if ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING ) {
49        the_rwlock->number_of_readers -= 1;
50        if ( the_rwlock->number_of_readers != 0 ) {
51          /* must be unlocked again */
52          _ISR_Enable( level );
53          return CORE_RWLOCK_SUCCESSFUL;
54        }
55    }
56
57    /* CORE_RWLOCK_LOCKED_FOR_WRITING or READING with readers */
58    executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
59
60    /*
61     * Implicitly transition to "unlocked" and find another thread interested
62     * in obtaining this rwlock.
63     */
64    the_rwlock->current_state = CORE_RWLOCK_UNLOCKED;
65  _ISR_Enable( level );
66
67  next = _Thread_queue_Dequeue( &the_rwlock->Wait_queue );
68
69  if ( next ) {
70    if ( next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE ) {
71      the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_WRITING;
72      return CORE_RWLOCK_SUCCESSFUL;
73    }
74
75    /*
76     * Must be CORE_RWLOCK_THREAD_WAITING_FOR_READING
77     */
78    the_rwlock->number_of_readers += 1;
79    the_rwlock->current_state = CORE_RWLOCK_LOCKED_FOR_READING;
80
81    /*
82     * Now see if more readers can be let go.
83     */
84    while ( 1 ) {
85      next = _Thread_queue_First( &the_rwlock->Wait_queue );
86      if ( !next ||
87           next->Wait.option == CORE_RWLOCK_THREAD_WAITING_FOR_WRITE )
88        return CORE_RWLOCK_SUCCESSFUL;
89      the_rwlock->number_of_readers += 1;
90      _Thread_queue_Extract( next );
91    }
92  }
93
94  /* indentation is to match _ISR_Disable at top */
95
96  return CORE_RWLOCK_SUCCESSFUL;
97}
Note: See TracBrowser for help on using the repository browser.