void* Buddy_Alloc(Buddy_Heap* h, size_t size, int zeroFill) { register int j, k; Buddy_FreeListNode *L, *R; int* p; if (size +sizeof(Buddy_FreeListNode) > (1<<h->M)) return NULL; j= k= Roundup(Max(size +sizeof(L->size), sizeof(Buddy_FreeListNode))); /* find k with 2^(k-1) < size <= 2^k */ cli(); /* b'cause freeList[] etc are shard vars !!! */ while ((j <=h->M) && (h->freeList[j].forward == &h->freeList[j])) /* R1: {find free block} */ j++; if (j <=h->M) { /* R2: remove block (i.e. first list entry) from freeList */ L= h->freeList[j].forward; h->freeList[j].forward= L->forward; L->forward->backward= (Buddy_FreeListNode*)&h->freeList[j]; L->size= k; /* tag block as reserved */ while (j != k) { /* R3: split required ? */ j--; /* R4: yes, split ! */ R= (void*)L +(1<<j); R->size= -j; /* mark block as free with its negative size */ R->forward= R->backward= (Buddy_FreeListNode*)&h->freeList[j]; /* insert free block with size j in freeList */ h->freeList[j].forward= h->freeList[j].backward = R; } //RTK_RestoreIntsEnable; if (zeroFill) { /* initialize block with zeros */ p= ((int*)L) +sizeof(L->size); for (j= 0; j <size; j++) *p++= 0; } return ((void*)L) +sizeof(L->size); /* available block starts at (L+1) */ } else { /* no available block with size k */ //RTK_RestoreIntsEnable; return 0; /* signal out of heap space */ } }
/* * Figure out how much real memory is available. * Start looking from the megabyte after the end of the kernel data, * until we find non-memory. */ vaddr_t size_memory() { unsigned int *volatile look; unsigned int *max; #if 0 extern char *end; #endif #define PATTERN 0x5a5a5a5a #define STRIDE (4*1024) /* 4k at a time */ #define Roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1)) /* * count it up. */ max = (void *)MAXPHYSMEM; #if 0 for (look = (void *)Roundup(end, STRIDE); look < max; #else for (look = (void *)first_addr; look < max; #endif look = (int *)((unsigned)look + STRIDE)) { unsigned save; /* if can't access, we've reached the end */ if (badwordaddr((vaddr_t)look)) { #if defined(DEBUG) printf("%x\n", look); #endif look = (int *)((int)look - STRIDE); break; } /* * If we write a value, we expect to read the same value back. * We'll do this twice, the 2nd time with the opposite bit * pattern from the first, to make sure we check all bits. */ save = *look; if (*look = PATTERN, *look != PATTERN) break; if (*look = ~PATTERN, *look != ~PATTERN) break; *look = save; } return (trunc_page((unsigned)look)); }