libk  Check-in [5393623a84]

Overview
Comment:add memory functions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5393623a84cb48a17c52c45274ffa54432a3f2968907a138236dd43c6bfe92c1
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