1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
#include <k/mem.h>
#include <k/core.h>
#include <k/def.h>
#include <k/type.h>
#include <posix.h>
/* heapa.c - kmheapa() "heap alloc"
* ~ lexi hale <lexi@hale.su>
* kmheapa() allocates a pointer on the heap à la libc malloc()
* see also: kmheapf() "heap free"
*/
/* we define all platform functions here,
* whether or not they're for the correct
* platform - only the ones actually called
* by the generated code will be linked,
* linker errors are our friend here! */
extern void* kmem_platform_mmap(void* addr,
unsigned long sz, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long off);
void* kmheapa(sz len) {
/* allocate an object on the heap and return
* a pointer, or NULL if the allocation failed. */
union {
void* raw;
ubyte* byte;
kmbox* header;
} region;
/* we need to allocate space for the header and
* for the actual object */
sz region_size = sizeof(kmbox) + len;
# ifdef KFenv_posix
/* posix APIs - we've got it easy. currently for nonlinear
* heap allocation kmheapa simply uses m(un)map and lets the
* kernel worry about it. it may ultimately be worth replacing
* this with a more sophisticated implementation, most likely
* an existing allocator like jemalloc, though i'm wary of
* including outside code - it creates a licensing mess and
* i'd prefer libk to be AGPLv3 across the board. possibility:
* include hooks for multiple allocators, allowing the user
* to select & link in her preferred allocator at compile time? */
/* because munmap needs to be informed of the size of
* the region it is going to unmap, we need to store
* that information in the allocated region itself.
* the user will be given a pointer that can be
* adjusted to point a field of type size_t that
* contains the size of the allocate space.*/
region.byte = kmem_platform_mmap(null, region_size,
posix_prot_read | posix_prot_write,
posix_flag_anonymous | posix_map_shared, -1, 0);
/* impl note: while per manpage fd is "ignored"
* for MAP_ANONYMOUS, "some implementations" require
* a value of -1 */
|
<
>
>
>
>
>
|
<
|
<
>
|
|
|
|
|
|
|
>
|
|
<
>
>
|
|
|
|
<
>
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#include <k/mem.h>
#include <k/core.h>
#include <k/def.h>
#include <k/type.h>
/* heapa.c - kmheapa() "heap alloc"
* ~ lexi hale <lexi@hale.su>
* kmheapa() allocates a pointer on the heap à la libc malloc()
* see also: kmheapf() "heap free"
*/
/* arch specific headers */
#ifdef KFenv_posix
# include <posix/posix.h>
#endif
/* we define all our platform functions here, whether or not
* they're for the correct platform - only the ones that are
* called by the preprocessed form of the code will actually
* be linked, linker errors are our friend here! */
extern void* kmem_platform_mmap(void* addr,
unsigned long sz, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long off);
void* kmheapa(sz len) {
/* allocate an object on the heap and return
* a pointer, or NULL if the allocation failed. */
union {
void* raw;
ubyte* byte;
kmbox* header;
} region;
/* we need to allocate space for the
* header and for the actual object */
sz region_size = sizeof(kmbox) + len;
# ifdef KFenv_posix
/* posix APIs - we've got it easy. currently for
* nonlinear heap allocation kmheapa simply uses
* m(un)map and lets the kernel worry about it. it
* may ultimately be worth replacing this with a
* more sophisticated implementation, most likely an
* existing allocator like jemalloc, though i'm wary
* of including outside code - it creates a licensing
* mess and i'd prefer libk to be AGPLv3 across the
* board. possibility: include hooks for multiple
* allocators, allowing the user to select & link in
* her preferred allocator at compile time? */
/* because munmap needs to be informed of the size of
* the region we are going to unmap, we need to store
* that information in the region that we are mapping.
* the user will receive an adjusted pointer that can
* be adjusted to point a field of type size_t that
* contains the size of the allocated space.*/
region.byte = kmem_platform_mmap(null, region_size,
posix_prot_read | posix_prot_write,
posix_flag_anonymous | posix_map_shared, -1, 0);
/* impl note: while per manpage fd is "ignored"
* for MAP_ANONYMOUS, "some implementations" require
* a value of -1 */
|