double ssd_clean_element_no_copyback(int elem_num, ssd_t *s) { double cost = 0; if (!ssd_start_cleaning(-1, elem_num, s)) { return cost; } switch(s->params.cleaning_policy) { case DISKSIM_SSD_CLEANING_POLICY_RANDOM: cost = ssd_clean_blocks_random(-1, elem_num, s); break; case DISKSIM_SSD_CLEANING_POLICY_GREEDY_WEAR_AGNOSTIC: case DISKSIM_SSD_CLEANING_POLICY_GREEDY_WEAR_AWARE: cost = ssd_clean_blocks_greedy(-1, elem_num, s); break; default: fprintf(stderr, "Error: invalid cleaning policy %d\n", s->params.cleaning_policy); exit(1); } 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; }
int ssd_start_cleaning_parunit(int parunit_num, int elem_num, ssd_t *s) { int i; int start; start = s->elements[elem_num].metadata.parunits[parunit_num].plane_to_clean; i = start; do { ASSERT(parunit_num == s->elements[elem_num].metadata.plane_meta[i].parunit_num); if (ssd_start_cleaning(i, elem_num, s)) { s->elements[elem_num].metadata.parunits[parunit_num].plane_to_clean = \ ssd_next_plane_in_parunit(i, parunit_num, elem_num, s); return i; } i = ssd_next_plane_in_parunit(i, parunit_num, elem_num, s); } while (i != start); return -1; }