source: rtems-docs/c-user/region_manager.rst @ 4de0da1

5
Last change on this file since 4de0da1 was b5d29c9, checked in by Sebastian Huber <sebastian.huber@…>, on 05/30/18 at 08:52:39

c-user: Update rtems_region_create()

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