Data Fields | |
offset_t | map_length |
offset_t | length_used |
*********************************** ** structure of a shared memory ** *********************************** Mapping 0 is special in that it will always exist so long as the arena file object exists. Mapping 0 is the first mapping. It has a read-write lock that is write-locked any time the a segment boundary moves in any mapping, was shown as ----- lines below. The mapping details for the first mapping are in the struct mapping_header in map_header. The second mapping details are in the struct mapping_header below the struct arena_header in the first mapping. The details of all subsequent mapping are in the top of the previous mappings. All padding is to bring the data to a CHUNK boundary. Padding may be from 0 to CHUNK-1 bytes with an exception for the name string in allocated segments. mapping 0 ---------------------------- | struct arena_header | <-- how to map first mapping | padding | and info about arena ---------------------------- | struct mapping_header | <-- how to map mapping 1 | padding | if it's there ---------------------------- | 1st segment | ---------------------------- | 2nd segment | ---------------------------- | . | | . | | . | ---------------------------- | last segment | ---------------------------- mapping 1 ---------------------------- | struct mapping_header | <-- how to map mapping 2 | padding | if it's there ---------------------------- | 1st segment | ---------------------------- | 2nd segment | ---------------------------- | . | | . | | . | ---------------------------- | last segment | ---------------------------- . . . mapping (num_mappings - 1) ---------------------------- | struct mapping_header | <-- how to map mapping | padding | in the future ---------------------------- | 1st segment | ---------------------------- | 2nd segment | ---------------------------- | . | | . | | . | ---------------------------- | last segment | ---------------------------- All other mappings look the same as mapping 0. The struct mapping_header in each mapping gives mapping information for the next mapping, so it will be zeros if there is none. The first mapping will never be unmapped, or remapped, for a given arena object in a given process. The mappings are kept the same length in all objects in all processes. Segments are nodes in an AVL binary tree. The AVL meta data is in the struct seg_header in the segment. *********************************** ** What's a segment look like ? ** *********************************** A free segment --------------------------------- | struct seg_header | | padding | -- -- | 0 or more bytes free memory | | padding | -- -- | struct seg_footer | | padding | --------------------------------- The AVL key for a free node entry is the segment size, then mapping number, and lastly offset to the top of the segment. Consequently when seaching for a free node a process may go back and forth accessing different memory mappings. Is there a better way? An allocated segment --------------------------------- | struct seg_header | | padding | -- -- | user data 0 or more bytes | | padding | -- -- | if(flags & WITH_RWLOCK) | | | | pthread_rwlock_t | | padding | -- -- | name string | | padding * | -- -- | struct seg_footer | | padding | --------------------------------- The AVL key for a allocated segment node is the name string, which is unique to a particular allocated segment. The existence of the pthread_rwlock_t depends on the WITH_RWLOCK bit in seg_footer->flags. * The name string padding may be longer than what is needed to pad the name string to the nearest CHUNK boundary, but user data padding will always be padded to the nearest CHUNK boundary. Any extra padding will be in the name string part. Extra padding may be needed to use up memory address space that was not big enough to make a free segment. If the user data has a size of zero the user data part will have size 0.
at the top of every mapping in all processes, except the first mapping which has struct arena_header before this.
offset_t mapping_header::length_used |
length of mapping that is used in measured in units of CHUNK bytes
So the length used in bytes is
length_used * CHUNK *
Definition at line 352 of file arena.h.
Referenced by shm_arena_create(), shm_arena_print(), shm_arena_print_list(), and shm_remove().
offset_t mapping_header::map_length |
mapping length in units of CHUNK bytes
We are assuming that getpagesize() is evenly divisible by CHUNK bytes. This is tested in configure. The last mapping may be longer than the sum of all other mappings minus the file length. The file is extended and shrunk with ftruncate(), but mappings stay fixed while they are mapped.
Definition at line 345 of file arena.h.
Referenced by shm_arena_create(), and shm_arena_print().