Overview
Comment: | add memory functions |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
5393623a84cb48a17c52c45274ffa544 |
User & Date: | lexi on 2019-08-18 11:34:59 |
Other Links: | manifest | tags |
Context
2019-08-18
| ||
13:42 | add functions, generate C syscall table check-in: a8d93823f1 user: lexi tags: trunk | |
11:34 | add memory functions check-in: 5393623a84 user: lexi tags: trunk | |
10:20 | fix kmheapa() and add kmheapf() check-in: 5279674525 user: lexi tags: trunk | |
Changes
Modified kcore/testbin.exe.c from [8406c82300] to [a4a4905883].
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
maybe = no; if (kiosend(e.std, ptr, null) == kiocond_ok) { /* great, continue */ } else { return kbad_io; } struct object* block = kmheapa(sizeof (struct object) * 4); if (block == null) return kbad_mem; block[1].a = 5; if (kmheapf(block) != kmcond_ok) return kbad_mem; return kbad_ok; } |
> > | < > | | |
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
maybe = no; if (kiosend(e.std, ptr, null) == kiocond_ok) { /* great, continue */ } else { return kbad_io; } kmptr object = kmheapao(sizeof (struct object) * 16); if (object.kind == kmkind_fail) return kbad_mem; /* struct object* block = kmheapa(sizeof (struct object) * 4); */ struct object* block = object.ref; block[5].a = 5; if (kmfree(object) != kmcond_ok) return kbad_mem; return kbad_ok; } |
Modified kmem/heapa.fn.c from [aa6d2182a2] to [8818444ab8].
1 2 3 4 5 6 7 .. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 .. 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 62 63 |
#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() ................................................................................ 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. */ void* val; # 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 ................................................................................ /* 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.*/ sz const region_total = len + sizeof len; ubyte* const region = kmem_platform_mmap(null, region_total, 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 */ if (region == (void*) -1) return null; /* worth retrieving errno? discuss */ *((sz*)region) = len; val = region + sizeof len; # else Knoimpl(kmheapa,KVos); # error missing implementation # endif return val; } |
> > | > > > > > > < | | < < < | > > > > > | |
1 2 3 4 5 6 7 8 .. 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 .. 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#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() ................................................................................ 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 ................................................................................ /* 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 */ if (region.raw == (void*) -1) return null; /* worth retrieving errno? discuss */ # else Knoimpl(kmheapa,KVos); # error missing implementation # endif void* const object = (region.byte + sizeof (kmbox)); region.header -> kind = kmkind_heap; region.header -> size = len; return object; } |
Modified kmem/kmem.md from [5405a3e53e] to [73d0a96333].
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
kmem supplies two module-level functions, used to interact with the `kmptr` container type. * `kmfree(kmptr) → void` - free, downref, or ignore the pasted object as appropriate * `kmshred(kmptr) → void` - free, downref, or ignore the pasted object as appropriate. if deallocating, zero its contents * `kmstat(void*) → kmptr` - convenience function to wrap a pointer to a non-managed object in a `kmptr` struct, so it can be passed to functions that accept arbitrary objects. `kmptr p = kmstat(raw)` is equivalent to `kmptr p = { kmkind_none, raw, NULL }`. * `kmtaint(&kmptr) → void` - "taints" a `kmptr` object by setting it to be shredded when freed. this may be desirable if the object pointed to contains privileged information. ## types kmem defines the following types: * `enum kmkind` - enumerates allocation strategies * `struct kmptr` - abstract pointer object |
> > > > |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
kmem supplies two module-level functions, used to interact with the `kmptr` container type. * `kmfree(kmptr) → void` - free, downref, or ignore the pasted object as appropriate * `kmshred(kmptr) → void` - free, downref, or ignore the pasted object as appropriate. if deallocating, zero its contents * `kmstat(void*) → kmptr` - convenience function to wrap a pointer to a non-managed object in a `kmptr` struct, so it can be passed to functions that accept arbitrary objects. `kmptr p = kmstat(raw)` is equivalent to `kmptr p = { kmkind_none, raw, NULL }`. * `kmtaint(&kmptr) → void` - "taints" a `kmptr` object by setting it to be shredded when freed. this may be desirable if the object pointed to contains privileged information. * `kmzero(void*,sz) → void` - zeroes a region of memory * `kmozero(kmptr) → void` - zeroes an object in memory * `kmcopy(void* dest, void* src, sz) → void` - copies one region of memory to another * `kmdup(kmptr) → kmptr` - duplicates an object in memory, allocating it as sibling of the original ## types kmem defines the following types: * `enum kmkind` - enumerates allocation strategies * `struct kmptr` - abstract pointer object |
Modified kmem/mem.h from [09be45a2b3] to [bec7e80543].
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 |
#ifdef __cplusplus extern "C" { #endif typedef enum kmcond { kmcond_ok, kmcond_bad_address, } kmcond; typedef enum kmkind { kmkind_none, kmkind_heap, kmkind_pool, kmkind_ref, kmkind_tree } kmkind; typedef enum kmshred { kmshred_yes, kmshred_no } kmshred; typedef struct kmcell { kmkind kind; sz size; kmshred shred; sz refs; struct kmcell* src; } kmcell; typedef struct kmptr { kmkind kind; kmshred shred; void* ref; kmcell* cell; } kmptr; /* heap functions */ void* kmheapa(sz); kmcond kmheapf(void*); #ifdef __cplusplus } #endif #endif |
> > > > > > > | > > > > > > > > > > > > < > > > > > > > > > |
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
#ifdef __cplusplus extern "C" { #endif typedef enum kmcond { kmcond_ok, kmcond_unnecessary, kmcond_fail, kmcond_unhandled, kmcond_mismatch, kmcond_bad_address, } kmcond; typedef enum kmkind { kmkind_none, kmkind_fail, kmkind_linear, kmkind_heap, kmkind_pool, kmkind_ref, kmkind_tree } kmkind; typedef enum kmshred { kmshred_yes, kmshred_no } kmshred; typedef struct kmbox { kmkind kind; sz size; kmshred shred; } kmbox; typedef struct kmcell { kmbox header; sz refs; struct kmcell* src; } kmcell; typedef struct kmnode { kmbox header; struct kmnode* origin, * branch, * next, * prev; } kmnode; typedef struct kmptr { kmkind kind; kmshred shred; void* ref; } kmptr; /* heap functions */ void* kmheapa(sz); kmptr kmheapao(sz); kmcond kmheapf(void*); /* generic functions */ kmcond kmfree(kmptr); kmkind kmtell(void*); void kmzero(void*,sz); void kmozero(kmptr); #ifdef __cplusplus } #endif #endif |