source: rtems-docs/c-user/region_manager.rst @ 4886d60

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

Use standard format for copyright lines

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