source: rtems/cpukit/rtems/src/regiongetsegment.c @ 620b23e

5
Last change on this file since 620b23e was 620b23e, checked in by Sebastian Huber <sebastian.huber@…>, on 11/24/16 at 05:13:11

score: Optimize _Thread_queue_Enqueue()

Move thread state for _Thread_queue_Enqueue() to the thread queue
context. This reduces the parameter count of _Thread_queue_Enqueue()
from five to four (ARM for example has only four function parameter
registers). Since the thread state is used after several function calls
inside _Thread_queue_Enqueue() this parameter was saved on the stack
previously.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Get Region Segment
5 *  @ingroup ClassicRegion
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2007.
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/rtems/regionimpl.h>
22#include <rtems/rtems/optionsimpl.h>
23#include <rtems/rtems/statusimpl.h>
24#include <rtems/score/threadqimpl.h>
25#include <rtems/score/statesimpl.h>
26
27static void _Region_Enqueue_callout(
28  Thread_queue_Queue   *queue,
29  Thread_Control       *the_thread,
30  Thread_queue_Context *queue_context
31)
32{
33  Region_Control *the_region;
34
35  the_region = REGION_OF_THREAD_QUEUE_QUEUE( queue );
36  _Region_Unlock( the_region );
37}
38
39rtems_status_code rtems_region_get_segment(
40  rtems_id           id,
41  uintptr_t          size,
42  rtems_option       option_set,
43  rtems_interval     timeout,
44  void              **segment
45)
46{
47  rtems_status_code  status;
48  Region_Control    *the_region;
49
50  if ( segment == NULL ) {
51    return RTEMS_INVALID_ADDRESS;
52  }
53
54  *segment = NULL;
55
56  if ( size == 0 ) {
57    return RTEMS_INVALID_SIZE;
58  }
59
60  the_region = _Region_Get_and_lock( id );
61
62  if ( the_region == NULL ) {
63    return RTEMS_INVALID_ID;
64  }
65
66  if ( size > the_region->maximum_segment_size ) {
67    status = RTEMS_INVALID_SIZE;
68  } else {
69    void *the_segment;
70
71    the_segment = _Region_Allocate_segment( the_region, size );
72
73    if ( the_segment != NULL ) {
74      *segment = the_segment;
75      status = RTEMS_SUCCESSFUL;
76    } else if ( _Options_Is_no_wait( option_set ) ) {
77      status = RTEMS_UNSATISFIED;
78    } else {
79      Thread_queue_Context  queue_context;
80      Thread_Control       *executing;
81
82      _Thread_queue_Context_initialize( &queue_context );
83      _Thread_queue_Acquire( &the_region->Wait_queue, &queue_context );
84
85      executing  = _Thread_Executing;
86      executing->Wait.count           = size;
87      executing->Wait.return_argument = segment;
88
89      /* FIXME: This is a home grown condition variable */
90      _Thread_queue_Context_set_thread_state(
91        &queue_context,
92        STATES_WAITING_FOR_SEGMENT
93      );
94      _Thread_queue_Context_set_enqueue_callout(
95        &queue_context,
96        _Region_Enqueue_callout
97      );
98      _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
99      _Thread_queue_Enqueue(
100        &the_region->Wait_queue.Queue,
101        the_region->wait_operations,
102        executing,
103        &queue_context
104      );
105      return _Status_Get_after_wait( executing );
106    }
107  }
108
109  _Region_Unlock( the_region );
110  return status;
111}
Note: See TracBrowser for help on using the repository browser.