objrtn Association_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (Association_c) { LEAVECRITICALSECTION(cs); return Association_c; } INHIBIT_THREADER; Association_c = gNewClass(Class, "Association", 0, 0, END); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return Association_c; }
objrtn ArgumentList_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (ArgumentList_c) { LEAVECRITICALSECTION(cs); return ArgumentList_c; } INHIBIT_THREADER; LinkObject_initialize(); if (ArgumentList_c) { ENABLE_THREADER; LEAVECRITICALSECTION(cs); return ArgumentList_c; } ArgumentList_c = gNewClass(Class, "ArgumentList", 0, 0, LinkObject, END); cMethodFor(ArgumentList, gNew, ArgumentList_cm_gNew); cMethodFor(ArgumentList, gNewArglist, ArgumentList_cm_gNewArglist); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return ArgumentList_c; }
objrtn InputStream_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (InputStream_c) { LEAVECRITICALSECTION(cs); return InputStream_c; } INHIBIT_THREADER; InputStream_c = gNewClass(Class, "InputStream", sizeof(InputStream_iv_t), 0, END); cMethodFor(InputStream, gNewWithStr, InputStream_cm_gNewWithStr); cMethodFor(InputStream, gNew, InputStream_cm_gNew); iMethodFor(InputStream, gDispose, InputStream_im_gDispose); iMethodFor(InputStream, gGCDispose, InputStream_im_gGCDispose); iMethodFor(InputStream, gLineHasColon, InputStream_im_gLineHasColon); iMethodFor(InputStream, gNextToken, InputStream_im_gNextToken); iMethodFor(InputStream, gDeepDispose, InputStream_im_gDispose); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return InputStream_c; }
objrtn SeriousCondition_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (SeriousCondition_c) { LEAVECRITICALSECTION(cs); return SeriousCondition_c; } INHIBIT_THREADER; Condition_initialize(); if (SeriousCondition_c) { ENABLE_THREADER; LEAVECRITICALSECTION(cs); return SeriousCondition_c; } SeriousCondition_c = gNewClass(Class, "SeriousCondition", 0, 0, Condition, END); iMethodFor(SeriousCondition, gDefaultRestart, SeriousCondition_im_gDefaultRestart); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return SeriousCondition_c; }
objrtn UnsignedShortInteger_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (UnsignedShortInteger_c) { LEAVECRITICALSECTION(cs); return UnsignedShortInteger_c; } INHIBIT_THREADER; Number_initialize(); if (UnsignedShortInteger_c) { ENABLE_THREADER; LEAVECRITICALSECTION(cs); return UnsignedShortInteger_c; } UnsignedShortInteger_c = gNewClass(Class, "UnsignedShortInteger", sizeof(UnsignedShortInteger_iv_t), 0, Number, END); cMethodFor(UnsignedShortInteger, gNewWithUnsigned, UnsignedShortInteger_cm_gNewWithUnsigned); iMethodFor(UnsignedShortInteger, gUnsignedShortValue, UnsignedShortInteger_im_gUnsignedShortValue); iMethodFor(UnsignedShortInteger, gChangeDoubleValue, UnsignedShortInteger_im_gChangeDoubleValue); iMethodFor(UnsignedShortInteger, gDoubleValue, UnsignedShortInteger_im_gDoubleValue); iMethodFor(UnsignedShortInteger, gCompare, UnsignedShortInteger_im_gCompare); iMethodFor(UnsignedShortInteger, gChangeLongValue, UnsignedShortInteger_im_gChangeLongValue); iMethodFor(UnsignedShortInteger, gChangeShortValue, UnsignedShortInteger_im_gChangeShortValue); iMethodFor(UnsignedShortInteger, gShortValue, UnsignedShortInteger_im_gShortValue); iMethodFor(UnsignedShortInteger, gPointerValue, UnsignedShortInteger_im_gPointerValue); iMethodFor(UnsignedShortInteger, gCharValue, UnsignedShortInteger_im_gCharValue); iMethodFor(UnsignedShortInteger, gStringRepValue, UnsignedShortInteger_im_gStringRepValue); iMethodFor(UnsignedShortInteger, gChangeUShortValue, UnsignedShortInteger_im_gChangeUShortValue); iMethodFor(UnsignedShortInteger, gHash, UnsignedShortInteger_im_gHash); iMethodFor(UnsignedShortInteger, gChangeValue, UnsignedShortInteger_im_gChangeValue); iMethodFor(UnsignedShortInteger, gLongValue, UnsignedShortInteger_im_gLongValue); iMethodFor(UnsignedShortInteger, gChangeCharValue, UnsignedShortInteger_im_gChangeCharValue); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return UnsignedShortInteger_c; }
void MA_compact(void) { MemBlk *mb; Header *fh, *mfh = NULL; int i; ENTERCRITICALSECTION(CS); for (mb=MMBP ; mb ; mb = mb->next) { fh = compact(mb); if (fh) { fh->next = mfh; mfh = fh; } } for (i=0 ; Map[i].userBytes ; ++i) Map[i].h = NULL; while (fh = mfh) { mfh = fh->next; fh->status = 'U'; fh->next = NULL; MA_free(fh+1); } LEAVECRITICALSECTION(CS); }
void asCThreadManager::Unprepare() { asASSERT(threadManager); if( threadManager == 0 ) return; // It's necessary to protect this section so no // other thread attempts to call AddRef or Release // while clean up is in progress. ENTERCRITICALSECTION(threadManager->criticalSection); if( --threadManager->refCount == 0 ) { // Make sure the local data is destroyed, at least for the current thread CleanupLocalData(); // As the critical section will be destroyed together // with the thread manager we must first clear the global // variable in case a new thread manager needs to be created; asCThreadManager *mgr = threadManager; threadManager = 0; // Leave the critical section before it is destroyed LEAVECRITICALSECTION(mgr->criticalSection); asDELETE(mgr,asCThreadManager); } else LEAVECRITICALSECTION(threadManager->criticalSection); }
int asCModule::AddModuleRef() { ENTERCRITICALSECTION(criticalSection); int r = ++moduleCount; LEAVECRITICALSECTION(criticalSection); return r; }
asCThreadLocalData *asCThreadManager::GetLocalData() { if( threadManager == 0 ) return 0; #ifndef AS_NO_THREADS #if defined AS_POSIX_THREADS asPWORD id = (asPWORD)pthread_self(); #elif defined AS_WINDOWS_THREADS asPWORD id = (asPWORD)GetCurrentThreadId(); #endif ENTERCRITICALSECTION(threadManager->criticalSection); asCThreadLocalData *tld = threadManager->GetLocalData(id); if( tld == 0 ) { // Create a new tld tld = asNEW(asCThreadLocalData)(); if( tld ) threadManager->SetLocalData(id, tld); } LEAVECRITICALSECTION(threadManager->criticalSection); return tld; #else if( threadManager->tld == 0 ) threadManager->tld = asNEW(asCThreadLocalData)(); return threadManager->tld; #endif }
int asCGarbageCollector::GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asIObjectType **type) { if( seqNbr ) *seqNbr = 0; if( obj ) *obj = 0; if( type ) *type = 0; ENTERCRITICALSECTION(gcCritical); asSObjTypePair *o = 0; asUINT newObjs = gcNewObjects.GetLength(); if( idx < newObjs ) o = &gcNewObjects[idx]; else if( idx < gcOldObjects.GetLength() + newObjs ) o = &gcOldObjects[idx-newObjs]; else { LEAVECRITICALSECTION(gcCritical); return asINVALID_ARG; } if( seqNbr ) *seqNbr = o->seqNbr; if( obj ) *obj = o->obj; if( type ) *type = o->type; LEAVECRITICALSECTION(gcCritical); return asSUCCESS; }
int asCModule::AddContextRef() { ENTERCRITICALSECTION(criticalSection); int r = ++contextCount; LEAVECRITICALSECTION(criticalSection); return r; }
void asCGarbageCollector::IncreaseCounterForNewObject(int idx) { // We need to protect this update with a critical section as // another thread might be appending an object at the same time ENTERCRITICALSECTION(gcCritical); gcNewObjects[idx].count++; LEAVECRITICALSECTION(gcCritical); }
asDWORD asCAtomic::atomicDec() { asDWORD v; ENTERCRITICALSECTION(cs); v = --value; LEAVECRITICALSECTION(cs); return v; }
int asCModule::ReleaseModuleRef() { ENTERCRITICALSECTION(criticalSection); int r = --moduleCount; LEAVECRITICALSECTION(criticalSection); return r; }
int asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType) { if( obj == 0 || objType == 0 ) { engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GC_RECEIVED_NULL_PTR); return asINVALID_ARG; } engine->CallObjectMethod(obj, objType->beh.addref); asSObjTypePair ot = {obj, objType, 0}; // Invoke the garbage collector to destroy a little garbage as new comes in // This will maintain the number of objects in the GC at a maintainable level without // halting the application, and without burdening the application with manually invoking the // garbage collector. if( engine->ep.autoGarbageCollect && gcNewObjects.GetLength() ) { // If the GC is already processing in another thread, then don't try this again if( TRYENTERCRITICALSECTION(gcCollecting) ) { // Skip this if the GC is already running in this thread if( !isProcessing ) { isProcessing = true; // TODO: The number of iterations should be dynamic, and increase // if the number of objects in the garbage collector grows high // Run one step of DetectGarbage if( gcOldObjects.GetLength() ) { IdentifyGarbageWithCyclicRefs(); DestroyOldGarbage(); } // Run a few steps of DestroyGarbage int iter = (int)gcNewObjects.GetLength(); if( iter > 10 ) iter = 10; while( iter-- > 0 ) DestroyNewGarbage(); isProcessing = false; } LEAVECRITICALSECTION(gcCollecting); } } // Add the data to the gcObjects array in a critical section as // another thread might be calling this method at the same time ENTERCRITICALSECTION(gcCritical); ot.seqNbr = numAdded++; gcNewObjects.PushLast(ot); LEAVECRITICALSECTION(gcCritical); return ot.seqNbr; }
void asCGarbageCollector::MoveAllObjectsToOldList() { // We need to protect this update with a critical section as // another thread might be appending an object at the same time ENTERCRITICALSECTION(gcCritical); if( gcOldObjects.Concatenate(gcNewObjects) ) gcNewObjects.SetLength(0); LEAVECRITICALSECTION(gcCritical); }
asCGarbageCollector::asSObjTypePair asCGarbageCollector::GetOldObjectAtIdx(int idx) { // We need to protect this access with a critical section as // another thread might be appending an object at the same time ENTERCRITICALSECTION(gcCritical); asSObjTypePair gcObj = gcOldObjects[idx]; LEAVECRITICALSECTION(gcCritical); return gcObj; }
objrtn BufferedTempFile_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (BufferedTempFile_c) { LEAVECRITICALSECTION(cs); return BufferedTempFile_c; } INHIBIT_THREADER; BufferedTempFile_c = gNewClass(Class, "BufferedTempFile", sizeof(BufferedTempFile_iv_t), 0, END); cMethodFor(BufferedTempFile, gOpenTempFile, BufferedTempFile_cm_gOpenTempFile); iMethodFor(BufferedTempFile, gFlush, BufferedTempFile_im_gFlush); iMethodFor(BufferedTempFile, gRetreat, BufferedTempFile_im_gRetreat); iMethodFor(BufferedTempFile, gPosition, BufferedTempFile_im_gPosition); iMethodFor(BufferedTempFile, gLength, BufferedTempFile_im_gLength); iMethodFor(BufferedTempFile, gWrite, BufferedTempFile_im_gWrite); iMethodFor(BufferedTempFile, gEndOfStream, BufferedTempFile_im_gEndOfStream); iMethodFor(BufferedTempFile, gSeek, BufferedTempFile_im_gSeek); iMethodFor(BufferedTempFile, gPointerValue, BufferedTempFile_im_gPointerValue); iMethodFor(BufferedTempFile, gAdvance, BufferedTempFile_im_gAdvance); iMethodFor(BufferedTempFile, gDispose, BufferedTempFile_im_gDispose); iMethodFor(BufferedTempFile, gName, BufferedTempFile_im_gName); iMethodFor(BufferedTempFile, gGets, BufferedTempFile_im_gGets); iMethodFor(BufferedTempFile, gGCDispose, BufferedTempFile_im_gGCDispose); iMethodFor(BufferedTempFile, gDeepDispose, BufferedTempFile_im_gDispose); iMethodFor(BufferedTempFile, gRead, BufferedTempFile_im_gRead); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return BufferedTempFile_c; }
objrtn ObjectPool_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (ObjectPool_c) { LEAVECRITICALSECTION(cs); return ObjectPool_c; } INHIBIT_THREADER; ObjectPool_c = gNewClass(Class, "ObjectPool", sizeof(ObjectPool_iv_t), sizeof(ObjectPool_cv_t), END); cMethodFor(ObjectPool, gNewGlobalPoolWithSize, ObjectPool_cm_gNewGlobalPoolWithSize); cMethodFor(ObjectPool, gDisposeGlobalPool, ObjectPool_cm_gDisposeGlobalPool); cMethodFor(ObjectPool, gRemoveFromPool, ObjectPool_cm_gRemoveFromPool); cMethodFor(ObjectPool, gNewWithInt, ObjectPool_cm_gNewWithInt); cMethodFor(ObjectPool, gAddToPool, ObjectPool_cm_gAddToPool); cMethodFor(ObjectPool, gNew, ObjectPool_cm_gNew); cMethodFor(ObjectPool, gNewGlobalPool, ObjectPool_cm_gNewGlobalPool); cMethodFor(ObjectPool, gDisposeObject, ObjectPool_cm_gDisposeObject); iMethodFor(ObjectPool, gRemoveFromPool, ObjectPool_im_gRemoveFromPool); iMethodFor(ObjectPool, gAddToPool, ObjectPool_im_gAddToPool); iMethodFor(ObjectPool, gDispose, ObjectPool_im_gDispose); iMethodFor(ObjectPool, gDeepDispose, ObjectPool_im_gDispose); iMethodFor(ObjectPool, gDisposeObject, ObjectPool_im_gDisposeObject); ObjectPool_cv = GetCVs(ObjectPool); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return ObjectPool_c; }
void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType) { engine->CallObjectMethod(obj, objType->beh.addref); asSObjTypePair ot = {obj, objType}; // Add the data to the gcObjects array in a critical section as // another thread might be calling this method at the same time ENTERCRITICALSECTION(gcCritical); gcObjects.PushLast(ot); LEAVECRITICALSECTION(gcCritical); }
void asCGarbageCollector::RemoveOldObjectAtIdx(int idx) { // We need to protect this update with a critical section as // another thread might be appending an object at the same time ENTERCRITICALSECTION(gcCritical); if( idx == (int)gcOldObjects.GetLength() - 1) gcOldObjects.PopLast(); else gcOldObjects[idx] = gcOldObjects.PopLast(); LEAVECRITICALSECTION(gcCritical); }
void asCMemoryMgr::FreeScriptNode(void *ptr) { ENTERCRITICALSECTION(cs); // Pre allocate memory for the array to avoid slow growth if( scriptNodePool.GetLength() == 0 ) scriptNodePool.Allocate(100, 0); scriptNodePool.PushLast(ptr); LEAVECRITICALSECTION(cs); }
objrtn PointerArray_initialize(void) { static CRITICALSECTION cs; static int volatile once = 0; ENTERCRITICALSECTION(_CI_CS_); if (!once) { INITIALIZECRITICALSECTION(cs); once = 1; } LEAVECRITICALSECTION(_CI_CS_); ENTERCRITICALSECTION(cs); if (PointerArray_c) { LEAVECRITICALSECTION(cs); return PointerArray_c; } INHIBIT_THREADER; Array_initialize(); if (PointerArray_c) { ENABLE_THREADER; LEAVECRITICALSECTION(cs); return PointerArray_c; } PointerArray_c = gNewClass(Class, "PointerArray", 0, 0, Array, END); cvMethodFor(PointerArray, vNew, PointerArray_cvm_vNew, PointerArray_cfm_vNew); ivMethodFor(PointerArray, vChangeValue, PointerArray_ivm_vChangeValue, PointerArray_ifm_vChangeValue); ivMethodFor(PointerArray, vPointerValue, PointerArray_ivm_vPointerValue, PointerArray_ifm_vPointerValue); init_class(); ENABLE_THREADER; LEAVECRITICALSECTION(cs); return PointerArray_c; }
int asCThreadManager::CleanupLocalData() { if( threadManager == 0 ) return 0; #ifndef AS_NO_THREADS int r = 0; #if defined AS_POSIX_THREADS asPWORD id = (asPWORD)pthread_self(); #elif defined AS_WINDOWS_THREADS asPWORD id = (asPWORD)GetCurrentThreadId(); #endif ENTERCRITICALSECTION(threadManager->criticalSection); asSMapNode<asPWORD,asCThreadLocalData*> *cursor = 0; if( threadManager->tldMap.MoveTo(&cursor, id) ) { asCThreadLocalData *tld = threadManager->tldMap.GetValue(cursor); // Can we really remove it at this time? if( tld->activeContexts.GetLength() == 0 ) { asDELETE(tld,asCThreadLocalData); threadManager->tldMap.Erase(cursor); r = 0; } else r = asCONTEXT_ACTIVE; } LEAVECRITICALSECTION(threadManager->criticalSection); return r; #else if( threadManager->tld ) { if( threadManager->tld->activeContexts.GetLength() == 0 ) { asDELETE(threadManager->tld,asCThreadLocalData); threadManager->tld = 0; } else return asCONTEXT_ACTIVE; } return 0; #endif }
void *asCMemoryMgr::AllocScriptNode() { ENTERCRITICALSECTION(cs); if( scriptNodePool.GetLength() ) { void *tRet = scriptNodePool.PopLast(); LEAVECRITICALSECTION(cs); return tRet; } LEAVECRITICALSECTION(cs); #if defined(AS_DEBUG) return ((asALLOCFUNCDEBUG_t)(userAlloc))(sizeof(asCScriptNode), __FILE__, __LINE__); #else return userAlloc(sizeof(asCScriptNode)); #endif }
void asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType) { engine->CallObjectMethod(obj, objType->beh.addref); asSObjTypePair ot = {obj, objType, 0}; // Invoke the garbage collector to destroy a little garbage as new comes in // This will maintain the number of objects in the GC at a maintainable level without // halting the application, and without burdening the application with manually invoking the // garbage collector. if( engine->ep.autoGarbageCollect && gcNewObjects.GetLength() ) { // If the GC is already processing in another thread, then don't try this again // TODO: What if it is already processing in this thread? if( TRYENTERCRITICALSECTION(gcCollecting) ) { // TODO: The number of iterations should be dynamic, and increase // if the number of objects in the garbage collector grows high // Run one step of DetectGarbage if( gcOldObjects.GetLength() ) { IdentifyGarbageWithCyclicRefs(); DestroyOldGarbage(); } // Run a few steps of DestroyGarbage int iter = (int)gcNewObjects.GetLength(); if( iter > 10 ) iter = 10; while( iter-- > 0 ) DestroyNewGarbage(); LEAVECRITICALSECTION(gcCollecting); } } // Add the data to the gcObjects array in a critical section as // another thread might be calling this method at the same time ENTERCRITICALSECTION(gcCritical); gcNewObjects.PushLast(ot); LEAVECRITICALSECTION(gcCritical); }
void asCThreadManager::Prepare() { // The critical section cannot be declared globally, as there is no // guarantee for the order in which global variables are initialized // or uninitialized. // For this reason it's not possible to prevent two threads from calling // AddRef at the same time, so there is a chance for a race condition here. // To avoid the race condition when the thread manager is first created, // the application must make sure to call the global asPrepareForMultiThread() // in the main thread before any other thread creates a script engine. if( threadManager == 0 ) threadManager = asNEW(asCThreadManager); else { ENTERCRITICALSECTION(threadManager->criticalSection); threadManager->refCount++; LEAVECRITICALSECTION(threadManager->criticalSection); } }
void asCMemoryMgr::FreeUnusedMemory() { // It's necessary to protect the scriptNodePool from multiple // simultaneous accesses, as the parser is used by several methods // that can be executed simultaneously. ENTERCRITICALSECTION(cs); int n; for( n = 0; n < (signed)scriptNodePool.GetLength(); n++ ) userFree(scriptNodePool[n]); scriptNodePool.Allocate(0, false); LEAVECRITICALSECTION(cs); // The engine already protects against multiple threads // compiling scripts simultaneously so this pool doesn't have // to be protected again. for( n = 0; n < (signed)byteInstructionPool.GetLength(); n++ ) userFree(byteInstructionPool[n]); byteInstructionPool.Allocate(0, false); }
void *MA_realloc(void *arg, unsigned n) { char *m; Header *h = (Header *) arg; ENTERCRITICALSECTION(CS); if (!h || (--h)->status != 'U') { LEAVECRITICALSECTION(CS); return NULL; } if (h->size >= n) { h->rsize = n; LEAVECRITICALSECTION(CS); return h+1; } m = (char *) MA_malloc(n, h->next); memcpy(m, h+1, h->rsize); h->next = NULL; MA_free(h+1); LEAVECRITICALSECTION(CS); return m; }
void MA_free(void *arg) { int i; Header *h = (Header *) arg; ENTERCRITICALSECTION(CS); if (!h || (--h)->status != 'U') { LEAVECRITICALSECTION(CS); return; } for (i=1 ; Map[i].userBytes && Map[i].userBytes <= h->size ; ++i); i--; h->status = 'F'; if (h->next) *((char **) h->next) = NULL; h->next = Map[i].h; Map[i].h = h; LEAVECRITICALSECTION(CS); }