| | |
| | | */ |
| | | #include "mm.h" |
| | | #include "sem_util.h" |
| | | #include "hashtable.h" |
| | | #include "key_def.h" |
| | | #include "logger_factory.h" |
| | | #include "bh_api.h" |
| | | #include <sys/sem.h> |
| | | #include <sys/shm.h> |
| | | |
| | |
| | | |
| | | /* $end mallocmacros */ |
| | | |
| | | |
| | | |
| | | // #define MAX_HEAP (512*(1<<20)) /* 20 MB */ |
| | | #define MAX_HEAP (512) /* 20 MB */ |
| | | /* Hard-coded keys for IPC objects */ |
| | |
| | | |
| | | newsize = ALIGN(size + (SIZE_T_SIZE << 1) + (PTR_SIZE << 1) ); |
| | | |
| | | //fprintf(stderr, "mm_malloc : size=%u\n", size); |
| | | /* Search the free list for a fit */ |
| | | SemUtil::dec(mutex); |
| | | if ((ptr = find_fit(newsize)) != NULL) |
| | |
| | | return aptr; |
| | | } else { |
| | | SemUtil::inc(mutex); |
| | | err_msg(0, "mm_malloc : out of memery\n"); |
| | | LoggerFactory::getLogger()->fatal("mm_malloc : out of memery\n"); |
| | | // abort(); |
| | | err_exit(0, "mm_malloc : out of memery\n"); |
| | | exit(1); |
| | | |
| | | return NULL; |
| | | } |
| | | |
| | |
| | | /* |
| | | * mm_free - Free a block |
| | | */ |
| | | void mm_free(void *ptr) |
| | | void mm_free(void *ptr, int enable) |
| | | { |
| | | if (ptr == 0) |
| | | if (ptr == 0) |
| | | return; |
| | | |
| | | if (check_mm_valid(ptr) == false) |
| | | return; |
| | | |
| | | /* |
| | |
| | | *} |
| | | */ |
| | | |
| | | SemUtil::dec(mutex); |
| | | if (enable == true) { |
| | | SemUtil::dec_uni(mutex); |
| | | } |
| | | ptr -= SIZE_T_SIZE; |
| | | size_t size = GET_SIZE(HDRP(ptr)); |
| | | PUT(HDRP(ptr), PACK(size, 0)); |
| | | PUT(FTRP(ptr), PACK(size, 0)); |
| | | *(size_t *)ptr = 0x00; |
| | | coalesce(ptr); |
| | | SemUtil::inc(mutex); |
| | | if (enable == true) { |
| | | SemUtil::inc(mutex); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /* |
| | | * mm_realloc - Naive implementation of realloc |
| | |
| | | { |
| | | |
| | | //同一进程内已经初始化过了 |
| | | SemUtil::dec(mutex); |
| | | SemUtil::dec_uni(mutex); |
| | | if (shmid != -1){ |
| | | hashtable = (hashtable_t *)shmp; |
| | | SemUtil::inc(mutex); |
| | |
| | | first = false; |
| | | shmid = shmget(SHM_KEY, 0, 0); |
| | | } |
| | | |
| | | if (shmid == -1) |
| | | err_exit(errno, "mm_init shmget"); |
| | | shmp = shmat(shmid, key_addr, 0); |
| | |
| | | bool mm_destroy(void) { |
| | | struct shmid_ds shmid_ds; |
| | | |
| | | SemUtil::dec(mutex); |
| | | SemUtil::dec_uni(mutex); |
| | | |
| | | if(shmctl(shmid, IPC_STAT, &shmid_ds) == 0) { |
| | | //LoggerFactory::getLogger()->debug("shm_nattch=%d\n", shmid_ds.shm_nattch); |
| | |
| | | //remove shared memery |
| | | if (shmctl(shmid, IPC_RMID, 0) == -1) |
| | | err_exit(errno, "mm_destroy shmctl IPC_RMID"); |
| | | else |
| | | LoggerFactory::getLogger()->debug("shared memory destroy\n"); |
| | | |
| | | LoggerFactory::getLogger()->debug( "mm_destroy: real destroy."); |
| | | |
| | | SemUtil::inc(mutex); |
| | | SemUtil::remove(mutex); |
| | |
| | | |
| | | void mm_free_by_key(int key) { |
| | | void *ptr; |
| | | |
| | | ptr = hashtable_get(hashtable, key); |
| | | if(ptr != NULL) { |
| | | mm_free(ptr); |
| | |
| | | PUT(HDRP(bp), PACK(size, 0)); /* Free block header */ //line:vm:mm:freeblockhdr |
| | | PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */ //line:vm:mm:freeblockftr |
| | | PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ //line:vm:mm:newepihdr |
| | | |
| | | |
| | | /* Coalesce if the previous block was free */ |
| | | return coalesce(bp); //line:vm:mm:returnblock |
| | | } |
| | | |
| | | static void insert_fblock (void *bp) |
| | | { |
| | | //后进先出的方式插入,即插入链表头位置 |
| | | |
| | | // insert into the header of the free list |
| | | PUT_PTR(SUCCRP(bp), NEXT_FBLKP(heap_listp)); //the successor of bp point to the old first free block |
| | | PUT_PTR(PREDRP(NEXT_FBLKP(heap_listp)), bp); //the predecessor of the old first free block point to bp |
| | |
| | | PUT(FTRP(bp), PACK(csize, 1)); |
| | | rm_fblock(bp); |
| | | } |
| | | return bp; |
| | | |
| | | *(size_t *)bp = inter_key_get(); |
| | | |
| | | return (bp + SIZE_T_SIZE); |
| | | } |
| | | |
| | | static int is_allocated(void *ptr) |
| | |
| | | |
| | | } |
| | | |
| | | void find_mm_data(int val) |
| | | { |
| | | void *bp = heap_listp; |
| | | |
| | | unsigned int diff; |
| | | struct timeval start, end; |
| | | |
| | | gettimeofday(&start, NULL); |
| | | SemUtil::dec(mutex); |
| | | for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) |
| | | { |
| | | if (GET_ALLOC(HDRP(bp))) { |
| | | if ((*(size_t *)bp) == val) { |
| | | mm_free(bp + SIZE_T_SIZE, false); |
| | | } |
| | | } |
| | | |
| | | gettimeofday(&end, NULL); |
| | | |
| | | diff = end.tv_sec - start.tv_sec; |
| | | if (diff >= TIME_DUR) |
| | | break; |
| | | } |
| | | SemUtil::inc(mutex); |
| | | |
| | | return; |
| | | } |
| | | |
| | | int check_mm_valid(void *bp) |
| | | { |
| | | int val; |
| | | |
| | | if ((bp >= mem_start_brk) && (bp <= mem_max_addr) && (GET_ALLOC(HDRP(bp - SIZE_T_SIZE)))) { |
| | | |
| | | val = *(size_t *)(bp - SIZE_T_SIZE); |
| | | if ((val >= START_KEY) || (val == SHM_BUS_KEY)) { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /* |
| | | * find_fit - Find a fit for a block with size bytes |
| | | */ |
| | | static void *find_fit(size_t size) |
| | | { |
| | | void *bp; |
| | | unsigned int diff; |
| | | struct timeval start, end; |
| | | |
| | | gettimeofday(&start, NULL); |
| | | for (bp = NEXT_FBLKP(heap_listp); bp != heap_listp; bp = NEXT_FBLKP(bp)) |
| | | { |
| | | if (!GET_ALLOC(HDRP(bp)) && (size <= GET_SIZE(HDRP(bp)))) |
| | | { |
| | | return bp; |
| | | } else if (GET_ALLOC(HDRP(bp)) && (GET_SIZE(HDRP(bp)) == 0)) |
| | | { |
| | | break; |
| | | } |
| | | |
| | | gettimeofday(&end, NULL); |
| | | |
| | | diff = end.tv_sec - start.tv_sec; |
| | | if (diff >= TIME_DUR) |
| | | break; |
| | | } |
| | | |
| | | return NULL; /* No fit */ |
| | | } |
| | | |