/** * Deallocs a ListPtr and any nodes it contains. * @param L ListPtr to Dealloc */ void freeList(ListPtr L) { if(L==NULL) return; if(L->size == 0) buddy_free(L); else { NodePtr currentNode = L->head; while(currentNode != NULL){ NodePtr temp = currentNode; currentNode = currentNode->next; freeNode(temp); } buddy_free(L); } }
int main() { struct Node * tempNode1, *tempNode2, *tempNode3; int size = 10; struct HeadNode * tempHead = buddy_new(size); if (tempHead!=NULL) { //注意申请的空间最大不是2^k, 而是2^k - 1 tempNode1 = buddy_alloc(tempHead,size,511); buddy_print(tempHead, size); tempNode2 = buddy_alloc(tempHead,size,10); buddy_print(tempHead, size); tempNode3 = buddy_alloc(tempHead,size,10); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode3); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode2); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode1); buddy_print(tempHead, size); } buddy_free(tempHead); getchar(); return 0; }
/** * Parses a free instruction * * @param cmd String representing an allocation command in the program * @returns Status of read and execute */ static status_t parse_free(char* cmd) { assert(cmd != NULL); char var_name; int matched; var_t* var; // Read the command string errno = 0; matched = sscanf(cmd, "free(%c)", &var_name); // Check if sscanf was valid if (matched != 1 || errno != 0 || (var = get_var(var_name)) == NULL) return parse_error(cmd); // Ensure that the variable is in use if (!var->in_use) { print_fault(cmd, "Double free", ERROR); return DOUBLEFREE; } // Free variable buddy_free(var->mem); var->mem = NULL; var->in_use = false; return SUCCESS; }
void tw_event_rollback(tw_event * event) { tw_event *e = event->caused_by_me; tw_lp *dest_lp = event->dest_lp; tw_free_output_messages(event, 0); dest_lp->pe->cur_event = event; dest_lp->kp->last_time = event->recv_ts; (*dest_lp->type->revent)(dest_lp->cur_state, &event->cv, tw_event_data(event), dest_lp); if (event->delta_buddy) { tw_clock start = tw_clock_read(); buddy_free(event->delta_buddy); g_tw_pe[0]->stats.s_buddy += (tw_clock_read() - start); event->delta_buddy = 0; } while (e) { tw_event *n = e->cause_next; e->cause_next = NULL; event_cancel(e); e = n; } event->caused_by_me = NULL; dest_lp->kp->s_e_rbs++; }
/* * allocate a subset of a block, return the rest to the free list */ static void buddy_allocate_subset(buddy_ctxt_t *buddy, int index1, int order1, int index2, int order2) { uint32_t i; buddy_remove_free(buddy, index1, order1); /* * ASSERT: GET_ORDER(all) == order1 * ASSERT: IS_FREE(all) * ASSERT: index2 + (1UL << order2) <= index1 + (1UL << order1) * ASSERT: index2 >= index1 */ /* mark everything as in use first and with order 0 first */ for(i = 0; i < (1UL << order1); i++) { buddy_block_t *block = buddy->all + index1 + i; block->prev = block->next = 0; /* order 0, not free */ if(index1 + i == index2) i += (1UL << order2) - 1; } /* put back the unused ones, mark our own with correct order */ for(i = 0; i < (1UL << order1); i++) { buddy_block_t *block = buddy->all + index1 + i; if(index1 + i == index2) { block->prev = order2 << SHIFT_ORDER; i += (1UL << order2) - 1; } else { buddy_free(buddy, buddy->base + ((index1 + i) << buddy->page_bits)); } } }
void buddy_free_range(buddy_t *bd, range_t range) { unsigned i; uint64_t old_start, start; uintptr_t sz, min_sz; min_sz = 1 << MIN_BUDDY_SZ_LOG2; if (aligned_for(range.start, MIN_BUDDY_SZ_LOG2) == 0) { if (range.extent < min_sz) { return; } old_start = range.start; range.start &= ~0ULL << MIN_BUDDY_SZ_LOG2; range.start += min_sz; range.extent -= range.start - old_start; } while (range.extent >= min_sz && aligned_for(range.start, MIN_BUDDY_SZ_LOG2)) { for(i = MAX_BUDDY_SZ_LOG2; i >= MIN_BUDDY_SZ_LOG2; i--) { sz = 1 << i; start = range.start - bd->start; if (sz > range.extent || aligned_for(start, i) == 0) { continue; } range.extent -= sz; range.start += sz; buddy_free(bd, start + bd->start, sz); break; } } }
void mem_buddy_test() { as_mem_buddy_t *b = buddy_new(4); unsigned x = buddy_alloc(b, 4); buddy_alloc(b, 8); buddy_alloc(b, 2); buddy_free(b, x); buddy_print(b); buddy_destroy(b); }
/** * Prints out a string representation of NodePtr and all the other NodePtr's it is connected to. * @param node NodePtr to print. */ static void print(NodePtr node) { char *output; while (node) { output = toString(node->data); printf("%s",output); buddy_free(output); node = node->next; } }
/** * This adds memory to the kernel memory pool. The memory region being added * must fall within a zone previously specified via kmem_create_zone(). * * Arguments: * [IN] base_addr: Base address of the memory region to add. * [IN] size: Size of the memory region in bytes. */ void kmem_add_memory(unsigned long base_addr, size_t size) { /* * kmem buddy allocator is initially empty. * Memory is added to it via buddy_free(). * buddy_free() will panic if there are any problems with the args. */ buddy_free(kmem, (void *)base_addr, ilog2(size)); /* Update statistics */ kmem_bytes_managed += size; }
int main() { setbuf(stdout, NULL); memarea ma; unsigned int sizepow2 = 25; /* 32 Mb */ blockinfo *blocks = malloc(buddy_nblocks(sizepow2) * sizeof(blockinfo)); char *membase = malloc(1 << sizepow2); memset(membase, 0, 1 << sizepow2); buddy_init(&ma, sizepow2, membase, blocks); srand(1); int iterations = 40000; void *allocated[iterations]; int got = 0; int malloc_probability = 50; int i; for (i = 0; i < iterations; i++) { if (((rand() % 100) < malloc_probability) || (0 == got)) { int nbytes = rand() % (2 * 1024 * 1024); allocated[got] = buddy_alloc(&ma, nbytes); if (NULL != allocated[got]) got++; } else { int index = rand() % got; buddy_free(&ma, allocated[index]); memmove(&allocated[index], &allocated[index + 1], (got - index - 1) * sizeof(void *)); got--; } print_mem_line(&ma, 128); if (0 < DELAYMS) { struct timespec st; st.tv_sec = DELAYMS / 1000; st.tv_nsec = (DELAYMS % 1000) * 1000000; nanosleep(&st, NULL); } } return 0; }
/** * Frees pages of memory previously allocated with kmem_get_pages(). */ void kmem_free_pages( /** Address of the memory region to free. */ const void * addr, /** Number of pages to free, 2^order. * The order must match the value passed to kmem_get_pages() * when the pages were allocated. */ unsigned long order ) { unsigned long flags; spin_lock_irqsave(&kmem_lock, flags); kmem_bytes_allocated -= (1UL << order); buddy_free(kmem, addr, order + ilog2(PAGE_SIZE)); spin_unlock_irqrestore(&kmem_lock, flags); }
void memfree (void *region){ if(region == NULL){ printf("memfree error: region is NULL\n"); return; } int handle = find_handle(region); if(handle == -1){ printf("memfree: Could not find region handle\n"); return; } //printf("Found Handle: %d\n", handle); switch(MemAllocs[handle].flags){ case BUDDY_ALLOC: printf("memfree: Buddy Type\n"); buddy_free(&MemAllocs[handle], region); break; case SLAB_ALLOC: printf("memfree: Slab Type\n"); break; case FREE1_ALLOC: printf("memfree: Free List Type\n"); free_list_free(handle, region); break; case FREE2_ALLOC: printf("memfree: Free List Type\n"); free_list_free(handle, region); break; case FREE3_ALLOC: printf("memfree: Free List Type\n"); free_list_free(handle, region); break; case FREE4_ALLOC: printf("memfree: Free List Type\n"); free_list_free(handle, region); break; default: printf("Could not find handle\n"); break; } }
void buddy_free_range(buddy_t *bd, range_t range) { uintptr_t min_sz = 1 << MIN_BUDDY_SZ_LOG2; /** Firstly, we use a helper function to check if the range's start address is aligned to a multiple of the smallest block size. If not, we adjust it so that it is. { */ /* Ensure the range start address is at least aligned to MIN_BUDDY_SZ_LOG2. */ if (aligned_for(range.start, MIN_BUDDY_SZ_LOG2) == 0) { if (range.extent < min_sz) return; uint64_t old_start = range.start; range.start &= ~0ULL << MIN_BUDDY_SZ_LOG2; range.start += min_sz; range.extent -= range.start - old_start; } /** Now, we iteratively work through the range trying to allocate the largest block we can. { */ while (range.extent >= min_sz && aligned_for(range.start, MIN_BUDDY_SZ_LOG2)) { for (unsigned i = MAX_BUDDY_SZ_LOG2; i >= MIN_BUDDY_SZ_LOG2; --i) { uintptr_t sz = 1 << i; uint64_t start = range.start - bd->start; if (sz > range.extent || aligned_for(start, i) == 0) continue; range.extent -= sz; range.start += sz; buddy_free(bd, start + bd->start, sz); break; } } }
/** * Frees memory previously allocated with kmem_alloc(). * * Arguments: * [IN] addr: Address of the memory region to free. * * NOTE: The size of the memory region being freed is assumed to be in a * 'struct kmem_block_hdr' header located immediately before the address * passed in by the caller. This header is created and initialized by * kmem_alloc(). */ void kmem_free( const void * addr ) { struct kmem_block_hdr *hdr; unsigned long flags; if( !addr ) return; BUG_ON((unsigned long)addr < sizeof(struct kmem_block_hdr)); /* Find the block header */ hdr = (struct kmem_block_hdr *)addr - 1; BUG_ON(hdr->magic != KMEM_MAGIC); /* Return block to the underlying buddy system */ spin_lock_irqsave(&kmem_lock, flags); kmem_bytes_allocated -= (1UL << hdr->order); buddy_free(kmem, hdr, hdr->order); spin_unlock_irqrestore(&kmem_lock, flags); }
/** * Deallocs the NodePtr and the JobPtr it contains * @param node NodePtr to dealloc */ void freeNode (NodePtr node) { if (isNodeNull(node)) return; freeJob(node->data); buddy_free(node); }
void runRandomTests(int count, unsigned int seed, int n, ListPtr list) { int i; int test; NodePtr node; JobPtr job; int *tests; tests = (int *) buddy_malloc(sizeof(int)*NUM_TESTS); for (i=0; i<NUM_TESTS; i++) tests[i]=0; srandom(seed); for (i=0; i<count; i++) { printf("\rRunning test #%d", i); test = (int) (NUM_TESTS * (double) rand()/RAND_MAX); tests[test]++; switch (test) { case 0: if (DEBUG > 1) fprintf(stderr,"addAtFront\n"); n++; job = createJob(n, "some info", n); node = createNode(job); addAtFront(list, node); break; case 1: if (DEBUG > 1) fprintf(stderr,"addAtRear\n"); n++; job = createJob(n, "some info", n); node = createNode(job); addAtRear(list, node); break; case 2: if (DEBUG > 1) fprintf(stderr,"removeFront\n"); node = removeFront(list); freeNode(node); break; case 3: if (DEBUG > 1) fprintf(stderr,"removeRear\n"); node = removeRear(list); freeNode(node); break; case 4: if (DEBUG > 1) fprintf(stderr,"removeNode\n"); node = removeNode(list, search(list, i)); freeNode(node); break; case 5: if (DEBUG > 1) fprintf(stderr,"reverseList\n"); reverseList(list); case 6: if (DEBUG > 1) fprintf(stderr,"searchList\n"); node = search(list, i); break; default: break; } } printf("\n"); print_stats(tests); buddy_free(tests); }
/* ioctl callback function */ long ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { char ch; /* current character to or from userspace */ int size; /* size of page being written to */ int bytes; /* current number of bytes being read or written */ switch (ioctl_num) { case IOCTL_ALLOC: printk(KERN_INFO "vmm: allocating %d bytes\n", (int)ioctl_param); return buddy_alloc((int)ioctl_param); case IOCTL_FREE: printk(KERN_INFO "vmm: freeing idx %d\n", (int)ioctl_param); return buddy_free((int)ioctl_param); case IOCTL_SET_IDX: current_idx = (int)ioctl_param; printk(KERN_INFO "vmm: setting idx to %d\n", current_idx); return 0; case IOCTL_SET_READ_SIZE: read_size = (int)ioctl_param; printk(KERN_INFO "vmm: setting read size to %d\n", read_size); return 0; case IOCTL_WRITE: /* reset the number of bytes written */ bytes = 0; /* get the page size */ size = buddy_size(current_idx); /* keep writing until some condition breaks us out */ while (1) { /* get the next byte from userspace */ get_user(ch, (char*)ioctl_param+bytes); /* if it's a null terminator we are finished writing */ if (ch == '\0') break; /* if we are about to write outside the page error out */ if (bytes > size) { printk(KERN_INFO "vmm: writing out of allocated area\n"); return -1; } /* write the byte into the pool */ *(buddy_pool+current_idx+bytes) = ch; printk(KERN_INFO "wrote %c to %d\n", ch, current_idx+bytes); /* go to the next byte */ bytes++; } printk(KERN_INFO "vmm: wrote %d bytes\n", bytes); /* return how many bytes were written */ return bytes; case IOCTL_READ: /* return error if trying to read more than the page size */ if (read_size > buddy_size(current_idx)) { printk(KERN_INFO "vmm: read bigger than allocated area\n"); return -1; } /* reset the number of bytes read */ bytes = 0; /* keep reading bytes until we've satisfied the request */ while (bytes < read_size) { /* get byte out of pool and send it to user */ put_user(*(buddy_pool+current_idx+bytes), (char*)ioctl_param+bytes); /* go to the next byte */ bytes++; } printk(KERN_INFO "vmm: read %d bytes\n", bytes); /* return how many bytes were read */ return bytes; default: printk(KERN_INFO "vmm: unknown ioctl call\n"); } return 0; }
int main(int argc, char **argv) { if(isArgumentForShowingVersion(argv)) showVersionAndExit(); char *buf; char *bufCopy; pid_t pid = getpid(); pid_t backgroundJob; int status = 0; char *prompt = getPrompt(); int bg; int jobNumber = 1; int counts; int jumpSet = 0; char *arguments[2048]; initialize(); printf("\n"); setPrompt(prompt); while ((buf = readline(prompt))) { if(strlen(buf) != 0) { bufCopy = buddy_malloc((strlen(buf)+1)*sizeof(char)); strcpy(bufCopy, buf); add_history(bufCopy); } else { printFinishedJobs(jobList); free(buf); continue; } free(buf); if(isCommandNotEmpty(bufCopy)) bg = isBackgroundCommand(bufCopy); getArgument(arguments, bufCopy, &counts); if(isExitCommand(bufCopy)){ buddy_free(bufCopy); freeList(jobList); if(arguments != NULL){ freeArguments(counts, arguments, NULL); } exit(0); } if(isCdCommand(bufCopy, arguments)){ changeDir(arguments); freeArguments(counts, arguments, bufCopy); } else if(isJobsCommand(bufCopy)) { printList(jobList); freeArguments(counts, arguments, bufCopy); } else if(isFgCommand(bufCopy, arguments)){ fg(arguments, jobList, counts, bufCopy); } else if(isBgCommand(bufCopy, arguments)){ bgS(arguments, jobList, counts, bufCopy); } else if (isCommandNotEmpty(bufCopy)) { if(bg == 1) { backgroundJob = fork(); if(backgroundJob == 0) { ignoreSignals(); runCommand(arguments, bufCopy); } else{ NodePtr n = createAndSetNode(&jobNumber, backgroundJob, bufCopy, bg); recordCommand(n, jobNumber, bg); freeArguments(counts, arguments, bufCopy); } } else { pid = fork(); if(pid == 0){ runCommand(arguments, bufCopy); } else { NodePtr n = createAndSetNode(&jobNumber, pid, bufCopy, bg); ignoreSignals(); if((waitpid(pid,&status,WUNTRACED))<0) err_sys("waitpid error"); freeArguments(counts, arguments, bufCopy); restoreSignalsAndDetermineStatus(status, jobList, n); } } } else { freeArguments(counts, arguments, bufCopy); } if(jumpSet == 0){ sigsetjmp(env, 1); jumpSet = 1; } continue; } if(buf == NULL) printf("\n"); exit(0); }
int main(int argc, char *argv[]) { int i; char ch; int count; unsigned long int seed; size_t size; struct element x[MAX_ITEMS]; int loc; if (argc < 2) { fprintf(stderr, "Usage: %s <num of tests> [random seed] [silent|terse|verbose|interactive]\n", argv[0]); exit(1); } count = atol(argv[1]); if (argc == 3) { seed = atol(argv[2]); srandom(seed); } if (argc == 4) { if (argv[3][0] == 's') { verbosity = SILENT; } else if (argv[3][0] == 't') { verbosity = TERSE; } else if (argv[3][0] == 'v') { verbosity = VERBOSE; } else if (argv[3][0] == 'i') { verbosity = INTERACTIVE; setvbuf(stdin, NULL, _IONBF, 0); } } if (verbosity > TERSE) system("clear"); buddy_init(0); if (verbosity > TERSE) { printf("Buddy system lists after initialization.\n"); printBuddyLists(); } if (verbosity == INTERACTIVE) { ch = getchar(); system("clear"); if (ch == 'q') exit(0); } for (i =0; i < MAX_ITEMS; i++) { x[i].ptr = NULL; x[i].size = 0; } for (i=0; i < count; i++) { //printf("GL "); loc = (i) % MAX_ITEMS; // where to put in our table //printf("Trying(%d): ", i); if (x[loc].ptr) { // printf("loc=%d ptr=%p size=%lu", loc, x[loc].ptr, x[loc].size); buddy_free(x[loc].ptr); // printf(" Done"); if (verbosity > SILENT) printf("buddy_freed address %p of size %lu in x[%d]\n", x[loc].ptr, x[loc].size, loc); if (verbosity > TERSE) printBuddyLists(); x[loc].ptr = NULL; x[loc].size = 0; // printf(" IfComplete "); } else { size = random() % MAX_REQUEST + 1; // how big a request // printf("loc=%d ptr=%p size=%lu", loc, x[loc].ptr, size); x[loc].ptr = (char *) buddy_malloc(size*sizeof(char)); // printf(" Done"); if (x[loc].ptr == NULL) { perror("TestBuddy:"); exit(1); } x[loc].size = size*sizeof(char); memset(x[loc].ptr, '1', x[loc].size); if (verbosity > SILENT) printf("buddy_malloced %lu bytes and stored address %p at x[%d]\n", size*sizeof(char), x[loc].ptr, loc); if (verbosity > TERSE) printBuddyLists(); // printf(" IfComplete "); } //printf ("V"); if (verbosity == INTERACTIVE) { ch = getchar(); system("clear"); if (ch == 'q') exit(0); } //printf("F\n"); } #ifdef STATS printBuddySystemStats(); #endif exit(0); }