Next: , Up: objects memory   [Index]


13.3.1 System memory pages and Vicare memory pages

In this section we discuss some private C preprocessor symbols related to memory allocation and garbage collection concepts.

The preprocessor constant IK_MMAP_ALLOCATION_GRANULARITY is determined by the GNU Autotools’s configure script and defined in the automatically generated header file config.h. The constants IK_PAGESIZE and IK_PAGESHIFT are hard–coded.

The constant IK_MMAP_ALLOCATION_GRANULARITY represents the memory allocation granularity used by mmap(): no matter the number of bytes we request to mmap(), it will always allocate the smallest multiple of the granularity that can contain the requested bytes:

|----------------------------| requested_size
|-----------|-----------|-----------| allocated_size
 granularity granularity granularity

On some platforms the allocation granularity equals the system page size (example GNU+Linux), on other platforms it does not (example Cygwin). We assume the allocation granularity can be obtained on any platform with:

#include <unistd.h>
long granularity = sysconf(_SC_PAGESIZE);

which should “officially” return the system page size, but in truth it does not (see Cygwin’s documentation).

To mind its own business, Vicare defines a “page size” as the preprocessor symbol IK_PAGESIZE, the number of bytes in Vicare’s page size is:

4096 = 4 * 1024 = 4 * 2^10 = 2^12 = #x1000 = #b1000000000000

notice how many bits are set to zero in the binary representation of 4096:

(number->string 4096 2) ⇒ #b1000000000000
;;                           2109876543210

the constant 4096 is used often in the code, so the preprocessor symbol IK_CHUNK_SIZE is also defined to it.

Vicare’s page size is not defined to be equal to the system page size, but:

It is natural to assign a zero–based index to each Vicare page:

   page     page     page     page     page     page
|--------|--------|--------|--------|--------|--------|
 ^        ^        ^        ^        ^        ^
#x0000   #x1000   #x2000   #x3000   #x4000   #x5000
index 0  index 1  index 2  index 3  index 4  index 5

The preprocessor symbol IK_PAGESHIFT is the number of bits to right–shift a tagged or untagged pointer to obtain the index of the page it is in; it is the number for which:

IK_PAGESIZE >> IK_PAGESHIFT = 1
2^IK_PAGESHIFT = IK_PAGESIZE

if IK_PAGESIZE is 4096, the value of IK_PAGESHIFT is 12; so for the example sizes 4000, 8000 and 10000 we have:

0 * 4096 <=  4000 < 1 * 4096        4000 >> 12 = 0
1 * 4096 <=  8000 < 2 * 4096        8000 >> 12 = 1
2 * 4096 <= 10000 < 3 * 4096       10000 >> 12 = 2

all the tagged pointers hold the tag in the 3 least significant bits, so right–shifting by IK_PAGESHIFT removes the tag: right–shifting by IK_PAGESHIFT works fine on both tagged and untagged pointers.

C Preprocessor Macro: ikuword_t IK_PAGE_INDEX (ikptr_t X)

Given the tagged or untagged pointer X: evaluate to the index of the memory page it is in; notice that the tag bits of a tagged pointer are not influent.

C Preprocessor Macro: ikuword_t IK_PAGE_INDEX_RANGE (ikuword_t size)

Given a number of bytes size: evaluate to the difference between two page indexes representing a region big enough to hold size bytes.

C Preprocessor Macro: ikptr_t IK_PAGE_POINTER_FROM_INDEX (ikuword_t idx)

Given a Vicare page index idx: return an untagged pointer to the first word of the page.

C Preprocessor Macro: ikuword_t IK_MMAP_ALLOCATION_SIZE (ikuword_t size)

Given a memory size in bytes: compute the smallest number of bytes mmap() will allocate to hold it.

C Preprocessor Macro: ikuword_t IK_MINIMUM_PAGES_NUMBER_FOR_SIZE (ikuword_t size)

Given a memory size in bytes: compute the smallest number of pages of size IK_PAGESIZE needed to hold it.

C Preprocessor Macro: ikuword_t IK_MMAP_ALLOCATION_SIZE_FOR_PAGES (ikuword_t npages)

Given a number of Vicare pages: return the number of bytes mmap() allocates to hold them.

C Preprocessor Macro: ikuword_t IK_ALIGN_TO_NEXT_PAGE (ikuword_t X)

Given a pointer or tagged pointer X: return an untagged pointer referencing the first byte in the page right after the one X belongs to.

   page     page     page
|--------|--------|--------|
               ^   ^
               X   |
                  returned_value
C Preprocessor Macro: ikuword_t IK_ALIGN_TO_PREV_PAGE (ikuword_t X)

Given a pointer or tagged pointer X: return an untagged pointer referencing the first byte in the page X belongs to.

   page     page     page
|--------|--------|--------|
          ^    ^
          |    X
 returned_value

Next: , Up: objects memory   [Index]