/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */ void dmm_free (USHORT *Base, USHORT p) { USHORT previous= 0; /* pointer to previous pointer */ p --; // Base[0] is num of alloc'ed blocks while ((Base[previous] != 0) && (Base[previous] < p)) previous= Base[previous]+1; Base[p+1] = Base[previous]; Base[previous]= p; check_merge (Base, p); check_merge (Base, previous-1); }
static void check_merge(buddy_t* pb, size_t n) { if (n > MEM_SIZ_512) { return; } node_t** ppn = &pb->node[n]; while (*ppn) { node_t* next = (*ppn)->next; if (next) { size_t addr1 = (size_t)(*ppn)->addr; size_t addr2 = (size_t)next->addr; if ((addr1 + mem_size[n] == addr2) && ((*ppn)->stat == MEM_FREE) && (next->stat == MEM_FREE) && (addr1 % mem_size[n + 1] == 0) ) { node_t* nxt = next->next; free((*ppn)->next); node_t** ppn2 = &pb->node[n + 1]; while (*ppn2) { if ((*ppn2)->addr > (*ppn)->addr) { (*ppn)->next = *ppn2; (*ppn2) = *ppn; break; } ppn2 = &(*ppn2)->next; } if (!(*ppn2)) { *ppn2 = *ppn; (*ppn2)->next = NULL; *ppn = NULL; } *ppn = nxt; } else { ppn = &(*ppn)->next; } } else { break; } } check_merge(pb, n + 1); }
void buddy_free(buddy_t* pb, void* addr) { for (int i = 0;i < 7;i++) { node_t** ppn = &pb->node[i]; while (*ppn) { if ((*ppn)->addr == addr) { (*ppn)->stat = MEM_FREE; check_merge(pb, i); return; } ppn = &(*ppn)->next; } } fprintf(stderr, "buddy_free error, invalid address: %0#8x\n", (size_t)addr); }