static void DaoMT_Critical( DaoProcess *proc, DaoValue *p[], int n ) { void *key; DNode *it; DMap *cache = (DMap*) DaoProcess_GetAuxData( proc, DaoMT_ProcMutexCache ); DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 ); DaoRoutine *routine = proc->activeRoutine; if( sect == NULL ) return; /* Get the original routine, if this one is a specialized copy: */ while( routine->original ) routine = routine->original; /* // Use "routine + sect->c" instead of "sect" as the key for mutex, // as "sect" may be different for different copy of specialized routine. // But "sect->c" won't change after being set during compiling. */ key = routine + sect->c; if( cache == NULL ){ cache = DHash_New(0,0); /* Local cache is used to avoid extra locking; */ DaoProcess_SetAuxData( proc, DaoMT_ProcMutexCache, cache ); } it = DMap_Find( cache, key ); /* Check local cache first; */ if( it == NULL ) it = DMap_Insert( cache, key, DaoMT_GetMutex( routine, key ) ); DMutex_Lock( (DMutex*) it->value.pVoid ); DaoProcess_Execute( proc ); DMutex_Unlock( (DMutex*) it->value.pVoid ); DaoProcess_PopFrame( proc ); }
static DMap* DaoProcess_GetTimeMap( DaoProcess *self ) { DMap *mapTime = (DMap*) DaoProcess_GetAuxData( self, DMap_DeleteTimeMap ); if( mapTime ) return mapTime; mapTime = DHash_New( 0, DAO_DATA_VALUE ); DaoProcess_SetAuxData( self, DMap_DeleteTimeMap, mapTime ); return mapTime; }