xref: /kvm-unit-tests/lib/alloc.c (revision 4363f1d9a646a5c7ea673bee8fc33ca6f2cddbd8)
1 #include "alloc.h"
2 
3 void *malloc(size_t size)
4 {
5 	return memalign(sizeof(long), size);
6 }
7 
8 void *calloc(size_t nmemb, size_t size)
9 {
10 	void *ptr = malloc(nmemb * size);
11 	if (ptr)
12 		memset(ptr, 0, nmemb * size);
13 	return ptr;
14 }
15 
16 #define METADATA_EXTRA	(2 * sizeof(uintptr_t))
17 #define OFS_SLACK	(-2 * sizeof(uintptr_t))
18 #define OFS_SIZE	(-sizeof(uintptr_t))
19 
20 static inline void *block_begin(void *mem)
21 {
22 	uintptr_t slack = *(uintptr_t *)(mem + OFS_SLACK);
23 	return mem - slack;
24 }
25 
26 static inline uintptr_t block_size(void *mem)
27 {
28 	return *(uintptr_t *)(mem + OFS_SIZE);
29 }
30 
31 void free(void *ptr)
32 {
33 	if (!alloc_ops->free)
34 		return;
35 
36 	void *base = block_begin(ptr);
37 	uintptr_t sz = block_size(ptr);
38 
39 	alloc_ops->free(base, sz);
40 }
41 
42 void *memalign(size_t alignment, size_t size)
43 {
44 	void *p;
45 	uintptr_t blkalign;
46 	uintptr_t mem;
47 
48 	assert(alloc_ops && alloc_ops->memalign);
49 	if (alignment <= sizeof(uintptr_t))
50 		alignment = sizeof(uintptr_t);
51 	else
52 		size += alignment - 1;
53 
54 	blkalign = MAX(alignment, alloc_ops->align_min);
55 	size = ALIGN(size + METADATA_EXTRA, alloc_ops->align_min);
56 	p = alloc_ops->memalign(blkalign, size);
57 
58 	/* Leave room for metadata before aligning the result.  */
59 	mem = (uintptr_t)p + METADATA_EXTRA;
60 	mem = ALIGN(mem, alignment);
61 
62 	/* Write the metadata */
63 	*(uintptr_t *)(mem + OFS_SLACK) = mem - (uintptr_t)p;
64 	*(uintptr_t *)(mem + OFS_SIZE) = size;
65 	return (void *)mem;
66 }
67