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

4.10
Last change on this file since e3f6d35 was e3f6d35, checked in by Gedare Bloom <gedare@…>, on Jan 2, 2020 at 10:45:30 PM

cpukit/score: avoid NULL and races in priority mutex

The PIP modifications from #3359 introduced new data structures
to track priority inheritance. Prioritized mutexes without PIP
share some of the code paths, and may result in NULL pointer
accesses. This patch checks for NULL, and also adds ISR critical
sections to an uncovered corner case during thread restarts.

Closes #3829.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/*
2 *  Thread Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/system.h>
20#include <rtems/score/apiext.h>
21#include <rtems/score/context.h>
22#include <rtems/score/coremutex.h>
23#include <rtems/score/interr.h>
24#include <rtems/score/isr.h>
25#include <rtems/score/object.h>
26#include <rtems/score/priority.h>
27#include <rtems/score/states.h>
28#include <rtems/score/sysstate.h>
29#include <rtems/score/thread.h>
30#include <rtems/score/threadq.h>
31#include <rtems/score/userext.h>
32#include <rtems/score/wkspace.h>
33
34/*
35 *  _Thread_Reset
36 *
37 *  DESCRIPTION:
38 *
39 *  This routine resets a thread to its initial stat but does
40 *  not actually restart it.  Some APIs do this in separate
41 *  operations and this division helps support this.
42 */
43
44void _Thread_Reset(
45  Thread_Control            *the_thread,
46  void                      *pointer_argument,
47  Thread_Entry_numeric_type  numeric_argument
48)
49{
50  CORE_mutex_Control *mutex;
51  ISR_Level              level;
52
53  the_thread->resource_count   = 0;
54  #if defined(RTEMS_ITRON_API)
55    the_thread->suspend_count  = 0;
56  #endif
57  the_thread->is_preemptible   = the_thread->Start.is_preemptible;
58  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
59  the_thread->budget_callout   = the_thread->Start.budget_callout;
60
61  the_thread->Start.pointer_argument = pointer_argument;
62  the_thread->Start.numeric_argument = numeric_argument;
63
64  if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
65
66    if ( _Watchdog_Is_active( &the_thread->Timer ) )
67      (void) _Watchdog_Remove( &the_thread->Timer );
68  }
69
70  _ISR_Disable( level );
71  if ( the_thread->Priority_node.waiting_to_hold != NULL ) {
72    mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node );
73    _Thread_Evaluate_priority( mutex->holder );
74  }
75  _ISR_Enable( level );
76
77  _ISR_Disable( level );
78  while ( !_Chain_Is_empty( &the_thread->Priority_node.Inherited_priorities ) ) {
79    _Thread_Dequeue_priority_node(
80      ((Thread_Priority_node*)_Chain_First(
81        &the_thread->Priority_node.Inherited_priorities
82      ))
83    );
84    _ISR_Flash( level );
85  }
86  _ISR_Enable( level );
87
88  if ( the_thread->Priority_node.current_priority != the_thread->Start.initial_priority ) {
89    the_thread->Priority_node.real_priority = the_thread->Start.initial_priority;
90    _Thread_Set_priority( the_thread, the_thread->Start.initial_priority );
91  }
92}
Note: See TracBrowser for help on using the repository browser.