source: rtems/c/src/exec/score/src/coremutexsurrender.c @ ca837f8a

4.104.114.84.95
Last change on this file since ca837f8a was fb1d8f81, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/01 at 18:33:57

2001-08-30 Joel Sherrill <joel@…>

  • src/coremutex.c, src/coremutexseize.c, src/coremutexsurrender.c, inline/rtems/score/coremutex.inl: The per thread field resource_count should only be manipulated when a mutex is priority ceiling or priority inherit. This was reported by Chris Johns <ccj@…> who also noticed that the use of switches for all disciplines generated less efficient code than using explicit tests for the one or two cases we were really interested in. Further review of his modifications made it apparent that the "isa" methods to test mutex discipline were not being used so this modification was swept into the code as well.
  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 *  Mutex Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the Mutex Handler.
7 *  This handler provides synchronization and mutual exclusion capabilities.
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.OARcorp.com/rtems/license.html.
15 *
16 *  $Id$
17 */
18
19#include <rtems/system.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/coremutex.h>
22#include <rtems/score/states.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/threadq.h>
25
26/*
27 *  _CORE_mutex_Surrender
28 *
29 *  DESCRIPTION:
30 *
31 *  This routine frees a unit to the mutex.  If a task was blocked waiting for
32 *  a unit from this mutex, then that task will be readied and the unit
33 *  given to that task.  Otherwise, the unit will be returned to the mutex.
34 *
35 *  Input parameters:
36 *    the_mutex            - the mutex to be flushed
37 *    id                   - id of parent mutex
38 *    api_mutex_mp_support - api dependent MP support actions
39 *
40 *  Output parameters:
41 *    CORE_MUTEX_STATUS_SUCCESSFUL - if successful
42 *    core error code              - if unsuccessful
43 */
44
45CORE_mutex_Status _CORE_mutex_Surrender(
46  CORE_mutex_Control                *the_mutex,
47  Objects_Id                         id,
48  CORE_mutex_API_mp_support_callout  api_mutex_mp_support
49)
50{
51  Thread_Control *the_thread;
52  Thread_Control *holder;
53
54  holder    = the_mutex->holder;
55
56  /*
57   *  The following code allows a thread (or ISR) other than the thread
58   *  which acquired the mutex to release that mutex.  This is only
59   *  allowed when the mutex in quetion is FIFO or simple Priority
60   *  discipline.  But Priority Ceiling or Priority Inheritance mutexes
61   *  must be released by the thread which acquired them.
62   */
63
64  if ( the_mutex->Attributes.only_owner_release ) {
65    if ( !_Thread_Is_executing( holder ) )
66      return CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE;
67  }
68
69  /* XXX already unlocked -- not right status */
70
71  if ( !the_mutex->nest_count )
72    return CORE_MUTEX_STATUS_SUCCESSFUL;
73
74  the_mutex->nest_count--;
75
76  if ( the_mutex->nest_count != 0 ) {
77    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
78      case CORE_MUTEX_NESTING_ACQUIRES:
79        return CORE_MUTEX_STATUS_SUCCESSFUL;
80      case CORE_MUTEX_NESTING_IS_ERROR:
81        /* should never occur */
82        return CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
83      case CORE_MUTEX_NESTING_BLOCKS:
84        /* Currently no API exercises this behavior. */
85        break;
86    }
87  }
88
89  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
90       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
91    holder->resource_count--;
92  the_mutex->holder    = NULL;
93  the_mutex->holder_id = 0;
94
95  /*
96   *  Whether or not someone is waiting for the mutex, an
97   *  inherited priority must be lowered if this is the last
98   *  mutex (i.e. resource) this task has.
99   */
100
101  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
102       _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
103    if ( holder->resource_count == 0 &&
104         holder->real_priority != holder->current_priority ) {
105      _Thread_Change_priority( holder, holder->real_priority, TRUE );
106    }
107  }
108
109  if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
110
111#if defined(RTEMS_MULTIPROCESSING)
112    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
113     
114      the_mutex->holder     = NULL;
115      the_mutex->holder_id  = the_thread->Object.id;
116      the_mutex->nest_count = 1;
117
118      ( *api_mutex_mp_support)( the_thread, id );
119
120    } else
121#endif
122    {
123
124      the_mutex->holder     = the_thread;
125      the_mutex->holder_id  = the_thread->Object.id;
126      if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
127           _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
128        the_thread->resource_count++;
129      the_mutex->nest_count = 1;
130
131     /*
132      *  No special action for priority inheritance or priority ceiling
133      *  because the_thread is guaranteed to be the highest priority
134      *  thread waiting for the mutex.
135      */
136    }
137  } else
138    the_mutex->lock = CORE_MUTEX_UNLOCKED;
139
140  return CORE_MUTEX_STATUS_SUCCESSFUL;
141}
142
Note: See TracBrowser for help on using the repository browser.