#ifndef _KMALLOC_H #define _KMALLOC_H #include "types.h" // This function allocates size bytes of contiguous memory. // Returns a pointer to allocated memory or NULL. void* kmalloc(size_t size); // This function allocates size bytes of contiguous, zeroed-out memory. // Returns a pointer to allocated memory or NULL. void* kzalloc(size_t size); // This function allocates memory for count elements each of size bytes, // zeroed-out memory. Returns a pointer to allocated memory or NULL. void* kcalloc(size_t count, size_t size); // 9 bytes in 8 bytes #define TAG_SHIFT 56 #define TAG_MASK ((uintptr_t)0xFF << TAG_SHIFT) #define SIGN_BIT ((uintptr_t)1 << 55) typedef struct { uintptr_t bits; } tagged_ptr; static inline tagged_ptr tp_make(void* p, uint8_t tag) { uintptr_t addr = (uintptr_t)p & ~TAG_MASK; return (tagged_ptr){addr | ((uintptr_t)tag << TAG_SHIFT)}; } static inline uint8_t tp_tag(tagged_ptr t) { return (uint8_t)(t.bits >> TAG_SHIFT); } static inline void* tp_ptr(tagged_ptr t) { /* Bits 48..55 were untouched and still equal the canonical sign. Copy bit 55 into bits 56..63. */ uintptr_t addr = (t.bits & SIGN_BIT) ? (t.bits | TAG_MASK) : (t.bits & ~TAG_MASK); return (void*)addr; } // powers of 2 #define KMALLOC_MAX_SIZE 17 #define LOWEST_POWER 3 struct freelist { struct freelist* nextnode; }; struct partialy_freelist { struct freelist* freelist_nextnode; struct partialy_freelist* partialy_freelist_nextnode; }; // this is used when object is too small to hold the big one in this case we use // first object as pointer storage and dont allocate it struct partialy_freelist_short { struct partialy_freelist_short* partialy_freelist_nextnode; }; union freelists_list { struct freelist* freelists[KMALLOC_MAX_SIZE]; struct { struct freelist* kmalloc_8; struct freelist* kmalloc_16; struct freelist* kmalloc_32; struct freelist* kmalloc_64; struct freelist* kmalloc_128; struct freelist* kmalloc_256; struct freelist* kmalloc_512; struct freelist* kmalloc_1024; struct freelist* kmalloc_2048; struct freelist* kmalloc_4096; struct freelist* kmalloc_8192; struct freelist* kmalloc_16384; struct freelist* kmalloc_32768; struct freelist* kmalloc_65536; struct freelist* kmalloc_131072; }; }; union partialy_freelists_list { struct partialy_freelist* partialy_freelists[KMALLOC_MAX_SIZE]; struct { struct partialy_freelist* kmalloc_8; struct partialy_freelist* kmalloc_16; struct partialy_freelist* kmalloc_32; struct partialy_freelist* kmalloc_64; struct partialy_freelist* kmalloc_128; struct partialy_freelist* kmalloc_256; struct partialy_freelist* kmalloc_512; struct partialy_freelist* kmalloc_1024; struct partialy_freelist* kmalloc_2048; struct partialy_freelist* kmalloc_4096; struct partialy_freelist* kmalloc_8192; struct partialy_freelist* kmalloc_16384; struct partialy_freelist* kmalloc_32768; struct partialy_freelist* kmalloc_65536; struct partialy_freelist* kmalloc_131072; }; }; #endif