Esempio n. 1
0
/**
* 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);
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
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++;
}
Esempio n. 5
0
/*
 * 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));
        }
    }
}
Esempio n. 6
0
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;
        }
    }
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
/**
* 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;
	} 
}
Esempio n. 9
0
/**
 * 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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
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);
}
Esempio n. 12
0
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;
	}
}
Esempio n. 13
0
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;
    }

  }
}
Esempio n. 14
0
/**
 * 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);
}
Esempio n. 15
0
/**
* 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);
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
/* 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;
}
Esempio n. 18
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);
}
Esempio n. 19
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);	
}