//////////////////////////////////////////////////////////////////////////////// // File : malloc.c // Date : 05/03/2013 // Author : Jean-Baptiste Bréjon / alain greiner // Copyright (c) UPMC-LIP6 //////////////////////////////////////////////////////////////////////////////// #include "malloc.h" #include "stdio.h" // Global variables defining the heap descriptors array (one heap per cluster) giet_heap_t heap[X_SIZE][Y_SIZE]; // Macro returning the smallest power of 2 larger or equal to size value #define GET_SIZE_INDEX(size) (size <= 0x00000001) ? 0 :\ (size <= 0x00000002) ? 1 :\ (size <= 0x00000004) ? 2 :\ (size <= 0x00000008) ? 3 :\ (size <= 0x00000010) ? 4 :\ (size <= 0x00000020) ? 5 :\ (size <= 0x00000040) ? 6 :\ (size <= 0x00000080) ? 7 :\ (size <= 0x00000100) ? 8 :\ (size <= 0x00000200) ? 9 :\ (size <= 0x00000400) ? 10 :\ (size <= 0x00000800) ? 11 :\ (size <= 0x00001000) ? 12 :\ (size <= 0x00002000) ? 13 :\ (size <= 0x00004000) ? 14 :\ (size <= 0x00008000) ? 15 :\ (size <= 0x00010000) ? 16 :\ (size <= 0x00020000) ? 17 :\ (size <= 0x00040000) ? 18 :\ (size <= 0x00080000) ? 19 :\ (size <= 0x00100000) ? 20 :\ (size <= 0x00200000) ? 21 :\ (size <= 0x00400000) ? 22 :\ (size <= 0x00800000) ? 23 :\ (size <= 0x01000000) ? 24 :\ (size <= 0x02000000) ? 25 :\ (size <= 0x04000000) ? 26 :\ (size <= 0x08000000) ? 27 :\ (size <= 0x10000000) ? 28 :\ (size <= 0x20000000) ? 29 :\ (size <= 0x40000000) ? 30 :\ (size <= 0x80000000) ? 31 :\ 32 //////////////////////////////// void heap_init( unsigned int x, unsigned int y ) { unsigned int heap_base; // heap segment base unsigned int heap_size; // heap segment size unsigned int heap_index; // size_index in free[array] unsigned int alloc_base; // alloc[] array base unsigned int alloc_size; // alloc[] array size unsigned int alloc_index; // size_index in free[array] unsigned int index; // iterator // get heap_base, heap size, and heap index giet_heap_info( &heap_base, &heap_size, x, y ); heap_index = GET_SIZE_INDEX( heap_size ); // checking heap segment constraints if ( heap_size == 0 ) // heap segment exist { giet_exit("ERROR in malloc() : heap not found \n"); } if ( heap_size != (1<= alloc_index ; index-- ) { heap[x][y].free[index] = base; ptr = (unsigned int*)base; *ptr = 0; base = base + (1<free[searched_index-1]; heap->free[searched_index-1] = (unsigned int)new; if ( searched_index == requested_index + 1 ) // terminal case: return lower half block { return vaddr; } else // non terminal case : lower half block must be split again { return split_block( heap, vaddr, searched_index-1, requested_index ); } } // end split_block() ////////////////////////////////////////// unsigned int get_block( giet_heap_t* heap, unsigned int searched_index, unsigned int requested_index ) { // test terminal case if ( (1< heap->heap_size ) // failure : return a NULL value { return 0; } else // search a block in free[searched_index] { unsigned int vaddr = heap->free[searched_index]; if ( vaddr == 0 ) // block not found : search in free[searched_index+1] { return get_block( heap, searched_index+1, requested_index ); } else // block found : pop it from free[searched_index] { // pop the block from free[searched_index] unsigned int next = *((unsigned int*)vaddr); heap->free[searched_index] = next; // test if the block must be split if ( searched_index == requested_index ) // no split required { return vaddr; } else // split is required { return split_block( heap, vaddr, searched_index, requested_index ); } } } } // end get_block() //////////////////////////////////////// void * remote_malloc( unsigned int size, unsigned int x, unsigned int y ) { // checking arguments if (size == 0) { giet_exit("ERROR in malloc() : requested size = 0 \n"); } if ( x >= X_SIZE ) { giet_exit("ERROR in malloc() : x coordinate too large\n"); } if ( y >= Y_SIZE ) { giet_exit("ERROR in malloc() : y coordinate too large\n"); } // initializes the heap if first access if ( heap[x][y].init != HEAP_INITIALIZED ) { heap_init( x, y ); } // normalize size if ( size < MIN_BLOCK_SIZE ) size = MIN_BLOCK_SIZE; // compute requested_index for the free[] array unsigned int requested_index = GET_SIZE_INDEX( size ); // take the lock protecting access to heap(x,y) lock_acquire( &heap[x][y].lock ); // call the recursive function get_block unsigned int base = get_block( &heap[x][y], requested_index, requested_index ); // update the alloc[] array if block found if ( base != 0 ) { unsigned offset = (base - heap[x][y].heap_base) / MIN_BLOCK_SIZE; unsigned char* ptr = (unsigned char*)(heap[x][y].alloc_base + offset); *ptr = requested_index; } // release the lock lock_release( &heap[x][y].lock ); return (void*)base; } // end remote_malloc() ////////////////////////////////// void * malloc( unsigned int size ) { unsigned int proc_id = giet_procid(); unsigned int cluster_xy = proc_id / NB_PROCS_MAX; unsigned int x = cluster_xy >> Y_WIDTH; unsigned int y = cluster_xy & ((1<