diff options
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c')
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c index 1fb18fbb87e2..bc5f0830a37b 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c @@ -26,6 +26,9 @@ /******************************************************************************* ***** Private fuctions ********************************************************/ +#define _GetSlot(database, x) \ + (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list))) + /******************************************************************************* ** gckKERNEL_NewDatabase ** @@ -56,6 +59,7 @@ gckKERNEL_NewDatabase( gcsDATABASE_PTR database; gctBOOL acquired = gcvFALSE; gctSIZE_T slot; + gcsDATABASE_PTR existingDatabase; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID); @@ -63,6 +67,21 @@ gckKERNEL_NewDatabase( gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE)); acquired = gcvTRUE; + /* Compute the hash for the database. */ + slot = ProcessID % gcmCOUNTOF(Kernel->db->db); + + /* Walk the hash list. */ + for (existingDatabase = Kernel->db->db[slot]; + existingDatabase != gcvNULL; + existingDatabase = existingDatabase->next) + { + if (existingDatabase->processID == ProcessID) + { + /* One process can't be added twice. */ + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + } + if (Kernel->db->freeDatabase != gcvNULL) { /* Allocate a database from the free list. */ @@ -81,9 +100,6 @@ gckKERNEL_NewDatabase( database = pointer; } - /* Compute the hash for the database. */ - slot = ProcessID % gcmCOUNTOF(Kernel->db->db); - /* Insert the database into the hash. */ database->next = Kernel->db->db[slot]; Kernel->db->db[slot] = database; @@ -350,6 +366,7 @@ static gceSTATUS gckKERNEL_NewRecord( IN gckKERNEL Kernel, IN gcsDATABASE_PTR Database, + IN gctUINT32 Slot, OUT gcsDATABASE_RECORD_PTR * Record ) { @@ -383,8 +400,8 @@ gckKERNEL_NewRecord( } /* Insert the record in the database. */ - record->next = Database->list; - Database->list = record; + record->next = Database->list[Slot]; + Database->list[Slot] = record; /* Release the database mutex. */ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex)); @@ -449,6 +466,7 @@ gckKERNEL_DeleteRecord( gceSTATUS status; gctBOOL acquired = gcvFALSE; gcsDATABASE_RECORD_PTR record, previous; + gctUINT32 slot = _GetSlot(Database, Data); gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x", Kernel, Database, Type, Data); @@ -458,8 +476,9 @@ gckKERNEL_DeleteRecord( gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE)); acquired = gcvTRUE; + /* Scan the database for this record. */ - for (record = Database->list, previous = gcvNULL; + for (record = Database->list[slot], previous = gcvNULL; record != gcvNULL; record = record->next ) @@ -490,7 +509,7 @@ gckKERNEL_DeleteRecord( /* Remove record from database. */ if (previous == gcvNULL) { - Database->list = record->next; + Database->list[slot] = record->next; } else { @@ -557,6 +576,7 @@ gckKERNEL_FindRecord( gceSTATUS status; gctBOOL acquired = gcvFALSE; gcsDATABASE_RECORD_PTR record; + gctUINT32 slot = _GetSlot(Database, Data); gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x", Kernel, Database, Type, Data); @@ -567,7 +587,7 @@ gckKERNEL_FindRecord( acquired = gcvTRUE; /* Scan the database for this record. */ - for (record = Database->list; + for (record = Database->list[slot]; record != gcvNULL; record = record->next ) @@ -642,6 +662,7 @@ gckKERNEL_CreateProcessDB( { gceSTATUS status; gcsDATABASE_PTR database = gcvNULL; + gctUINT32 i; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID); @@ -668,7 +689,11 @@ gckKERNEL_CreateProcessDB( database->mapUserMemory.bytes = 0; database->mapUserMemory.maxBytes = 0; database->mapUserMemory.totalBytes = 0; - database->list = gcvNULL; + + for (i = 0; i < gcmCOUNTOF(database->list); i++) + { + database->list[i] = gcvNULL; + } #if gcdSECURE_USER { @@ -848,7 +873,7 @@ gckKERNEL_AddProcessDB( gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database)); /* Create a new record in the database. */ - gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, &record)); + gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record)); /* Initialize the record. */ record->kernel = Kernel; @@ -1086,6 +1111,7 @@ gckKERNEL_DestroyProcessDB( gctPHYS_ADDR physical; gcuVIDMEM_NODE_PTR node; gckKERNEL kernel = Kernel; + gctUINT32 i; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID); @@ -1126,8 +1152,11 @@ gckKERNEL_DestroyProcessDB( ProcessID); } + for(i = 0; i < gcmCOUNTOF(database->list); i++) + { + /* Walk all records. */ - for (record = database->list; record != gcvNULL; record = next) + for (record = database->list[i]; record != gcvNULL; record = next) { /* Next next record. */ next = record->next; @@ -1293,6 +1322,8 @@ gckKERNEL_DestroyProcessDB( gcvNULL)); } + } + /* Delete the database. */ gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database)); |