static int ssd_invoke_gang_cleaning(int gang_num, ssd_t *s) { int i; int elem_num; double max_cost = 0; double elem_clean_cost; int cleaning_invoked = 0; gang_metadata *g = &s->gang_meta[gang_num]; // all the elements in the gang must be free ASSERT(g->busy == FALSE); ASSERT(g->cleaning == FALSE); // invoke cleaning on all the elements for (i = 0; i < s->params.elements_per_gang; i ++) { elem_num = gang_num * s->params.elements_per_gang + i; elem_clean_cost = _ssd_invoke_element_cleaning(elem_num, s); // stat s->elements[elem_num].stat.tot_clean_time += max_cost; if (max_cost < elem_clean_cost) { max_cost = elem_clean_cost; } } // cleaning was invoked on all the elements. we can start // the next operation on this gang only after the cleaning // gets over on all the elements. if (max_cost > 0) { ioreq_event *tmp; g->busy = 1; g->cleaning = 1; cleaning_invoked = 1; // we use the 'blkno' field to store the gang number tmp = (ioreq_event *)getfromextraq(); tmp->devno = s->devno; tmp->time = simtime + max_cost; tmp->blkno = gang_num; tmp->ssd_gang_num = gang_num; tmp->type = SSD_CLEAN_GANG; tmp->flags = SSD_CLEAN_GANG; tmp->busno = -1; tmp->bcount = -1; stat_update (&s->stat.acctimestats, max_cost); addtointq ((event *)tmp); } return cleaning_invoked; }
static int ssd_invoke_element_cleaning(int elem_num, ssd_t *s) { double max_cost = 0; int cleaning_invoked = 0; ssd_element *elem = &s->elements[elem_num]; // element must be free ASSERT(elem->media_busy == FALSE); max_cost = _ssd_invoke_element_cleaning(elem_num, s); // cleaning was invoked on this element. we can start // the next operation on this elem only after the cleaning // gets over. if (max_cost > 0) { ioreq_event *tmp; elem->media_busy = 1; cleaning_invoked = 1; // we use the 'blkno' field to store the element number tmp = (ioreq_event *)getfromextraq(); tmp->devno = s->devno; tmp->time = simtime + max_cost; tmp->blkno = elem_num; tmp->ssd_elem_num = elem_num; tmp->type = SSD_CLEAN_ELEMENT; tmp->flags = SSD_CLEAN_ELEMENT; tmp->busno = -1; tmp->bcount = -1; stat_update (&s->stat.acctimestats, max_cost); addtointq ((event *)tmp); // stat elem->stat.tot_clean_time += max_cost; elem->power_stat.acc_time += max_cost; ssd_dpower(s, max_cost); } return cleaning_invoked; }