[OSy] test1

Eva Semanová evi.semanova at gmail.com
Wed Oct 24 17:19:42 CEST 2018


ešte mi treba dokončiť free funkciu

Eva Semanová
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://d3s.mff.cuni.cz/pipermail/nswi004/attachments/20181024/7fcaebc1/attachment.html>
-------------- next part --------------
/*this was alocated as global*/

static heap_block_head_t * position = NULL;
///////////////////////

void *malloc (const size_t size)
{
        /*
         * Checking for maximum size avoids errors due to
         * overflow, which would be hard to debug.
         */
        assert (size <= HEAP_BLOCK_SIZE_MAX);

        /* Disable interrupts while accessing shared structures. */
        ipl_t state = query_and_disable_interrupts ();

        /*
         * We have to allocate a bit more to have room for
         * header and footer. The size of the memory block
         * also has to be 4 bytes aligned to avoid unaligned
         * memory access exception while accessing the
         * footer structure.
         */
        size_t real_size = ALIGN_UP (size, ALIGNMENT) +
            sizeof (heap_block_head_t) + sizeof (heap_block_foot_t);

        void *result = NULL;

		
	
/* Iterate over all heaps */
        list_foreach (heap_list, heap_t, link, heap) {
			if ((position != NULL) && (heap != position->heap)) {
				continue;
			}
			heap_block_head_t *pos;
			
			if(heap == position->heap) {
				pos = position;
			} else {
				pos = (heap_block_head_t *) heap->heap_start;
			}
			
			while ((result == NULL) && ((void *) pos < heap->heap_end)) {
					/* Make sure the heap is not corrupted. */
					block_check (pos);

					/* Try to find a block that is free and large enough. */
					if ((pos->free) && (pos->size >= real_size)) {
							/*
							 * We have found a suitable block.
							 * See if we should split it.
							 */
							size_t split_limit = real_size +
								sizeof (heap_block_head_t) + sizeof (heap_block_foot_t);

							if (pos->size > split_limit) {
									/* Block big enough -> split. */
									void *next = ((void *) pos) + real_size;
									block_init (next, pos->size - real_size, true, heap);
									block_init (pos, real_size, false, heap);
							} else {
									/* Block too small -> use as is. */
									pos->free = false;
							}

							/* Either way we have our result. */
							result = ((void *) pos) + sizeof (heap_block_head_t);
					}

					/* Advance to the next block. */
					pos = (heap_block_head_t *) (((void *) pos) + pos->size);
					if(result != NULL) {
						if((void *) pos < heap->heap_end)) {
							position = pos; //this is the new place where to start searching
						}
						else {
							position = (heap_block_head_t*) (heap->link.next);
						}						
					}
			}
                if (result != NULL)
                        break;
        }
		/*second foreach*/
		list_foreach(heap_list, heap_t, link, heap) {
			if ((result != NULL) || (position == NULL)) {
				break;
			}
			
			/*if (heap == position->heap) */

			heap_block_head_t *pos= (heap_block_head_t *) heap->heap_start;
			
			while ((result == NULL) && ((void *) pos < heap->heap_end) && (pos != position) {
					/* Make sure the heap is not corrupted. */
					block_check (pos);

					/* Try to find a block that is free and large enough. */
					if ((pos->free) && (pos->size >= real_size)) {
							/*
							 * We have found a suitable block.
							 * See if we should split it.
							 */
							size_t split_limit = real_size +
								sizeof (heap_block_head_t) + sizeof (heap_block_foot_t);

							if (pos->size > split_limit) {
									/* Block big enough -> split. */
									void *next = ((void *) pos) + real_size;
									block_init (next, pos->size - real_size, true, heap);
									block_init (pos, real_size, false, heap);
							} else {
									/* Block too small -> use as is. */
									pos->free = false;
							}

							/* Either way we have our result. */
							result = ((void *) pos) + sizeof (heap_block_head_t);
					}

					/* Advance to the next block. */
					pos = (heap_block_head_t *) (((void *) pos) + pos->size);
					if(result != NULL) {
						if((void *) pos < heap->heap_end)) {
							position = pos; //this is the new place where to start searching
						}
						else {
							position = (heap_block_head_t*) (heap->link.next);
						}						
					}
			}
                if (result != NULL)
                        break;
		}

        /*
         * There is not enough empty space in the existing
         * heaps. Try to acquire a new heap and allocate the
         * block from it.
         */
        if (result == NULL)
                result = malloc_heap (size);

        conditionally_enable_interrupts (state);

        return result;
		
}


static void *malloc_heap (const size_t size)
{
        /*
         * Calculate the proper size of the new heap
         * (with appropriate headers and alignment).
         */
        size_t real_size = ALIGN_UP (size, ALIGNMENT) +
            sizeof (heap_block_head_t) + sizeof (heap_block_foot_t);
        size_t split_limit = real_size +
            sizeof (heap_block_head_t) + sizeof (heap_block_foot_t);
        size_t heap_size =
            ALIGN_UP (real_size + sizeof (heap_t), FRAME_SIZE);

        /*
         * Calcutate the number of frames required from
         * the frame allocator. The new heap should be at
         * least HEAP_FRAMES large.
         */
        size_t frames = heap_size >> FRAME_WIDTH;
        if (frames < HEAP_FRAMES) {
                frames = HEAP_FRAMES;
                heap_size = frames << FRAME_WIDTH;
        }

        /*
         * Ask the frame allocator for a continuous physical
         * memory area for the new heap.
         */
        uintptr_t phys;
        int rc = frame_alloc (&phys, frames, VF_VA_AUTO | VF_AT_KSEG0);
        if (rc != EOK)
                return NULL;

        /*
         * Initialize the heap structure.
         */
        heap_t *heap = (heap_t *) ADDR_IN_KSEG0 (phys);

        link_init (&heap->link);
        heap->heap_start = ((void *) heap) + sizeof (heap_t);
        heap->heap_end = ((void *) heap) + heap_size;
        heap->frames = frames;

        heap_block_head_t *cur = (heap_block_head_t *) heap->heap_start;
        size_t payload_heap_size = heap_size - sizeof (heap_t);

        /*
         * Allocate the block from the newly created heap.
         */
        if (payload_heap_size > split_limit) {
                void *next = ((void *) cur) + real_size;
                block_init (next, payload_heap_size - real_size, true, heap);
                block_init (cur, real_size, false, heap);
				position = (heap_block_head_t *)next;
        } else {
                block_init (cur, payload_heap_size, false, heap);
				//heap is full, start searching from beginning
				position = NULL;
		}

        list_append (&heap_list, &heap->link);

        return ((void *) heap->heap_start + sizeof (heap_block_head_t));
}

/*I have to rewrite free function*/


More information about the NSWI004 mailing list