blob: f4266f5d064e88ed02e5f579e59080596bb2200a [file] [log] [blame]
#include "alloc.h"
#include "asm/page.h"
#include "bitops.h"
void *malloc(size_t size)
{
return memalign(sizeof(long), size);
}
static bool mult_overflow(size_t a, size_t b)
{
#if BITS_PER_LONG == 32
/* 32 bit system, easy case: just use u64 */
return (u64)a * (u64)b >= (1ULL << 32);
#else
#ifdef __SIZEOF_INT128__
/* if __int128 is available use it (like the u64 case above) */
unsigned __int128 res = a;
res *= b;
res >>= 64;
return res != 0;
#else
u64 tmp;
if ((a >> 32) && (b >> 32))
return true;
if (!(a >> 32) && !(b >> 32))
return false;
tmp = (u32)a;
tmp *= (u32)b;
tmp >>= 32;
if (a < b)
tmp += a * (b >> 32);
else
tmp += b * (a >> 32);
return tmp >> 32;
#endif /* __SIZEOF_INT128__ */
#endif /* BITS_PER_LONG == 32 */
}
void *calloc(size_t nmemb, size_t size)
{
void *ptr;
assert(!mult_overflow(nmemb, size));
ptr = malloc(nmemb * size);
if (ptr)
memset(ptr, 0, nmemb * size);
return ptr;
}
void free(void *ptr)
{
if (alloc_ops->free)
alloc_ops->free(ptr);
}
void *memalign(size_t alignment, size_t size)
{
void *p;
if (!size)
return NULL;
assert(is_power_of_2(alignment));
assert(alloc_ops && alloc_ops->memalign);
p = alloc_ops->memalign(alignment, size);
assert(p);
return (void *)p;
}