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
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#include <error_table.h>
/* 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! */
kmcond kmheapa(void** where, 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
................................................................................
* a value of -1 */
struct k_platform_syscall_answer r = k_platform_syscall
(k_platform_syscall_mmap, Kmsz(args), args);
if (r.error == 0) region.byte = (ubyte*)r.ret; else {
switch (r.error) {
case k_platform_error_EAGAIN: return kmcond_bad_lock;
case k_platform_error_EINVAL: return kmcond_bad_size;
case k_platform_error_EMFILE: return kmcond_too_many;
case k_platform_error_ENOMEM: return kmcond_no_room;
default: return kmcond_fail_assert;
}
}
# else
Knoimpl(kmheapa,KVos);
# error missing implementation
# endif
void* const object = (region.byte + sizeof (kmbox));
region.header -> kind = kmkind_heap;
region.header -> size = len;
*where = object;
return kmcond_ok;
}
|
|
>
|
|
|
|
|
>
>
>
|
>
|
|
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
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#include <error_table.h>
/* 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! */
kmres 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;
kmres reply;
# 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
................................................................................
* a value of -1 */
struct k_platform_syscall_answer r = k_platform_syscall
(k_platform_syscall_mmap, Kmsz(args), args);
if (r.error == 0) region.byte = (ubyte*)r.ret; else {
switch (r.error) {
case k_platform_error_EAGAIN: reply.cond = kmcond_bad_lock; break;
case k_platform_error_EINVAL: reply.cond = kmcond_bad_size; break;
case k_platform_error_EMFILE: reply.cond = kmcond_too_many; break;
case k_platform_error_ENOMEM: reply.cond = kmcond_no_room; break;
default: reply.cond = kmcond_fail_assert;
}
reply.raw = (void*)0;
return reply;
}
# else
Knoimpl(kmheapa,KVos);
# error missing implementation
# endif
void* const object = (region.byte + sizeof (kmbox));
region.header -> kind = kmkind_heap;
region.header -> size = len;
reply.cond = kmcond_ok;
reply.raw = object;
return reply;
}
|