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