AE_FORCEINLINE void fence(memory_order order) { // Non-specialized arch, use heavier memory barriers everywhere just in case :-( switch (order) { case memory_order_relaxed: break; case memory_order_acquire: _ReadBarrier(); AeLiteSync(); _ReadBarrier(); break; case memory_order_release: _WriteBarrier(); AeLiteSync(); _WriteBarrier(); break; case memory_order_acq_rel: _ReadWriteBarrier(); AeLiteSync(); _ReadWriteBarrier(); break; case memory_order_seq_cst: _ReadWriteBarrier(); AeFullSync(); _ReadWriteBarrier(); break; default: assert(false); } }
bool irsdkMemServer::finalizeHeader() { assert(!m_isHeaderFinalized); if(m_isInitialized && !m_isHeaderFinalized) { // copy our local header memcpy(pHeader, &localHeader, sizeof(localHeader)); // copy over the var header char *pBase = pSharedMem + localHeader.varHeaderOffset; memcpy(pBase, &localVarHeader, sizeof(localVarHeader)); // flush caches to all processors _WriteBarrier(); localHeader.status = irsdk_stConnected; pHeader->status = irsdk_stConnected; //should we fire an event? PulseEvent(hDataValidEvent); // only write header out once m_isHeaderFinalized = true; return true; } return false; }
void irsdkMemServer::shutdown() { //signal clients that we are going away if(pHeader) pHeader->status = 0; localHeader.status = 0; // flush caches to all processors _WriteBarrier(); if(hDataValidEvent) { //make sure event not left triggered (probably redundant) ResetEvent(hDataValidEvent); CloseHandle(hDataValidEvent); } if(pSharedMem) UnmapViewOfFile(pSharedMem); if(hMemMapFile) CloseHandle(hMemMapFile); hDataValidEvent = NULL; pSharedMem = NULL; pHeader = NULL; hMemMapFile = NULL; m_isInitialized = false; m_isHeaderFinalized = false; }
// Insert glyph sheets UINT STDMETHODCALLTYPE CFW1GlyphAtlas::InsertSheet(IFW1GlyphSheet *pGlyphSheet) { if(pGlyphSheet == NULL) return 0xffffffff; UINT sheetIndex = 0xffffffff; EnterCriticalSection(&m_glyphSheetsCriticalSection); if(m_sheetCount < m_maxSheetCount) { pGlyphSheet->AddRef(); sheetIndex = m_sheetCount; m_glyphSheets[sheetIndex] = pGlyphSheet; _WriteBarrier(); MemoryBarrier(); ++m_sheetCount; // Restrict the number of open sheets UINT numActiveSheets = 4; if(m_sheetCount > m_currentSheetIndex + numActiveSheets) { m_glyphSheets[m_currentSheetIndex]->CloseSheet(); ++m_currentSheetIndex; } } LeaveCriticalSection(&m_glyphSheetsCriticalSection); return sheetIndex; }
bool irsdkMemServer::pollSampleVars() { const irsdk_varHeader *rec; if(m_isInitialized) { char *pBase = pSharedMem + localHeader.varBuf[curBuf].bufOffset; // for each entry for(int index=0; index<localHeader.numVars; index++) { rec = &localVarHeader[index]; if(entryVarHelper[index].varPtr) { writeVar(localVarHeader[index].count, localVarHeader[index].type, entryVarHelper[index].multiplier, entryVarHelper[index].offset, entryVarHelper[index].varPtr, pBase + rec->offset); } } // flush caches to all processors _WriteBarrier(); // update indexes localHeader.varBuf[curBuf].tickCount = count; pHeader->varBuf[curBuf].tickCount = count; // flush caches to all processors _WriteBarrier(); // and signal new data PulseEvent(hDataValidEvent); // switch buffers curBuf = (curBuf+1) % irsdkMemServer::bufCount; // increment count count++; return true; } return false; }
void Win32_Raytrace_Work_Queue::add_entry(Raytrace_Work_Entry entry) { u32 new_next_entry_to_add = (this->next_entry_to_add + 1) % COUNT_OF(this->entries); assert(new_next_entry_to_add != this->next_entry_to_do); Raytrace_Work_Entry *entry_to_add = this->entries + this->next_entry_to_add; *entry_to_add = entry; _WriteBarrier(); this->next_entry_to_add = new_next_entry_to_add; ReleaseSemaphore(this->semaphore, 1, 0); }
void bar() { _ReadWriteBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} _ReadBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} _WriteBarrier(); // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}} // FIXME: It'd be handy if we didn't have to hardcode the line number in // intrin.h. // [email protected]:754 {{declared here}} // [email protected]:759 {{declared here}} // [email protected]:764 {{declared here}} }
AE_FORCEINLINE void compiler_fence(memory_order order) { switch (order) { case memory_order_relaxed: break; case memory_order_acquire: _ReadBarrier(); break; case memory_order_release: _WriteBarrier(); break; case memory_order_acq_rel: _ReadWriteBarrier(); break; case memory_order_seq_cst: _ReadWriteBarrier(); break; default: assert(false); } }
bool irsdkMemServer::startup() { if(!hMemMapFile) { hMemMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, irsdkMemServer::SharedMemSize, IRSDK_MEMMAPFILENAME); } if (hMemMapFile) { if(!pSharedMem) { pSharedMem = (char *)MapViewOfFile(hMemMapFile, FILE_MAP_ALL_ACCESS, 0, 0, irsdkMemServer::SharedMemSize); pHeader = (irsdk_header *)pSharedMem; } //****Warning, assuming pHeader is valid if pSharedMem is valid if(pSharedMem) { // zero shared memory memset(pSharedMem, 0, irsdkMemServer::SharedMemSize); //clear status untill we are fully initialized pHeader->status = 0; localHeader.status = 0; // flush caches to all processors _WriteBarrier(); if(!hDataValidEvent) hDataValidEvent = CreateEvent(NULL, true, false, IRSDK_DATAVALIDEVENTNAME); if(hDataValidEvent) { // ok all setup, allow access m_isInitialized = true; return true; } else printf("Could not create data valid event (%d).\n", GetLastError()); } else printf("Could not map view of file (%d).\n", GetLastError()); } else printf("Could not create file mapping object (%d).\n", GetLastError()); m_isInitialized = false; return false; }
// safe to call before m_isInitialized, only writes to localHeader bool irsdkMemServer::regSessionInfo(const char *str) { if(m_isInitialized) { if(str) { // only update if changed char *dest = (pSharedMem + localHeader.sessionInfoOffset); if(0 != strncmp(str, dest, localHeader.sessionInfoLen)) { strncpy(dest, str, localHeader.sessionInfoLen); dest[localHeader.sessionInfoLen-1] = '\0'; // flush caches to all processors _WriteBarrier(); localHeader.sessionInfoUpdate++; pHeader->sessionInfoUpdate = localHeader.sessionInfoUpdate; } } } return false; }
static FORCEINLINE VOID xen_wmb() { KeMemoryBarrier(); _WriteBarrier(); }
static FORCEINLINE VOID __WriteMemoryBarrier() { KeMemoryBarrier(); _WriteBarrier(); }
int main( int argc, char *argv[] ) { int i; HANDLE bgThread; DWORD exitCode; SECURITY_ATTRIBUTES semSec; MSEmul_UseSharedMemory(true); #if 1 { char test[256], *head; test[0] = '\0'; head = test; fprintf( stderr, "appending to test[%lu] with snprintf:\n", sizeof(test) ); do{ int len = strlen(test), n; size_t ni = strlen("0123456789"); fprintf( stderr, "len(test[%lu])=%d, rem. %lu added", sizeof(test), len, (size_t)(sizeof(test) - len) ); fflush(stderr); n = snprintf( &test[len], (size_t)(sizeof(test) - len), "0123456789" ); head += n; fprintf( stderr, " %d (head[%lu]=", n, head - test ); fflush(stderr); if( len + n < sizeof(test) ){ fprintf( stderr, "%c) -> %lu\n", head[0], strlen(test) ); } else{ fprintf( stderr, "!$@#) -> %lu\n", strlen(test) ); } } while( strlen(test) < sizeof(test)-1 ); fprintf( stderr, "test = %s\n", test ); } #endif init_HRTime(); tStart = HRTime_Time(); HRTime_tic(); { double t0; DWORD ret; HANDLE hh; if( (hh = CreateSemaphore( NULL, 1, 0x7FFFFFFF, NULL )) ){ t0 = HRTime_Time(); ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000)); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n", (DWORD)(SLEEPTIMEFG*1000), ret, t0 ); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000)); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n", (DWORD)(SLEEPTIMEFG*1000), ret, t0 ); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, 500); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds\n", ret, t0 ); ReleaseSemaphore(hh, 1, NULL); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, 500); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds after ReleaseSemaphore()\n", ret, t0 ); CloseHandle(hh); } else{ fprintf( stderr, "Error creating semaphore: %s\n", winError(GetLastError()) ); } ret = 0; YieldProcessor(); fprintf( stderr, "sizeof(long)=%lu\n", sizeof(long) ); _WriteBarrier(); { long oval, lbool; void *ptr = NULL, *optr; oval = _InterlockedCompareExchange( (long*) &ret, 10L, 0L ); fprintf( stderr, "_InterlockedCompareExchange(&ret==0, 10, 0) == %lu, ret==%lu\n", oval, ret ); optr = InterlockedCompareExchangePointer( &ptr, (void*) fprintf, NULL ); fprintf( stderr, "InterlockedCompareExchangePointer(&ptr==NULL, fprintf==%p, NULL) == %p, ret==%p\n", fprintf, optr, ptr ); _InterlockedIncrement( (long*) &ret ); fprintf( stderr, "_InterlockedIncrement(&ret) ret=%lu\n", ret ); _InterlockedDecrement( (long*) &ret ); fprintf( stderr, "_InterlockedDecrement(&ret) ret=%lu\n", ret ); _ReadWriteBarrier(); lbool = false; _InterlockedSetTrue(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); _InterlockedSetTrue(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); _InterlockedSetFalse(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); } } #ifdef DEBUG { CSEScopedLock *scope = ObtainCSEScopedLock(NULL); fprintf( stderr, "NULL testscope %p:locked==%u\n", scope, IsCSEScopeLocked(scope) ); scope = ReleaseCSEScopedLock(scope); } #endif csex = CreateCSEHandle(4000); if( !csex ){ fprintf( stderr, "Failure creating CSEHandle\n" ); exit(1); } else{ fprintf( stderr, "Created a '%s' CSEHandle with spinMax==%lu\n", CSEHandleInfo(csex), csex->spinMax ); } fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fputs( "\n", stderr ); if( (bgThread = CreateThread( NULL, 0, bgThreadSleeper, NULL, CREATE_SUSPENDED, NULL )) ){ unsigned long ret; double tEnd; fprintf( stderr, ">%lx t=%g will start %lx and WaitForSingleObject on it (should take 5s)\n", GetCurrentThreadId(), HRTime_Time() - tStart, GetThreadId(bgThread) ); ResumeThread(bgThread); // Sleep(1); ret = WaitForSingleObject( bgThread, 1500 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,1500)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 10000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,10000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } fputs( "\n", stderr ); if( (nudgeEvent = CreateEvent( NULL, false, false, NULL )) ){ if( (bgThread = CreateThread( NULL, 0, bgThread2Nudge, NULL, 0, NULL )) ){ unsigned long ret; double tEnd; Sleep(1000); fprintf( stderr, ">%lx t=%g SetEvent(nudgeEvent) = %d; sleep(1ms) and then wait for return nudge\n", GetCurrentThreadId(), HRTime_Time() - tStart, SetEvent(nudgeEvent) ); Sleep(1); ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time(); fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n", GetCurrentThreadId(), ret, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } CloseHandle(nudgeEvent); } fputs( "\n", stderr ); semSec.nLength = sizeof(SECURITY_ATTRIBUTES); semSec.lpSecurityDescriptor = NULL; semSec.bInheritHandle = true; // semSec does not actually need to be used: if( (nudgeEvent = CreateSemaphore( &semSec, 0, 0x7FFFFFFF, (char*) "cseSem" )) ){ if( (bgThread = CreateThread( NULL, 0, bgThread4SemTest, NULL, 0, NULL )) ){ unsigned long ret; double tEnd; Sleep(1000); fprintf( stderr, ">%lx t=%g ReleaseSemaphore(nudgeEvent,1,NULL) = %d; sleep(1ms) and then wait for return nudge\n", GetCurrentThreadId(), HRTime_Time() - tStart, ReleaseSemaphore(nudgeEvent, 1, NULL) ); Sleep(1); ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time(); fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n", GetCurrentThreadId(), ret, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } CloseHandle(nudgeEvent); } fputs( "\n", stderr ); if( (bgThread = CreateThread( NULL, 0, bgCSEXaccess, NULL, CREATE_SUSPENDED, NULL )) ){ fprintf( stderr, "csex is %slocked\n", (IsCSEHandleLocked(csex))? "" : "not " ); SetThreadPriority( bgThread, GetThreadPriority(GetCurrentThread()) ); fprintf( stderr, "GetThreadPriority(GetCurrentThread()) = %d\n", GetThreadPriority(GetCurrentThread()) ); ResumeThread(bgThread); i = 0; fprintf( stderr, "entering main csex locking loop at t=%gs\n", HRTime_toc() ); while( i < 5 ){ double t0, t1; if( IsCSEHandleLocked(csex) ){ fprintf( stderr, "\tmain loop waiting for csex lock\n" ); } t0 = HRTime_toc(); { #ifdef LOCKSCOPEFG CSEScopedLock *scope = ObtainCSEScopedLock(csex); #else unsigned char unlock = LockCSEHandle(csex); #endif t1 = HRTime_toc(); i += 1; fprintf( stderr, "> got csex lock #%d=%d at t=%g after %gs; starting %g s wait\n", i, IsCSEHandleLocked(csex), t1, t1-t0, SLEEPTIMEFG ); fflush(stderr); #ifdef BUSYSLEEPING MMSleep(SLEEPTIMEFG); #else do{ t1 = HRTime_toc(); } while (t1-t0 < SLEEPTIMEFG); #endif fprintf( stderr, "\tmain loop wait #%d ended at t=%gs; csex lock=%d\n", i, HRTime_toc(), IsCSEHandleLocked(csex) ); fflush(stderr); #ifndef LOCKSCOPEFG UnlockCSEHandle( csex, unlock ); #else scope = ReleaseCSEScopedLock(scope); #endif } // just to give the other thread a chance to get a lock: Sleep(1); } fprintf( stderr, "exiting main csex locking loop at t=%gs\n", HRTime_toc() ); _InterlockedSetFalse(&bgRun); WaitForSingleObject( bgThread, 5000 ); CloseHandle(bgThread); fprintf( stderr, "Background loop finished at t=%gs\n", HRTime_toc() ); } else{ fprintf( stderr, "Failure creating bgCSEXaccess thread\n" ); } DeleteCSEHandle(csex); ASSERT(1); ASSERT(0); exit(0); }