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
|