double ssd_clean_element(ssd_t *s, int elem_num) { double cost = 0; if (s->params.copy_back == SSD_COPY_BACK_DISABLE) { cost = ssd_clean_element_no_copyback(elem_num, s); } else { cost = ssd_clean_element_copyback(elem_num, s); } return cost; }
static double ssd_write_one_active_page(int blkno, int count, int elem_num, ssd_t *s) { double cost = 0; int cleaning_invoked = 0; ssd_element_metadata *metadata; ssd_power_element_stat *power_stat; int lbn; metadata = &(s->elements[elem_num].metadata); power_stat = &(s->elements[elem_num].power_stat); // get the logical page number corresponding to this blkno lbn = ssd_logical_pageno(blkno, s); // see if there are any free pages left inside the active block. // as per the osr design, the last page is used as a summary page. // so if the active_page is already pointing to the summary page, // then we need to find another free block to act as active block. if (ssd_last_page_in_block(metadata->active_block, s)) { // do we need to create more free blocks for future writes? if (ssd_start_cleaning(-1, elem_num, s)) { printf ("We should not clean here ...\n"); ASSERT(0); // if we're cleaning in the background, this should // not get executed if (s->params.cleaning_in_background) { exit(1); } cleaning_invoked = 1; cost += ssd_clean_element_no_copyback(elem_num, s); } // if we had invoked the cleaning, we must again check if we // need an active block before allocating one. this check is // needed because the above cleaning procedure might have // allocated new active blocks during the process of cleaning, // which might still have free pages for writing. if (!cleaning_invoked || ssd_last_page_in_block(metadata->active_block, s)) { _ssd_alloc_active_block(-1, elem_num, s); } } // issue the write to the current active page cost += _ssd_write_page_osr(s, metadata, lbn, power_stat, blkno); cost += ssd_data_transfer_cost(s, count); ssd_power_flash_calculate(SSD_POWER_FLASH_BUS_DATA_TRANSFER, ssd_data_transfer_cost(s,s->params.page_size), power_stat, s); return cost; }