xref: /kvm-unit-tests/lib/alloc.c (revision 2c96b77ec9d3b1fcec7525174e23a6240ee05949)
1 #include "alloc.h"
2 #include "asm/page.h"
3 #include "bitops.h"
4 
5 void *malloc(size_t size)
6 {
7 	return memalign(sizeof(long), size);
8 }
9 
10 static bool mult_overflow(size_t a, size_t b)
11 {
12 #if BITS_PER_LONG == 32
13 	/* 32 bit system, easy case: just use u64 */
14 	return (u64)a * (u64)b >= (1ULL << 32);
15 #else
16 #ifdef __SIZEOF_INT128__
17 	/* if __int128 is available use it (like the u64 case above) */
18 	unsigned __int128 res = a;
19 	res *= b;
20 	res >>= 64;
21 	return res != 0;
22 #else
23 	u64 tmp;
24 
25 	if ((a >> 32) && (b >> 32))
26 		return true;
27 	if (!(a >> 32) && !(b >> 32))
28 		return false;
29 	tmp = (u32)a;
30 	tmp *= (u32)b;
31 	tmp >>= 32;
32 	if (a < b)
33 		tmp += a * (b >> 32);
34 	else
35 		tmp += b * (a >> 32);
36 	return tmp >> 32;
37 #endif /* __SIZEOF_INT128__ */
38 #endif /* BITS_PER_LONG == 32 */
39 }
40 
41 void *calloc(size_t nmemb, size_t size)
42 {
43 	void *ptr;
44 
45 	assert(!mult_overflow(nmemb, size));
46 	ptr = malloc(nmemb * size);
47 	if (ptr)
48 		memset(ptr, 0, nmemb * size);
49 	return ptr;
50 }
51 
52 void free(void *ptr)
53 {
54 	if (alloc_ops->free)
55 		alloc_ops->free(ptr);
56 }
57 
58 void *memalign(size_t alignment, size_t size)
59 {
60 	void *p;
61 
62 	if (!size)
63 		return NULL;
64 
65 	assert(is_power_of_2(alignment));
66 	assert(alloc_ops && alloc_ops->memalign);
67 
68 	p = alloc_ops->memalign(alignment, size);
69 	assert(p);
70 
71 	return (void *)p;
72 }
73