source: rtems-docs/c_user/region_manager.rst @ d389819

4.115
Last change on this file since d389819 was d389819, checked in by Amar Takhar <amar@…>, on 01/18/16 at 05:37:40

Convert all Unicode to ASCII(128)

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