X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fiocache.c;h=8f735419f1d9f65d4a823d8a316ec0a8c9402917;hb=e7dd0e094f0c23bb20ddb0025f41d1c0c28f5ab2;hp=8ea6929a8a2401c97f108b91ad4eb6671f46bf19;hpb=75e87cf46a3899f76bae5c64e130cfc033562e9a;p=tpg%2Facess2.git diff --git a/Kernel/drv/iocache.c b/Kernel/drv/iocache.c index 8ea6929a..8f735419 100644 --- a/Kernel/drv/iocache.c +++ b/Kernel/drv/iocache.c @@ -3,12 +3,16 @@ * - IO Cache * * By thePowersGang (John Hodge) + * + * TODO: Convert to use spare physical pages instead */ -#include +#define DEBUG 0 +#include #include // === TYPES === typedef struct sIOCache_Ent tIOCache_Ent; +typedef struct sIOCache_PageInfo tIOCache_PageInfo; // === STRUCTURES === struct sIOCache_Ent @@ -20,11 +24,20 @@ struct sIOCache_Ent Uint8 Data[]; }; +struct sIOCache_PageInfo +{ + tIOCache_PageInfo *GlobalNext; + tIOCache_PageInfo *CacheNext; + tIOCache *Owner; + tPAddr BasePhys; + Uint64 BaseOffset; +}; + struct sIOCache { tIOCache *Next; int SectorSize; - int Lock; + tMutex Lock; int Mode; Uint32 ID; tIOCache_WriteCallback Write; @@ -34,9 +47,10 @@ struct sIOCache }; // === GLOBALS === - int glIOCache_Caches; +tShortSpinlock glIOCache_Caches; tIOCache *gIOCache_Caches = NULL; int giIOCache_NumCaches = 0; +tIOCache_PageInfo *gIOCache_GlobalPages; // === CODE === /** @@ -45,7 +59,7 @@ tIOCache *gIOCache_Caches = NULL; */ tIOCache *IOCache_Create( tIOCache_WriteCallback Write, Uint32 ID, int SectorSize, int CacheSize ) { - tIOCache *ret = malloc( sizeof(tIOCache) ); + tIOCache *ret = calloc( 1, sizeof(tIOCache) ); // Sanity Check if(!ret) return NULL; @@ -56,14 +70,12 @@ tIOCache *IOCache_Create( tIOCache_WriteCallback Write, Uint32 ID, int SectorSiz ret->ID = ID; ret->Write = Write; ret->CacheSize = CacheSize; - ret->CacheUsed = 0; - ret->Entries = 0; // Append to list - LOCK( &glIOCache_Caches ); + SHORTLOCK( &glIOCache_Caches ); ret->Next = gIOCache_Caches; gIOCache_Caches = ret; - RELEASE( &glIOCache_Caches ); + SHORTREL( &glIOCache_Caches ); // Return return ret; @@ -75,19 +87,38 @@ tIOCache *IOCache_Create( tIOCache_WriteCallback Write, Uint32 ID, int SectorSiz */ int IOCache_Read( tIOCache *Cache, Uint64 Sector, void *Buffer ) { - tIOCache_Ent *ent; + + ENTER("pCache XSector pBuffer", Cache, Sector, Buffer); // Sanity Check! - if(!Cache || !Buffer) + if(!Cache || !Buffer) { + LEAVE('i', -1); return -1; + } // Lock - LOCK( &Cache->Lock ); + Mutex_Acquire( &Cache->Lock ); if(Cache->CacheSize == 0) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); + LEAVE('i', -1); return -1; } - + + #if IOCACHE_USE_PAGES + tIOCache_PageInfo *page; + size_t offset = (Sector*Cache->SectorSize) % PAGE_SIZE; + Uint64 wanted_base = (Sector*Cache->SectorSize) & ~(PAGE_SIZE-1); + for( page = Cache->Pages; page; page = page->CacheNext ) + { + void *tmp; + if(page->BaseOffset < WantedBase) continue; + if(page->BaseOffset > WantedBase) break; + tmp = MM_MapTemp( page->BasePhys ); + memcpy( Buffer, tmp + offset, Cache->SectorSize ); + MM_FreeTemp( tmp ); + } + #else + tIOCache_Ent *ent; // Search the list for( ent = Cache->Entries; ent; ent = ent->Next ) { @@ -95,15 +126,18 @@ int IOCache_Read( tIOCache *Cache, Uint64 Sector, void *Buffer ) if( ent->Num == Sector ) { memcpy(Buffer, ent->Data, Cache->SectorSize); ent->LastAccess = now(); - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); + LEAVE('i', 1); return 1; } // It's a sorted list, so as soon as we go past `Sector` we know // it's not there if(ent->Num > Sector) break; } + #endif - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); + LEAVE('i', 0); return 0; } @@ -122,9 +156,9 @@ int IOCache_Add( tIOCache *Cache, Uint64 Sector, void *Buffer ) return -1; // Lock - LOCK( &Cache->Lock ); + Mutex_Acquire( &Cache->Lock ); if(Cache->CacheSize == 0) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return -1; } @@ -134,7 +168,7 @@ int IOCache_Add( tIOCache *Cache, Uint64 Sector, void *Buffer ) { // Is it already here? if( ent->Num == Sector ) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return 0; } @@ -171,6 +205,10 @@ int IOCache_Add( tIOCache *Cache, Uint64 Sector, void *Buffer ) oldestPrev = prev; } } + if( !oldest ) { + Log_Error("IOCache", "Cache full, but also empty"); + return -1; + } // Remove from list, write back and free oldestPrev->Next = oldest->Next; if(oldest->LastWrite && Cache->Mode != IOCACHE_VIRTUAL) @@ -189,7 +227,7 @@ int IOCache_Add( tIOCache *Cache, Uint64 Sector, void *Buffer ) Cache->CacheUsed ++; // Release Spinlock - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); // Return success return 1; @@ -207,9 +245,9 @@ int IOCache_Write( tIOCache *Cache, Uint64 Sector, void *Buffer ) if(!Cache || !Buffer) return -1; // Lock - LOCK( &Cache->Lock ); + Mutex_Acquire( &Cache->Lock ); if(Cache->CacheSize == 0) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return -1; } @@ -226,7 +264,7 @@ int IOCache_Write( tIOCache *Cache, Uint64 Sector, void *Buffer ) ent->LastWrite = 0; } - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return 1; } // It's a sorted list, so as soon as we go past `Sector` we know @@ -234,7 +272,7 @@ int IOCache_Write( tIOCache *Cache, Uint64 Sector, void *Buffer ) if(ent->Num > Sector) break; } - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return 0; } @@ -249,9 +287,9 @@ void IOCache_Flush( tIOCache *Cache ) if( Cache->Mode == IOCACHE_VIRTUAL ) return; // Lock - LOCK( &Cache->Lock ); + Mutex_Acquire( &Cache->Lock ); if(Cache->CacheSize == 0) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return; } @@ -262,7 +300,7 @@ void IOCache_Flush( tIOCache *Cache ) ent->LastWrite = 0; } - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); } /** @@ -274,9 +312,9 @@ void IOCache_Destroy( tIOCache *Cache ) tIOCache_Ent *ent, *prev = NULL; // Lock - LOCK( &Cache->Lock ); + Mutex_Acquire( &Cache->Lock ); if(Cache->CacheSize == 0) { - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); return; } @@ -294,24 +332,24 @@ void IOCache_Destroy( tIOCache *Cache ) Cache->CacheSize = 0; - RELEASE( &Cache->Lock ); + Mutex_Release( &Cache->Lock ); // Remove from list - LOCK( &glIOCache_Caches ); + SHORTLOCK( &glIOCache_Caches ); { - tIOCache *ent; - tIOCache *prev = (tIOCache*)&gIOCache_Caches; - for(ent = gIOCache_Caches; - ent; - prev = ent, ent = ent->Next ) + tIOCache *cache; + tIOCache *prev_cache = (tIOCache*)&gIOCache_Caches; + for(cache = gIOCache_Caches; + cache; + prev_cache = cache, cache = cache->Next ) { - if(ent == Cache) { - prev->Next = ent->Next; + if(cache == Cache) { + prev_cache->Next = cache->Next; break; } } } - RELEASE( &glIOCache_Caches ); + SHORTREL( &glIOCache_Caches ); free(Cache); }