source: rtems/cpukit/score/src/threadqenqueue.c @ 3250664

4.115
Last change on this file since 3250664 was 3250664, checked in by Joel Sherrill <joel.sherrill@…>, on 07/15/14 at 17:37:36

Thread Queue: Merge discipline subroutines into main methods

There was a lot of duplication between the discipline subroutines.
With the transition to RBTrees for priority discipline, there were
only a few lines of source code manipulating the data structure
for FIFO and priority. Thus is made sense to fold these back
into the main methods.

As part of doing this all of the tests for discipline were changed
to be in the same order.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Queue Enqueue
5 * @ingroup ScoreThreadQ
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014.
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/score/threadqimpl.h>
22#include <rtems/score/isrlevel.h>
23#include <rtems/score/threadimpl.h>
24#include <rtems/score/watchdogimpl.h>
25
26void _Thread_queue_Enqueue_with_handler(
27  Thread_queue_Control         *the_thread_queue,
28  Thread_Control               *the_thread,
29  Watchdog_Interval             timeout,
30  Thread_queue_Timeout_callout  handler
31)
32{
33  ISR_Level                         level;
34  Thread_blocking_operation_States  sync_state;
35
36#if defined(RTEMS_MULTIPROCESSING)
37  if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet )
38    the_thread = _Thread_MP_Allocate_proxy( the_thread_queue->state );
39  else
40#endif
41  /*
42   *  Set the blocking state for this thread queue in the thread.
43   */
44  _Thread_Set_state( the_thread, the_thread_queue->state );
45
46  /*
47   *  If the thread wants to timeout, then schedule its timer.
48   */
49  if ( timeout ) {
50    _Watchdog_Initialize(
51       &the_thread->Timer,
52       handler,
53       the_thread->Object.id,
54       NULL
55    );
56
57    _Watchdog_Insert_ticks( &the_thread->Timer, timeout );
58  }
59
60  /*
61   * Now initiate the enqueuing and checking if the blocking operation
62   * should be completed or the thread has had its blocking condition
63   * satisfied before we got here.
64   */
65  _ISR_Disable( level );
66
67  sync_state = the_thread_queue->sync_state;
68  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
69
70  if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
71    /*
72     * Invoke the discipline specific enqueue method.
73     */
74    if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
75      _Chain_Append_unprotected(
76        &the_thread_queue->Queues.Fifo,
77        &the_thread->Object.Node
78      );
79    } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
80      _RBTree_Insert(
81        &the_thread_queue->Queues.Priority,
82        &the_thread->RBNode,
83        _Thread_queue_Compare_priority,
84        false
85      );
86    }
87
88    the_thread->Wait.queue = the_thread_queue;
89    the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
90    _ISR_Enable( level );
91    return;
92  } else { /* sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) */
93    _Thread_blocking_operation_Cancel( sync_state, the_thread, level );
94  }
95}
Note: See TracBrowser for help on using the repository browser.