source: rtems/cpukit/rtems/src/regiongetsegment.c @ 80cf60e

5
Last change on this file since 80cf60e was 80cf60e, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/20 at 07:48:32

Canonicalize config.h include

Use the following variant which was already used by most source files:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

  • Property mode set to 100644
File size: 2.8 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#ifdef 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  Per_CPU_Control      *cpu_self,
31  Thread_queue_Context *queue_context
32)
33{
34  Region_Control *the_region;
35
36  _Thread_queue_Add_timeout_ticks(
37    queue,
38    the_thread,
39    cpu_self,
40    queue_context
41  );
42
43  the_region = REGION_OF_THREAD_QUEUE_QUEUE( queue );
44  _Region_Unlock( the_region );
45}
46
47rtems_status_code rtems_region_get_segment(
48  rtems_id           id,
49  uintptr_t          size,
50  rtems_option       option_set,
51  rtems_interval     timeout,
52  void              **segment
53)
54{
55  rtems_status_code  status;
56  Region_Control    *the_region;
57
58  if ( segment == NULL ) {
59    return RTEMS_INVALID_ADDRESS;
60  }
61
62  *segment = NULL;
63
64  if ( size == 0 ) {
65    return RTEMS_INVALID_SIZE;
66  }
67
68  the_region = _Region_Get_and_lock( id );
69
70  if ( the_region == NULL ) {
71    return RTEMS_INVALID_ID;
72  }
73
74  if ( size > the_region->maximum_segment_size ) {
75    status = RTEMS_INVALID_SIZE;
76  } else {
77    void *the_segment;
78
79    the_segment = _Region_Allocate_segment( the_region, size );
80
81    if ( the_segment != NULL ) {
82      *segment = the_segment;
83      status = RTEMS_SUCCESSFUL;
84    } else if ( _Options_Is_no_wait( option_set ) ) {
85      status = RTEMS_UNSATISFIED;
86    } else {
87      Thread_queue_Context  queue_context;
88      Thread_Control       *executing;
89
90      _Thread_queue_Context_initialize( &queue_context );
91      _Thread_queue_Acquire( &the_region->Wait_queue, &queue_context );
92
93      executing  = _Thread_Executing;
94      executing->Wait.count           = size;
95      executing->Wait.return_argument = segment;
96
97      /* FIXME: This is a home grown condition variable */
98      _Thread_queue_Context_set_thread_state(
99        &queue_context,
100        STATES_WAITING_FOR_SEGMENT
101      );
102      _Thread_queue_Context_set_timeout_ticks( &queue_context, timeout );
103      _Thread_queue_Context_set_enqueue_callout(
104        &queue_context,
105        _Region_Enqueue_callout
106      );
107      _Thread_queue_Enqueue(
108        &the_region->Wait_queue.Queue,
109        the_region->wait_operations,
110        executing,
111        &queue_context
112      );
113      return _Status_Get_after_wait( executing );
114    }
115  }
116
117  _Region_Unlock( the_region );
118  return status;
119}
Note: See TracBrowser for help on using the repository browser.