void ide_writeback(void) { static uint32_t counter = 0; counter ++; if (counter == WRITEBACK_TIME * HZ) { cache_writeback(); counter = 0; } }
/* flush the cash - write back all dirty blocks */ void cache_flush() { if(CACHE_DEBUG) printf("flushing cache\n"); lock_acquire(&cache_globallock); int i; for (i = 0; i < CACHE_SIZE; i++) cache_writeback(i); lock_release(&cache_globallock); }
/* evicts a cache block */ void cache_evict () { ASSERT(lock_held_by_current_thread(&cache_globallock)); //unsigned loops = 0; /* as long as no cache block has been evicted */ while (true) { /* if(loops > 3 * CACHE_SIZE) { printf("Cache block %u | writer: %u | reader: %u\n", cep, cache[cep]->writer, cache[cep]->reader); } */ /* search cache block to evict */ /* if no one is writing and reading the block */ if (cache[cep]->writer == 0 && cache[cep]->reader == 0) { /* if cache block was accessed before * give it a second chance */ if (cache[cep]->accessed) { cache[cep]->accessed = false; } /* if cache block was not accessed nor * written in the last clock turn * evict it */ else { if(CACHE_DEBUG) printf("evicted cache block %u\n", (unsigned int) cep); cache_writeback(cep); bitmap_set (cache_table, cep, false); /* zero block first? */ return; } } cep = (cep + 1) % CACHE_SIZE; //loops++; } }
static void ide_driver_thread(void) { static Msg m; while (true) { receive(ANY, &m,1); if (m.src == MSG_HARD_INTR) { if (m.type == IDE_WRITEBACK) { cache_writeback(); } else { panic("IDE interrupt is leaking"); } } else if (m.type == DEV_READ) { uint32_t i; uint8_t data; for (i = 0; i < m.len; i ++) { data = read_byte(m.offset + i); copy_from_kernel(fetch_pcb(m.req_pid), m.buf + i, &data, 1); } m.ret = i; m.dest = m.src; m.src = IDE; send(m.dest, &m,1); } else if (m.type == DEV_WRITE) { uint32_t i; uint8_t data; for (i = 0; i < m.len; i ++) { copy_to_kernel(fetch_pcb(m.req_pid), &data, m.buf + i, 1); write_byte(m.offset + i, data); } m.ret = i; m.dest = m.src; m.src = IDE; send(m.dest, &m,1); } else { assert(0); } } }