source: rtems/cpukit/score/src/coremutex.c @ 900d337f

4.115
Last change on this file since 900d337f was 900d337f, checked in by Sebastian Huber <sebastian.huber@…>, on 05/05/15 at 11:05:54

score: Rework _Thread_Change_priority()

Move the writes to Thread_Control::current_priority and
Thread_Control::real_priority into _Thread_Change_priority() under the
protection of the thread lock. Add a filter function to
_Thread_Change_priority() to enable specialized variants.

Avoid race conditions during a thread priority restore with the new
Thread_Control::priority_restore_hint for an important average case
optimizations used by priority inheritance mutexes.

Update #2273.

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Initialize a Core Mutex
5 *  @ingroup ScoreMutex
6 */
7
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.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/system.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/coremuteximpl.h>
24#include <rtems/score/thread.h>
25
26CORE_mutex_Status _CORE_mutex_Initialize(
27  CORE_mutex_Control           *the_mutex,
28  Thread_Control               *executing,
29  const CORE_mutex_Attributes  *the_mutex_attributes,
30  bool                          initially_locked
31)
32{
33
34/* Add this to the RTEMS environment later ?????????
35  rtems_assert( initial_lock == CORE_MUTEX_LOCKED ||
36                initial_lock == CORE_MUTEX_UNLOCKED );
37 */
38
39  the_mutex->Attributes    = *the_mutex_attributes;
40
41  if ( initially_locked ) {
42    bool is_priority_ceiling =
43      _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
44
45    the_mutex->nest_count = 1;
46    the_mutex->holder     = executing;
47
48    if (  is_priority_ceiling ||
49         _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
50      Priority_Control ceiling = the_mutex->Attributes.priority_ceiling;
51      Per_CPU_Control *cpu_self;
52
53      /* The mutex initialization is only protected by the allocator lock */
54      cpu_self = _Thread_Dispatch_disable();
55
56      /*
57       * The test to check for a ceiling violation is a bit arbitrary.  In case
58       * this thread is the owner of a priority inheritance mutex, then it may
59       * get a higher priority later or anytime on SMP configurations.
60       */
61      if ( is_priority_ceiling && executing->current_priority < ceiling ) {
62        /*
63         * There is no need to undo the previous work since this error aborts
64         * the object creation.
65         */
66        _Thread_Dispatch_enable( cpu_self );
67        return CORE_MUTEX_STATUS_CEILING_VIOLATED;
68      }
69
70#ifdef __RTEMS_STRICT_ORDER_MUTEX__
71       _Chain_Prepend_unprotected( &executing->lock_mutex,
72                                   &the_mutex->queue.lock_queue );
73       the_mutex->queue.priority_before = executing->current_priority;
74#endif
75
76      executing->resource_count++;
77
78      if ( is_priority_ceiling ) {
79        _Thread_Raise_priority( executing, ceiling );
80      }
81
82      _Thread_Dispatch_enable( cpu_self );
83    }
84  } else {
85    the_mutex->nest_count = 0;
86    the_mutex->holder     = NULL;
87  }
88
89  _Thread_queue_Initialize(
90    &the_mutex->Wait_queue,
91    _CORE_mutex_Is_fifo( the_mutex_attributes ) ?
92      THREAD_QUEUE_DISCIPLINE_FIFO : THREAD_QUEUE_DISCIPLINE_PRIORITY
93  );
94
95  return CORE_MUTEX_STATUS_SUCCESSFUL;
96}
Note: See TracBrowser for help on using the repository browser.