source: rtems-docs/c-user/region_manager.rst @ 12dccfe

5
Last change on this file since 12dccfe was 12dccfe, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:05

Remove superfluous "All rights reserved."

  • Property mode set to 100644
File size: 22.0 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR)
4
5.. index:: regions
6
7Region Manager
8**************
9
10Introduction
11============
12
13The region manager provides facilities to dynamically allocate memory in
14variable sized units.  The directives provided by the region manager are:
15
16- rtems_region_create_ - Create a region
17
18- rtems_region_ident_ - Get ID of a region
19
20- rtems_region_delete_ - Delete a region
21
22- rtems_region_extend_ - Add memory to a region
23
24- rtems_region_get_segment_ - Get segment from a region
25
26- rtems_region_return_segment_ - Return segment to a region
27
28- rtems_region_get_segment_size_ - Obtain size of a segment
29
30- rtems_region_resize_segment_ - Change size of a segment
31
32Background
33==========
34
35.. index:: region, definition
36.. index:: segment, definition
37
38Region Manager Definitions
39--------------------------
40
41A region makes up a physically contiguous memory space with user-defined
42boundaries from which variable-sized segments are dynamically allocated and
43deallocated.  A segment is a variable size section of memory which is allocated
44in multiples of a user-defined page size.  This page size is required to be a
45multiple of four greater than or equal to four.  For example, if a request for
46a 350-byte segment is made in a region with 256-byte pages, then a 512-byte
47segment is allocated.
48
49Regions are organized as doubly linked chains of variable sized memory blocks.
50Memory requests are allocated using a first-fit algorithm.  If available, the
51requester receives the number of bytes requested (rounded up to the next page
52size).  RTEMS requires some overhead from the region's memory for each segment
53that is allocated.  Therefore, an application should only modify the memory of
54a segment that has been obtained from the region.  The application should NOT
55modify the memory outside of any obtained segments and within the region's
56boundaries while the region is currently active in the system.
57
58Upon return to the region, the free block is coalesced with its neighbors (if
59free) on both sides to produce the largest possible unused block.
60
61.. index:: region attribute set, building
62
63Building an Attribute Set
64-------------------------
65
66In general, an attribute set is built by a bitwise OR of the desired attribute
67components.  The set of valid region attributes is provided in the following
68table:
69
70.. list-table::
71 :class: rtems-table
72
73 * - ``RTEMS_FIFO``
74   - tasks wait by FIFO (default)
75 * - ``RTEMS_PRIORITY``
76   - tasks wait by priority
77
78Attribute values are specifically designed to be mutually exclusive, therefore
79bitwise OR and addition operations are equivalent as long as each attribute
80appears exactly once in the component list.  An attribute listed as a default
81is not required to appear in the attribute list, although it is a good
82programming practice to specify default attributes.  If all defaults are
83desired, the attribute ``RTEMS_DEFAULT_ATTRIBUTES`` should be specified on this
84call.
85
86This example demonstrates the attribute_set parameter needed to create a region
87with the task priority waiting queue discipline.  The attribute_set parameter
88to the ``rtems_region_create`` directive should be ``RTEMS_PRIORITY``.
89
90Building an Option Set
91----------------------
92
93In general, an option is built by a bitwise OR of the desired option
94components.  The set of valid options for the ``rtems_region_get_segment``
95directive are listed in the following table:
96
97.. list-table::
98 :class: rtems-table
99
100 * - ``RTEMS_WAIT``
101   - task will wait for segment (default)
102 * - ``RTEMS_NO_WAIT``
103   - task should not wait
104
105Option values are specifically designed to be mutually exclusive, therefore
106bitwise OR and addition operations are equivalent as long as each option
107appears exactly once in the component list.  An option listed as a default is
108not required to appear in the option list, although it is a good programming
109practice to specify default options.  If all defaults are desired, the
110option ``RTEMS_DEFAULT_OPTIONS`` should be specified on this call.
111
112This example demonstrates the option parameter needed to poll for a segment.
113The option parameter passed to the ``rtems_region_get_segment`` directive
114should be ``RTEMS_NO_WAIT``.
115
116Operations
117==========
118
119Creating a Region
120-----------------
121
122The ``rtems_region_create`` directive creates a region with the user-defined
123name.  The user may select FIFO or task priority as the method for placing
124waiting tasks in the task wait queue.  RTEMS allocates a Region Control Block
125(RNCB) from the RNCB free list to maintain the newly created region.  RTEMS
126also generates a unique region ID which is returned to the calling task.
127
128It is not possible to calculate the exact number of bytes available to the user
129since RTEMS requires overhead for each segment allocated.  For example, a
130region with one segment that is the size of the entire region has more
131available bytes than a region with two segments that collectively are the size
132of the entire region.  This is because the region with one segment requires
133only the overhead for one segment, while the other region requires the overhead
134for two segments.
135
136Due to automatic coalescing, the number of segments in the region dynamically
137changes.  Therefore, the total overhead required by RTEMS dynamically changes.
138
139Obtaining Region IDs
140--------------------
141
142When a region is created, RTEMS generates a unique region ID and assigns it to
143the created region until it is deleted.  The region ID may be obtained by
144either of two methods.  First, as the result of an invocation of the
145``rtems_region_create`` directive, the region ID is stored in a user provided
146location.  Second, the region ID may be obtained later using the
147``rtems_region_ident`` directive.  The region ID is used by other region
148manager directives to access this region.
149
150Adding Memory to a Region
151-------------------------
152
153The ``rtems_region_extend`` directive may be used to add memory to an existing
154region.  The caller specifies the size in bytes and starting address of the
155memory being added.
156
157Acquiring a Segment
158-------------------
159
160The ``rtems_region_get_segment`` directive attempts to acquire a segment from a
161specified region.  If the region has enough available free memory, then a
162segment is returned successfully to the caller.  When the segment cannot be
163allocated, one of the following situations applies:
164
165- By default, the calling task will wait forever to acquire the segment.
166
167- Specifying the ``RTEMS_NO_WAIT`` option forces an immediate return with an
168  error status code.
169
170- Specifying a timeout limits the interval the task will wait before returning
171  with an error status code.
172
173If the task waits for the segment, then it is placed in the region's task wait
174queue in either FIFO or task priority order.  All tasks waiting on a region are
175returned an error when the message queue is deleted.
176
177Releasing a Segment
178-------------------
179
180When a segment is returned to a region by the ``rtems_region_return_segment``
181directive, it is merged with its unallocated neighbors to form the largest
182possible segment.  The first task on the wait queue is examined to determine if
183its segment request can now be satisfied.  If so, it is given a segment and
184unblocked.  This process is repeated until the first task's segment request
185cannot be satisfied.
186
187Obtaining the Size of a Segment
188-------------------------------
189
190The ``rtems_region_get_segment_size`` directive returns the size in bytes of
191the specified segment.  The size returned includes any "extra" memory included
192in the segment because of rounding up to a page size boundary.
193
194Changing the Size of a Segment
195------------------------------
196
197The ``rtems_region_resize_segment`` directive is used to change the size in
198bytes of the specified segment.  The size may be increased or decreased.  When
199increasing the size of a segment, it is possible that the request cannot be
200satisfied.  This directive provides functionality similar to the ``realloc()``
201function in the Standard C Library.
202
203Deleting a Region
204-----------------
205
206A region can be removed from the system and returned to RTEMS with the
207``rtems_region_delete`` directive.  When a region is deleted, its control block
208is returned to the RNCB free list.  A region with segments still allocated is
209not allowed to be deleted.  Any task attempting to do so will be returned an
210error.  As a result of this directive, all tasks blocked waiting to obtain a
211segment from the region will be readied and returned a status code which
212indicates that the region was deleted.
213
214Directives
215==========
216
217This section details the region manager's directives.  A subsection is
218dedicated to each of this manager's directives and describes the calling
219sequence, related constants, usage, and status codes.
220
221.. raw:: latex
222
223   \clearpage
224
225.. index:: create a region
226
227.. _rtems_region_create:
228
229REGION_CREATE - Create a region
230-------------------------------
231
232CALLING SEQUENCE:
233    .. code-block:: c
234
235        rtems_status_code rtems_region_create(
236          rtems_name       name,
237          void            *starting_address,
238          uintptr_t        length,
239          uintptr_t        page_size,
240          rtems_attribute  attribute_set,
241          rtems_id        *id
242        );
243
244DIRECTIVE STATUS CODES:
245    .. list-table::
246     :class: rtems-table
247
248     * - ``RTEMS_SUCCESSFUL``
249       - region created successfully
250     * - ``RTEMS_INVALID_NAME``
251       - invalid region name
252     * - ``RTEMS_INVALID_ADDRESS``
253       - ``id`` is NULL
254     * - ``RTEMS_INVALID_ADDRESS``
255       - ``starting_address`` is NULL
256     * - ``RTEMS_TOO_MANY``
257       - too many regions created
258     * - ``RTEMS_INVALID_SIZE``
259       - invalid page size
260     * - ``RTEMS_INVALID_SIZE``
261       - the memory area defined by the starting address and the length
262         parameters is too small
263
264DESCRIPTION:
265    This directive creates a region from a contiguous memory area
266    which starts at starting_address and is length bytes long.  The memory area
267    must be large enough to contain some internal region administration data.
268    Segments allocated from the region will be a multiple of page_size bytes in
269    length.  The specified page size will be aligned to an
270    architecture-specific minimum alignment if necessary.
271
272    The assigned region id is returned in id.  This region id is used as an
273    argument to other region related directives to access the region.
274
275    For control and maintenance of the region, RTEMS allocates and initializes
276    an RNCB from the RNCB free pool.  Thus memory from the region is not used
277    to store the RNCB.  However, some overhead within the region is required by
278    RTEMS each time a segment is constructed in the region.
279
280    Specifying ``RTEMS_PRIORITY`` in attribute_set causes tasks waiting for a
281    segment to be serviced according to task priority.  Specifying
282    ``RTEMS_FIFO`` in attribute_set or selecting ``RTEMS_DEFAULT_ATTRIBUTES``
283    will cause waiting tasks to be serviced in First In-First Out order.
284
285NOTES:
286    This directive will obtain the allocator mutex and may cause the calling
287    task to be preempted.
288
289    The following region attribute constants are defined by RTEMS:
290
291    .. list-table::
292     :class: rtems-table
293
294     * - ``RTEMS_FIFO``
295       - tasks wait by FIFO (default)
296     * - ``RTEMS_PRIORITY``
297       - tasks wait by priority
298
299.. raw:: latex
300
301   \clearpage
302
303.. index:: get ID of a region
304.. index:: obtain ID of a region
305.. index:: rtems_region_ident
306
307.. _rtems_region_ident:
308
309REGION_IDENT - Get ID of a region
310---------------------------------
311
312CALLING SEQUENCE:
313    .. code-block:: c
314
315        rtems_status_code rtems_region_ident(
316          rtems_name  name,
317          rtems_id   *id
318        );
319
320DIRECTIVE STATUS CODES:
321    .. list-table::
322     :class: rtems-table
323
324     * - ``RTEMS_SUCCESSFUL``
325       - region identified successfully
326     * - ``RTEMS_INVALID_ADDRESS``
327       - ``id`` is NULL
328     * - ``RTEMS_INVALID_NAME``
329       - region name not found
330
331DESCRIPTION:
332
333    This directive obtains the region id associated with the region name to be
334    acquired.  If the region name is not unique, then the region id will match
335    one of the regions with that name.  However, this region id is not
336    guaranteed to correspond to the desired region.  The region id is used to
337    access this region in other region manager directives.
338
339NOTES:
340    This directive will not cause the running task to be preempted.
341
342.. raw:: latex
343
344   \clearpage
345
346.. index:: delete a region
347.. index:: rtems_region_delete
348
349.. _rtems_region_delete:
350
351REGION_DELETE - Delete a region
352-------------------------------
353
354CALLING SEQUENCE:
355    .. code-block:: c
356
357        rtems_status_code rtems_region_delete(
358          rtems_id id
359        );
360
361DIRECTIVE STATUS CODES:
362    .. list-table::
363     :class: rtems-table
364
365     * - ``RTEMS_SUCCESSFUL``
366       - region deleted successfully
367     * - ``RTEMS_INVALID_ID``
368       - invalid region id
369     * - ``RTEMS_RESOURCE_IN_USE``
370       - segments still in use
371
372DESCRIPTION:
373    This directive deletes the region specified by id.  The region cannot be
374    deleted if any of its segments are still allocated.  The RNCB for the
375    deleted region is reclaimed by RTEMS.
376
377NOTES:
378    This directive will obtain the allocator mutex and may cause the calling
379    task to be preempted.
380
381    The calling task does not have to be the task that created the region.  Any
382    local task that knows the region id can delete the region.
383
384.. raw:: latex
385
386   \clearpage
387
388.. index:: add memory to a region
389.. index:: region, add memory
390.. index:: rtems_region_extend
391
392.. _rtems_region_extend:
393
394REGION_EXTEND - Add memory to a region
395--------------------------------------
396
397CALLING SEQUENCE:
398    .. code-block:: c
399
400        rtems_status_code rtems_region_extend(
401          rtems_id   id,
402          void      *starting_address,
403          uintptr_t  length
404        );
405
406DIRECTIVE STATUS CODES:
407    .. list-table::
408     :class: rtems-table
409
410     * - ``RTEMS_SUCCESSFUL``
411       - region extended successfully
412     * - ``RTEMS_INVALID_ADDRESS``
413       - ``starting_address`` is NULL
414     * - ``RTEMS_INVALID_ID``
415       - invalid region id
416     * - ``RTEMS_INVALID_ADDRESS``
417       - invalid address of area to add
418
419DESCRIPTION:
420    This directive adds the memory area which starts at
421    :c:data:`starting_address` for :c:data:`length` bytes to the region
422    specified by :c:data:`id`.
423
424    There are no alignment requirements for the memory area.  The memory area
425    must be big enough to contain some maintenance blocks.  It must not overlap
426    parts of the current heap memory areas.  Disconnected memory areas added to
427    the heap will lead to used blocks which cover the gaps.  Extending with an
428    inappropriate memory area will corrupt the heap resulting in undefined
429    behaviour.
430
431NOTES:
432    This directive will obtain the allocator mutex and may cause the calling
433    task to be preempted.
434
435    The calling task does not have to be the task that created the region.  Any
436    local task that knows the region identifier can extend the region.
437
438.. raw:: latex
439
440   \clearpage
441
442.. index:: get segment from region
443.. index:: rtems_region_get_segment
444
445.. _rtems_region_get_segment:
446
447REGION_GET_SEGMENT - Get segment from a region
448----------------------------------------------
449
450CALLING SEQUENCE:
451    .. code-block:: c
452
453        rtems_status_code rtems_region_get_segment(
454          rtems_id         id,
455          uintptr_t        size,
456          rtems_option     option_set,
457          rtems_interval   timeout,
458          void           **segment
459        );
460
461DIRECTIVE STATUS CODES:
462    .. list-table::
463     :class: rtems-table
464
465     * - ``RTEMS_SUCCESSFUL``
466       - segment obtained successfully
467     * - ``RTEMS_INVALID_ADDRESS``
468       - ``segment`` is NULL
469     * - ``RTEMS_INVALID_ID``
470       - invalid region id
471     * - ``RTEMS_INVALID_SIZE``
472       - request is for zero bytes or exceeds the size of maximum segment which is
473         possible for this region
474     * - ``RTEMS_UNSATISFIED``
475       - segment of requested size not available
476     * - ``RTEMS_TIMEOUT``
477       - timed out waiting for segment
478     * - ``RTEMS_OBJECT_WAS_DELETED``
479       - region deleted while waiting
480
481DESCRIPTION:
482    This directive obtains a variable size segment from the region specified by
483    ``id``.  The address of the allocated segment is returned in segment.  The
484    ``RTEMS_WAIT`` and ``RTEMS_NO_WAIT`` components of the options parameter
485    are used to specify whether the calling tasks wish to wait for a segment to
486    become available or return immediately if no segment is available.  For
487    either option, if a sufficiently sized segment is available, then the
488    segment is successfully acquired by returning immediately with the
489    ``RTEMS_SUCCESSFUL`` status code.
490
491    If the calling task chooses to return immediately and a segment large
492    enough is not available, then an error code indicating this fact is
493    returned.  If the calling task chooses to wait for the segment and a
494    segment large enough is not available, then the calling task is placed on
495    the region's segment wait queue and blocked.  If the region was created
496    with the ``RTEMS_PRIORITY`` option, then the calling task is inserted into
497    the wait queue according to its priority.  However, if the region was
498    created with the ``RTEMS_FIFO`` option, then the calling task is placed at
499    the rear of the wait queue.
500
501    The timeout parameter specifies the maximum interval that a task is willing
502    to wait to obtain a segment.  If timeout is set to ``RTEMS_NO_TIMEOUT``,
503    then the calling task will wait forever.
504
505NOTES:
506    This directive will obtain the allocator mutex and may cause the calling
507    task to be preempted.
508
509    The actual length of the allocated segment may be larger than the requested
510    size because a segment size is always a multiple of the region's page size.
511
512    The following segment acquisition option constants are defined by RTEMS:
513
514    .. list-table::
515     :class: rtems-table
516
517     * - ``RTEMS_WAIT``
518       - task will wait for segment (default)
519     * - ``RTEMS_NO_WAIT``
520       - task should not wait
521
522    A clock tick is required to support the timeout functionality of this
523    directive.
524
525.. raw:: latex
526
527   \clearpage
528
529.. index:: return segment to region
530.. index:: rtems_region_return_segment
531
532.. _rtems_region_return_segment:
533
534REGION_RETURN_SEGMENT - Return segment to a region
535--------------------------------------------------
536
537CALLING SEQUENCE:
538    .. code-block:: c
539
540        rtems_status_code rtems_region_return_segment(
541          rtems_id  id,
542          void     *segment
543        );
544
545DIRECTIVE STATUS CODES:
546    .. list-table::
547     :class: rtems-table
548
549     * - ``RTEMS_SUCCESSFUL``
550       - segment returned successfully
551     * - ``RTEMS_INVALID_ADDRESS``
552       - ``segment`` is NULL
553     * - ``RTEMS_INVALID_ID``
554       - invalid region id
555     * - ``RTEMS_INVALID_ADDRESS``
556       - segment address not in region
557
558DESCRIPTION:
559    This directive returns the segment specified by segment to the region
560    specified by id.  The returned segment is merged with its neighbors to form
561    the largest possible segment.  The first task on the wait queue is examined
562    to determine if its segment request can now be satisfied.  If so, it is
563    given a segment and unblocked.  This process is repeated until the first
564    task's segment request cannot be satisfied.
565
566NOTES:
567    This directive will cause the calling task to be preempted if one or more
568    local tasks are waiting for a segment and the following conditions exist:
569
570    - a waiting task has a higher priority than the calling task
571
572    - the size of the segment required by the waiting task is less than or
573      equal to the size of the segment returned.
574
575.. raw:: latex
576
577   \clearpage
578
579.. index:: get size of segment
580.. index:: rtems_region_get_segment_size
581
582.. _rtems_region_get_segment_size:
583
584REGION_GET_SEGMENT_SIZE - Obtain size of a segment
585--------------------------------------------------
586
587CALLING SEQUENCE:
588    .. code-block:: c
589
590        rtems_status_code rtems_region_get_segment_size(
591          rtems_id   id,
592          void      *segment,
593          uintptr_t *size
594        );
595
596DIRECTIVE STATUS CODES:
597    .. list-table::
598     :class: rtems-table
599
600     * - ``RTEMS_SUCCESSFUL``
601       - segment obtained successfully
602     * - ``RTEMS_INVALID_ADDRESS``
603       - ``segment`` is NULL
604     * - ``RTEMS_INVALID_ADDRESS``
605       - ``size`` is NULL
606     * - ``RTEMS_INVALID_ID``
607       - invalid region id
608     * - ``RTEMS_INVALID_ADDRESS``
609       - segment address not in region
610
611DESCRIPTION:
612    This directive obtains the size in bytes of the specified segment.
613
614NOTES:
615    The actual length of the allocated segment may be larger than the requested
616    size because a segment size is always a multiple of the region's page size.
617
618.. raw:: latex
619
620   \clearpage
621
622.. index:: resize segment
623.. index:: rtems_region_resize_segment
624
625.. _rtems_region_resize_segment:
626
627REGION_RESIZE_SEGMENT - Change size of a segment
628------------------------------------------------
629
630CALLING SEQUENCE:
631    .. code-block:: c
632
633        rtems_status_code rtems_region_resize_segment(
634          rtems_id   id,
635          void      *segment,
636          uintptr_t  new_size,
637          uintptr_t *old_size
638        );
639
640DIRECTIVE STATUS CODES:
641    .. list-table::
642     :class: rtems-table
643
644     * - ``RTEMS_SUCCESSFUL``
645       - segment obtained successfully
646     * - ``RTEMS_INVALID_ADDRESS``
647       - ``segment`` is NULL
648     * - ``RTEMS_INVALID_ADDRESS``
649       - ``old_size`` is NULL
650     * - ``RTEMS_INVALID_ID``
651       - invalid region id
652     * - ``RTEMS_INVALID_ADDRESS``
653       - segment address not in region
654     * - ``RTEMS_UNSATISFIED``
655       - unable to make segment larger
656
657DESCRIPTION:
658    This directive is used to increase or decrease the size of a segment.  When
659    increasing the size of a segment, it is possible that there is not memory
660    available contiguous to the segment.  In this case, the request is
661    unsatisfied.
662
663NOTES:
664    This directive will obtain the allocator mutex and may cause the calling
665    task to be preempted.
666
667    If an attempt to increase the size of a segment fails, then the application
668    may want to allocate a new segment of the desired size, copy the contents
669    of the original segment to the new, larger segment and then return the
670    original segment.
Note: See TracBrowser for help on using the repository browser.