Differences From
Artifact [aa6d2182a2]:
1 +#include <k/mem.h>
1 2 #include <k/core.h>
2 3 #include <k/def.h>
3 4 #include <k/type.h>
4 5 #include <posix.h>
5 6 /* heapa.c - kmheapa() "heap alloc"
6 7 * ~ lexi hale <lexi@hale.su>
7 8 * kmheapa() allocates a pointer on the heap à la libc malloc()
................................................................................
16 17 extern void* kmem_platform_mmap(void* addr,
17 18 unsigned long sz, unsigned long prot, unsigned long flags,
18 19 unsigned long fd, unsigned long off);
19 20
20 21 void* kmheapa(sz len) {
21 22 /* allocate an object on the heap and return
22 23 * a pointer, or NULL if the allocation failed. */
23 - void* val;
24 + union {
25 + void* raw;
26 + ubyte* byte;
27 + kmbox* header;
28 + } region;
29 + /* we need to allocate space for the header and
30 + * for the actual object */
31 + sz region_size = sizeof(kmbox) + len;
24 32
25 33 # ifdef KFenv_posix
26 34 /* posix APIs - we've got it easy. currently for nonlinear
27 35 * heap allocation kmheapa simply uses m(un)map and lets the
28 36 * kernel worry about it. it may ultimately be worth replacing
29 37 * this with a more sophisticated implementation, most likely
30 38 * an existing allocator like jemalloc, though i'm wary of
................................................................................
36 44 /* because munmap needs to be informed of the size of
37 45 * the region it is going to unmap, we need to store
38 46 * that information in the allocated region itself.
39 47 * the user will be given a pointer that can be
40 48 * adjusted to point a field of type size_t that
41 49 * contains the size of the allocate space.*/
42 50
43 - sz const region_total = len + sizeof len;
44 - ubyte* const region = kmem_platform_mmap(null, region_total,
51 + region.byte = kmem_platform_mmap(null, region_size,
45 52 posix_prot_read | posix_prot_write,
46 53 posix_flag_anonymous | posix_map_shared, -1, 0);
47 54 /* impl note: while per manpage fd is "ignored"
48 55 * for MAP_ANONYMOUS, "some implementations" require
49 56 * a value of -1 */
50 57
51 - if (region == (void*) -1) return null;
58 + if (region.raw == (void*) -1) return null;
52 59 /* worth retrieving errno? discuss */
53 60
54 - *((sz*)region) = len;
55 - val = region + sizeof len;
56 -
57 61 # else
58 62 Knoimpl(kmheapa,KVos);
59 63 # error missing implementation
60 64 # endif
65 +
66 + void* const object = (region.byte + sizeof (kmbox));
67 +
68 + region.header -> kind = kmkind_heap;
69 + region.header -> size = len;
61 70
62 - return val;
71 + return object;
63 72 }