#include "myalloc.h" #include #include #include #include struct mm_state { int nblck_per_bnk; size_t s_block; char* act_banks; char* alloc_blocks; }; /* Returns the module number based on the bank number which it contains. */ int bank_to_mod(int bank_num) { const struct ram_info* info = hw_raminfo(); int mod_num = floor(bank_num / info->nbanks_per_module); return mod_num; } /* Returns the bank number based on the block number which it contains. */ int block_to_bank(mm_state_t* st, int block_num) { int bank_num = floor(block_num / st->nblck_per_bnk); return bank_num; } char* block_to_addr(mm_state_t* st, int block_num) { const struct ram_info* info = hw_raminfo(); int bank = floor(block_num / st->nblck_per_bnk); int mod = floor(bank / info->nbanks_per_module); int block_offs = (block_num % (info->nbanks_per_module * st->nblck_per_bnk)); int byte_offs = block_offs * st->s_block; return (char*)(info->module_addrs[mod] + byte_offs); } int addr_to_block(mm_state_t* st, void* ptr) { const struct ram_info* info = hw_raminfo(); int nblock = info->nmodules * info->nbanks_per_module * st->nblck_per_bnk; int block_num; for (block_num = 0; block_num < nblock; block_num++) { // printf("gegeven %p mogelijk %p\n", ptr, (void*)block_to_addr(st, block_num)); if ((void*)block_to_addr(st, block_num) == ptr) { break; } } return block_num; } // void init_bank_arr(mm_state_t* st, int nbank_state) // { // return; // } // void init_block_arr(mm_state_t* st, int nblock_state) // { // return; // } bool check_bank(mm_state_t* st, int bank_num) { return (st->act_banks[bank_num / 8] & (1 << (7 - (bank_num % 8)))) == (1 << (7 - (bank_num % 8))); } bool check_block(mm_state_t* st, int block_num) { return (st->alloc_blocks[block_num / 8] & (1 << (7 - (block_num % 8)))) == (1 << (7 - (block_num % 8))); } void set_bank(mm_state_t* st, int bank_num) { const struct ram_info* info = hw_raminfo(); int mod_num = bank_num / info->nbanks_per_module; //printf("%d %d\n", mod_num, bank_num); hw_activate(mod_num, (bank_num % info->nbanks_per_module)); st->act_banks[bank_num / 8] |= (1 << (7 - (bank_num % 8))); return; } void set_block(mm_state_t* st, int block_num) { //printf("%d ", block_num); int bank_num = block_num / st->nblck_per_bnk; if (!check_bank(st, bank_num)) { set_bank(st, bank_num); } st->alloc_blocks[block_num / 8] |= (1 << (7 - (block_num % 8))); } void set_block_ran(mm_state_t* st, int fst, int nblock) { for (int i = fst; i < (fst + nblock); i++) { set_block(st, i); } } void clr_block(mm_state_t* st, int block_num) { st->alloc_blocks[block_num / 8] &= ~(1 << (7 - (block_num % 8))); } void clr_block_ran(mm_state_t* st, int fst, int nblock) { for (int i = fst; i < (fst + nblock); i++) { clr_block(st, i); } } /* Returns the number of the first block which corresponds to the smalles fit. Returns NULL if no fit is found. */ int smallest_fit(mm_state_t* st, size_t nbytes) { const struct ram_info* inf = hw_raminfo(); int nblcks_req = ceil((float)nbytes / (float)st->s_block); int nblcks_tot = st->nblck_per_bnk * inf->nbanks_per_module * inf->nmodules; // nblck_per_mod = inf->nbanks_per_module * st->nblck_per_bnk; int sml_blck = 0; int cur_blck = 0; // int pos_in_bank = 0; int sml_blck_s = nblcks_tot; int cur_blck_s = nblcks_tot; bool new_blk = true; for (int i = 0; i < nblcks_tot; i++) { if (check_block(st, i) || !((i + 1) % st->nblck_per_bnk)) { if (cur_blck_s < sml_blck_s && cur_blck >= nblcks_req) { sml_blck = cur_blck; sml_blck_s = cur_blck_s; } new_blk = true; } else { if (new_blk) { cur_blck = i; cur_blck_s = 1; new_blk = false; } else { cur_blck_s += 1; } } } //printf("S%d R%d\n", sml_blck_s, nblcks_req); if (sml_blck_s < nblcks_req) { return 0; } return sml_blck; } /* TEMP */ void print_bit(char* bit, int size) { for (int k = 0; k < size; k++) { for (int i = 0; i < 8; i++) { printf("%d", !!((bit[k] << i) & 0x80)); } } printf("\n"); } mm_state_t* mm_initialize(void) { const struct ram_info* info = hw_raminfo(); int nbanks = (info->nbanks_per_module * info->nmodules); int nblck_per_bnk = 16; size_t s_bnk_arr = ceil(nbanks / 8); size_t s_blck_arr = ceil(((float)nbanks * (float)nblck_per_bnk) / 8); size_t s_state = sizeof (mm_state_t) + s_bnk_arr + s_blck_arr; int nbank_state = ceil((float)s_state / (float)info->bank_size); int nblock_state = ceil((float)s_state / (float)(info->bank_size / nblck_per_bnk)); for (int i = 0; i < nbank_state; i++) { hw_activate(0, i); } char *base = (char*)info->module_addrs[0]; mm_state_t *st = (mm_state_t *)base; st->nblck_per_bnk = nblck_per_bnk; st->s_block = info->bank_size / nblck_per_bnk; st->act_banks = base + sizeof (mm_state_t); st->alloc_blocks = st->act_banks + s_bnk_arr; for (int i = 0; i < (int) s_bnk_arr; i++) { st->act_banks[i] = 0; } for (int i = 0; i < (int) s_blck_arr; i++) { st->alloc_blocks[i] = 0; } for (int i = 0; i < nbank_state; i++) { st->act_banks[i / 8] |= (1 << (7 - (i % 8))); } for (int i = 0; i < nblock_state; i++) { st->alloc_blocks[i / 8] |= (1 << (7 - (i % 8))); } // printf("%d\n", s_state); // printf("%d\n", s_bnk_arr); // printf("%d\n", s_blck_arr); // print_bit(st->act_banks, (int)s_bnk_arr); // print_bit(st->alloc_blocks, (int)s_blck_arr); return st; } void *mm_alloc(mm_state_t* st, size_t nbytes) { int* nblck_ptr; void* ptr; const struct ram_info *info = hw_raminfo(); int nbytes_p_mod = (info->nmodules * info->nbanks_per_module * info->bank_size); int nbytes_tot = nbytes + 8; if (nbytes_tot > nbytes_p_mod) { return NULL; } //printf("%d\n", nbytes_tot); int fst_blk_num = smallest_fit(st, nbytes_tot); if (!fst_blk_num) { return NULL; } int nblock = (int)ceil((float)nbytes_tot / (float)st->s_block); set_block_ran(st, fst_blk_num, nblock); nblck_ptr = (int*)block_to_addr(st, fst_blk_num); ptr = (void*)nblck_ptr + 8; *nblck_ptr = nblock; // printf("taart %d kaas %d baas %d\n", nblock, *nblck_ptr, sizeof (int)); print_bit(st->act_banks, 5); print_bit(st->alloc_blocks, 84); return ptr; } void mm_free(mm_state_t* st, void *ptr) { int* nblck_ptr = ptr - 8; // printf("%d blocknum %d\n", *nblck_ptr, addr_to_block(st, nblck_ptr)); int fst_blck_num = addr_to_block(st, nblck_ptr); clr_block_ran(st, fst_blck_num, *nblck_ptr); }