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