static void icacheinsert(u8int score[VtScoreSize], IAddr *ia, int state) { IEntry *ie; if((ie = poplast(&icache.free)) == nil && (ie = evictlru()) == nil){ addstat(StatIcacheStall, 1); while((ie = poplast(&icache.free)) == nil && (ie = evictlru()) == nil){ // Could safely return here if state == IEClean. // But if state == IEDirty, have to wait to make // sure we don't lose an index write. // Let's wait all the time. flushdcache(); kickicache(); rsleep(&icache.full); } addstat(StatIcacheStall, -1); } memmove(ie->score, score, VtScoreSize); ie->state = state; ie->ia = *ia; if(state == IEClean){ addstat(StatIcachePrefetch, 1); pushfirst(&icache.clean, ie); }else{ addstat(StatIcacheWrite, 1); assert(state == IEDirty); icache.ndirty++; setstat(StatIcacheDirty, icache.ndirty); delaykickicache(); pushfirst(&icache.dirty, ie); } ihashinsert(icache.hash, ie); }
int syncindex(Index *ix) { Arena *arena; int i, e, e1, ok; ok = 0; for(i = 0; i < ix->narenas; i++){ trace(TraceProc, "syncindex start %d", i); arena = ix->arenas[i]; e = syncarena(arena, TWID32, 1, 1); e1 = e; e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr); if(e & SyncHeader) fprint(2, "arena %s: header is out-of-date\n", arena->name); if(e1){ fprint(2, "arena %s: %x\n", arena->name, e1); ok = -1; continue; } flushdcache(); if(arena->memstats.clumps == arena->diskstats.clumps) continue; fprint(2, "%T %s: indexing %d clumps...\n", arena->name, arena->memstats.clumps - arena->diskstats.clumps); if(syncarenaindex(arena, ix->amap[i].start) < 0){ fprint(2, "arena %s: syncarenaindex: %r\n", arena->name); ok = -1; continue; } if(wbarena(arena) < 0){ fprint(2, "arena %s: wbarena: %r\n", arena->name); ok = -1; continue; } flushdcache(); delaykickicache(); } return ok; }