source: rtems/cpukit/score/src/wkspace.c @ 83bf105

4.115
Last change on this file since 83bf105 was 83bf105, checked in by Sebastian Huber <sebastian.huber@…>, on 02/19/14 at 09:57:46

score: Rename _Internal_error_Occurred()

Rename _Internal_error_Occurred() into _Terminate().

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Workspace Handler Support
5 *  @ingroup ScoreWorkspace
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
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.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/score/wkspace.h>
22#include <rtems/score/heapimpl.h>
23#include <rtems/score/interr.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/score/tls.h>
26#include <rtems/config.h>
27
28#include <string.h>  /* for memset */
29
30/* #define DEBUG_WORKSPACE */
31#if defined(DEBUG_WORKSPACE)
32  #include <rtems/bspIo.h>
33#endif
34
35static uint32_t _Get_maximum_thread_count(void)
36{
37  uint32_t thread_count = 0;
38
39  thread_count += _Thread_Get_maximum_internal_threads();
40
41  thread_count += rtems_resource_maximum_per_allocation(
42    Configuration_RTEMS_API.maximum_tasks
43  );
44
45#if defined(RTEMS_POSIX_API)
46  thread_count += rtems_resource_maximum_per_allocation(
47    Configuration_POSIX_API.maximum_threads
48  );
49#endif
50
51  return thread_count;
52}
53
54void _Workspace_Handler_initialization(
55  Heap_Area *areas,
56  size_t area_count,
57  Heap_Initialization_or_extend_handler extend
58)
59{
60  Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize;
61  uintptr_t remaining = rtems_configuration_get_work_space_size();
62  bool do_zero = rtems_configuration_get_do_zero_of_workspace();
63  bool unified = rtems_configuration_get_unified_work_area();
64  uintptr_t page_size = CPU_HEAP_ALIGNMENT;
65  uintptr_t overhead = _Heap_Area_overhead( page_size );
66  uintptr_t tls_size = (uintptr_t) _TLS_Size;
67  size_t i;
68
69  if ( tls_size > 0 ) {
70    uintptr_t tls_alignment = (uintptr_t) _TLS_Alignment;
71    uintptr_t tls_alloc = _TLS_Get_allocation_size( tls_size, tls_alignment );
72
73    remaining += _Get_maximum_thread_count()
74      * _Heap_Size_with_overhead( page_size, tls_alloc, tls_alignment );
75  }
76
77  for (i = 0; i < area_count; ++i) {
78    Heap_Area *area = &areas [i];
79
80    if ( do_zero ) {
81      memset( area->begin, 0, area->size );
82    }
83
84    if ( area->size > overhead ) {
85      uintptr_t space_available;
86      uintptr_t size;
87
88      if ( unified ) {
89        size = area->size;
90      } else {
91        if ( remaining > 0 ) {
92          size = remaining < area->size - overhead ?
93            remaining + overhead : area->size;
94        } else {
95          size = 0;
96        }
97      }
98
99      space_available = (*init_or_extend)(
100        &_Workspace_Area,
101        area->begin,
102        size,
103        page_size
104      );
105
106      area->begin = (char *) area->begin + size;
107      area->size -= size;
108
109      if ( space_available < remaining ) {
110        remaining -= space_available;
111      } else {
112        remaining = 0;
113      }
114
115      init_or_extend = extend;
116    }
117  }
118
119  if ( remaining > 0 ) {
120    _Terminate(
121      INTERNAL_ERROR_CORE,
122      true,
123      INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
124    );
125  }
126}
127
128void *_Workspace_Allocate(
129  size_t   size
130)
131{
132  void *memory;
133
134  memory = _Heap_Allocate( &_Workspace_Area, size );
135  #if defined(DEBUG_WORKSPACE)
136    printk(
137      "Workspace_Allocate(%d) from %p/%p -> %p\n",
138      size,
139      __builtin_return_address( 0 ),
140      __builtin_return_address( 1 ),
141      memory
142    );
143  #endif
144  return memory;
145}
146
147void *_Workspace_Allocate_aligned( size_t size, size_t alignment )
148{
149  return _Heap_Allocate_aligned( &_Workspace_Area, size, alignment );
150}
151
152/*
153 *  _Workspace_Free
154 */
155void _Workspace_Free(
156  void *block
157)
158{
159  #if defined(DEBUG_WORKSPACE)
160    printk(
161      "Workspace_Free(%p) from %p/%p\n",
162      block,
163      __builtin_return_address( 0 ),
164      __builtin_return_address( 1 )
165    );
166  #endif
167  _Heap_Free( &_Workspace_Area, block );
168}
169
170void *_Workspace_Allocate_or_fatal_error(
171  size_t      size
172)
173{
174  void *memory;
175
176  memory = _Heap_Allocate( &_Workspace_Area, size );
177  #if defined(DEBUG_WORKSPACE)
178    printk(
179      "Workspace_Allocate_or_fatal_error(%d) from %p/%p -> %p\n",
180      size,
181      __builtin_return_address( 0 ),
182      __builtin_return_address( 1 ),
183      memory
184    );
185  #endif
186
187  if ( memory == NULL )
188    _Terminate(
189      INTERNAL_ERROR_CORE,
190      true,
191      INTERNAL_ERROR_WORKSPACE_ALLOCATION
192    );
193
194  return memory;
195}
Note: See TracBrowser for help on using the repository browser.