// Destructor. ~win_fenced_block() { #if defined(__BORLANDC__) LONG barrier = 0; ::InterlockedExchange(&barrier, 1); #elif defined(BOOST_MSVC) && ((BOOST_MSVC < 1400) || !defined(MemoryBarrier)) # if defined(_M_IX86) # pragma warning(push) # pragma warning(disable:4793) LONG barrier; __asm { xchg barrier, eax } # pragma warning(pop) # endif // defined(_M_IX86) #else MemoryBarrier(); #endif }
uintptr_t InsertionRoutine(void* arg) { InsertionArg* arg_data = static_cast<InsertionArg*>(arg); while (*arg_data->begin_running == 0); MemoryBarrier(); AtomicHashTable* hash_table = arg_data->hash_table; const uint32_t begin = arg_data->begin_num; const uint32_t count = arg_data->num_insertions; for (uint32_t i = 0; i < count; ++i) { uint32_t value = begin + i; hash_table->Insert(&value, sizeof(value), &value, sizeof(value)); } return 0; }
size_t AtomicQueue::CurrentSize() const { const uint64_t cur_head = mHead; const uint64_t cur_tail = mTail; MemoryBarrier(); const uint64_t size = static_cast<uint64_t>(mItemSize); const uint64_t cur_head_num = GET_NUM(cur_head); const uint64_t cur_tail_num = GET_NUM(cur_tail); if (cur_head_num == cur_tail_num) { // Empty if the counters match, full otherwise. return (cur_head == cur_tail) ? 0 : mItemSize; } else if (cur_tail_num > cur_head_num) { return static_cast<size_t>((cur_tail_num - cur_head_num) / size); } else { const uint64_t looped_tail = cur_tail_num + (size * mNumItems); return static_cast<size_t>((looped_tail - cur_head_num) / size); } }
KOKKOS_FORCEINLINE_FUNCTION void memory_fence() { #if defined( __KALMAR_CC__ ) ; #elif defined( KOKKOS_ATOMICS_USE_CUDA ) __threadfence(); #elif defined( KOKKOS_ATOMICS_USE_GCC ) || \ ( defined( KOKKOS_COMPILER_NVCC ) && defined( KOKKOS_ATOMICS_USE_INTEL ) ) __sync_synchronize(); #elif defined( KOKKOS_ATOMICS_USE_INTEL ) _mm_mfence(); #elif defined( KOKKOS_ATOMICS_USE_OMP31 ) #pragma omp flush #elif defined( KOKKOS_ATOMICS_USE_WINDOWS ) MemoryBarrier(); #else #error "Error: memory_fence() not defined" #endif }
/** * Frees resources used by a work queue. * * \param WorkQueue A work queue object. */ VOID PhDeleteWorkQueue( _Inout_ PPH_WORK_QUEUE WorkQueue ) { PLIST_ENTRY listEntry; PPH_WORK_QUEUE_ITEM workQueueItem; #ifdef DEBUG ULONG index; #endif #ifdef DEBUG PhAcquireQueuedLockExclusive(&PhDbgWorkQueueListLock); if ((index = PhFindItemList(PhDbgWorkQueueList, WorkQueue)) != -1) PhRemoveItemList(PhDbgWorkQueueList, index); PhReleaseQueuedLockExclusive(&PhDbgWorkQueueListLock); #endif // Wait for all worker threads to exit. WorkQueue->Terminating = TRUE; MemoryBarrier(); if (WorkQueue->SemaphoreHandle) NtReleaseSemaphore(WorkQueue->SemaphoreHandle, WorkQueue->CurrentThreads, NULL); PhWaitForRundownProtection(&WorkQueue->RundownProtect); // Free all un-executed work items. listEntry = WorkQueue->QueueListHead.Flink; while (listEntry != &WorkQueue->QueueListHead) { workQueueItem = CONTAINING_RECORD(listEntry, PH_WORK_QUEUE_ITEM, ListEntry); listEntry = listEntry->Flink; PhpDestroyWorkQueueItem(workQueueItem); } if (WorkQueue->SemaphoreHandle) NtClose(WorkQueue->SemaphoreHandle); }
FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer, PWSTR Marker, PVOID Buffer, ULONG Length, PULONG PBytesTransferred) { FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; MemoryBarrier(); if (0 != DirBuffer) { AcquireSRWLockShared(&DirBuffer->Lock); PULONG Index = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark); ULONG Count = (DirBuffer->Capacity - DirBuffer->HiMark) / sizeof(ULONG); ULONG IndexNum; FSP_FSCTL_DIR_INFO *DirInfo; if (0 == Marker) IndexNum = 0; else { FspFileSystemSearchDirectoryBuffer(DirBuffer, Marker, lstrlenW(Marker), &IndexNum); IndexNum++; } for (; IndexNum < Count; IndexNum++) { DirInfo = (PVOID)(DirBuffer->Buffer + Index[IndexNum]); if (!FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred)) { ReleaseSRWLockShared(&DirBuffer->Lock); return; } } ReleaseSRWLockShared(&DirBuffer->Lock); } FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred); }
void interlocked_queue_push(interlocked_queue_t* q, void* data) { interlocked_queue_node_t* node = new_interlocked_queue_node(); interlocked_queue_node_t* t = nullptr; interlocked_queue_node_t* next = nullptr; void* volatile* hazards[1] = { nullptr }; void* key = allocate_hazard_pointers(1, hazards); if(!hazards[0]) { RaiseException(ERROR_NOT_ENOUGH_MEMORY, 0, 0, nullptr); return; } node->data = data; for(;;) { t = q->tail; *hazards[0] = t; MemoryBarrier(); if(q->tail != t) { continue; } next = t->next; if(q->tail != t) { continue; } if(next != nullptr) { casp((void* volatile*)&q->tail, t, next); continue; } if(casp((void* volatile*)&t->next, nullptr, node)) { break; } } casp((void* volatile*)&q->tail, t, node); deallocate_hazard_pointers(key); }
//Perhaps use cat to get the characters into a known location that the linker can't mess with? static void UpdateFb() { for (unsigned int cy = 0; cy < fbinfo.cbheight; cy++){ for (unsigned int cx = 0; cx < fbinfo.cbwidth; cx++){ unsigned int char_offset = (cy * fbinfo.cbwidth) + cx; unsigned int fb_bx = (cx * CHAR_WIDTH) + fbinfo.xoffs; unsigned int fb_by = (cy * CHAR_HEIGHT) + fbinfo.yoffs; unsigned int char_index = fbinfo.cb[char_offset].c; unsigned int bgr = fbinfo.cb[char_offset].bgr; unsigned int bgg = fbinfo.cb[char_offset].bgg; unsigned int bgb = fbinfo.cb[char_offset].bgb; unsigned int fgr = fbinfo.cb[char_offset].fgr; unsigned int fgg = fbinfo.cb[char_offset].fgg; unsigned int fgb = fbinfo.cb[char_offset].fgb; for (unsigned int y = 0; y < CHAR_HEIGHT; y++){ for (unsigned int x = 0; x < CHAR_WIDTH; x++){ unsigned int fb_x = fb_bx + x; unsigned int fb_y = fb_by + y; unsigned int v = fbinfo.charpix[char_index * CHAR_WIDTH * CHAR_HEIGHT + y * CHAR_WIDTH + x]; unsigned int fb_offset = fb_y * fbinfo.pitch + fb_x*3; unsigned char r = (bgr * (255 - v) + fgr * v)/255; unsigned char g = (bgg * (255 - v) + fgg * v)/255; unsigned char b = (bgb * (255 - v) + fgb * v)/255; fbinfo.pointer[fb_offset] = r; fbinfo.pointer[fb_offset + 1] = g; fbinfo.pointer[fb_offset + 2] = b; } } } } MemoryBarrier(); }
bool AtomicQueue::Enqueue(const void* data_item) { const uint64_t cur_head = mHead; const uint64_t cur_tail = mTail; MemoryBarrier(); const uint64_t cur_head_num = GET_NUM(cur_head); const uint64_t cur_tail_num = GET_NUM(cur_tail); // Check if full (numbers match, but counters do not) if (cur_head_num == cur_tail_num && cur_head != cur_tail) return false; memcpy(static_cast<char*>(mBuffer) + cur_tail_num, data_item, mItemSize); const uint64_t new_tail_num = cur_tail_num + mItemSize; const uint64_t tail_cnt = GET_CNT(cur_tail); // Check if looped through buffer. mTail = (new_tail_num == (mItemSize * mNumItems)) ? CONSTRUCT_NEXT_VALUE(tail_cnt, 0) : CONSTRUCT_VALUE(tail_cnt, new_tail_num); return true; }
/* * http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx */ gint (g_atomic_int_get) (const volatile gint *atomic) { MemoryBarrier (); return *atomic; }
OsStatus_t UsbSchedulerLinkPeriodicElement( _In_ UsbScheduler_t* Scheduler, _In_ int ElementPool, _In_ uint8_t* Element) { OsStatus_t Result; UsbSchedulerObject_t* sObject = NULL; UsbSchedulerPool_t* sPool = NULL; uintptr_t PhysicalAddress = 0; size_t i; assert(ElementPool < Scheduler->Settings.PoolCount); // Validate element and lookup pool sPool = &Scheduler->Settings.Pools[ElementPool]; sObject = USB_ELEMENT_OBJECT(sPool, Element); PhysicalAddress = USB_ELEMENT_PHYSICAL(sPool, sObject->Index); // Now loop through the bandwidth-phases and link it for (i = sObject->StartFrame; i < Scheduler->Settings.FrameCount; i += sObject->FrameInterval) { // Two cases, first or not first if (Scheduler->VirtualFrameList[i] == 0) { Scheduler->VirtualFrameList[i] = (uintptr_t)Element; Scheduler->Settings.FrameList[i] = LODWORD(PhysicalAddress) | USB_ELEMENT_LINKFLAGS(sObject->Flags); //@todo if 64 bit support in xhci } else { // Ok, so we need to index us by Interval // Lowest interval must come last UsbSchedulerObject_t *ExistingObject = NULL; UsbSchedulerPool_t *ExistingPool = NULL; uint8_t *ExistingElement = (uint8_t*)Scheduler->VirtualFrameList[i]; // Get element and validate existance Result = UsbSchedulerGetPoolFromElement(Scheduler, ExistingElement, &ExistingPool); assert(Result == OsSuccess); ExistingObject = USB_ELEMENT_OBJECT(ExistingPool, ExistingElement); // Isochronous always have first right regardless of interval // so if this is not isochronous loop past all isochronous //if (!(sObject->Flags & USB_ELEMENT_ISOCHRONOUS)) { // while (ExistingObject->Flags & USB_ELEMENT_ISOCHRONOUS) { // if (ExistingObject->BreathIndex == USB_ELEMENT_NO_INDEX || // ExistingObject == sObject) { // break; // } // // Move to next object // ExistingPool = USB_ELEMENT_GET_POOL(Scheduler, ExistingObject->BreathIndex); // ExistingElement = USB_ELEMENT_INDEX(ExistingPool, ExistingObject->BreathIndex); // ExistingObject = USB_ELEMENT_OBJECT(ExistingPool, ExistingElement); // } //} // @todo as this will break the linkage // Iterate to correct spot based on interval while (ExistingObject->BreathIndex != USB_ELEMENT_NO_INDEX && ExistingObject != sObject) { if (sObject->FrameInterval > ExistingObject->FrameInterval) { break; } // Move to next object ExistingPool = USB_ELEMENT_GET_POOL(Scheduler, ExistingObject->BreathIndex); ExistingElement = USB_ELEMENT_INDEX(ExistingPool, ExistingObject->BreathIndex); ExistingObject = USB_ELEMENT_OBJECT(ExistingPool, ExistingElement); } // Link us in only if we are not ourselves if (ExistingObject != sObject) { // Two insertion cases. To front or not to front // We must have a larger interval and existingelement must be front if (ExistingElement == (uint8_t*)Scheduler->VirtualFrameList[i] && sObject->FrameInterval > ExistingObject->FrameInterval) { USB_ELEMENT_LINK(sPool, Element, USB_CHAIN_BREATH) = Scheduler->Settings.FrameList[i]; sObject->BreathIndex = ExistingObject->Index; MemoryBarrier(); Scheduler->VirtualFrameList[i] = (uintptr_t)Element; Scheduler->Settings.FrameList[i] = LODWORD(PhysicalAddress) | USB_ELEMENT_LINKFLAGS(sObject->Flags); //@todo if 64 bit support in xhci } else { USB_ELEMENT_LINK(sPool, Element, USB_CHAIN_BREATH) = USB_ELEMENT_LINK(ExistingPool, ExistingElement, USB_CHAIN_BREATH); sObject->BreathIndex = ExistingObject->BreathIndex; MemoryBarrier(); USB_ELEMENT_LINK(ExistingPool, ExistingElement, USB_CHAIN_BREATH) = LODWORD(PhysicalAddress) | USB_ELEMENT_LINKFLAGS(sObject->Flags); ExistingObject->BreathIndex = sObject->Index; } } } } return OsSuccess; }
void Memory::Fence() { MemoryBarrier(); }
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult) { /* * Attempt to insert our FileNode into the volume device's generic table. * If an FileNode with the same UserContext already exists, then use that * FileNode instead. * * There is no FileNode that can be acquired when calling this function. */ PAGED_CODE(); PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; FSP_FILE_NODE *OpenedFileNode; BOOLEAN Inserted, DeletePending; NTSTATUS Result; FspFsvolDeviceLockContextTable(FsvolDeviceObject); OpenedFileNode = FspFsvolDeviceInsertContextByName(FsvolDeviceObject, &FileNode->FileName, FileNode, &FileNode->ContextByNameElementStorage, &Inserted); ASSERT(0 != OpenedFileNode); if (Inserted) { /* * The new FileNode was inserted into the Context table. Set its share access * and reference and open it. There should be (at least) two references to this * FileNode, one from our caller and one from the Context table. */ ASSERT(OpenedFileNode == FileNode); IoSetShareAccess(GrantedAccess, ShareAccess, FileObject, &OpenedFileNode->ShareAccess); } else { /* * The new FileNode was NOT inserted into the Context table. Instead we are * opening a prior FileNode that we found in the table. */ ASSERT(OpenedFileNode != FileNode); DeletePending = 0 != OpenedFileNode->DeletePending; MemoryBarrier(); if (DeletePending) { Result = STATUS_DELETE_PENDING; goto exit; } /* * FastFat says to do the following on Vista and above. * * Quote: * Do an extra test for writeable user sections if the user did not allow * write sharing - this is neccessary since a section may exist with no handles * open to the file its based against. */ if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) && FlagOn(GrantedAccess, FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) && MmDoesFileHaveUserWritableReferences(&OpenedFileNode->NonPaged->SectionObjectPointers)) { Result = STATUS_SHARING_VIOLATION; goto exit; } /* share access check */ Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &OpenedFileNode->ShareAccess, TRUE); exit: if (!NT_SUCCESS(Result)) { if (0 != PResult) *PResult = Result; OpenedFileNode = 0; } } if (0 != OpenedFileNode) { FspFileNodeReference(OpenedFileNode); OpenedFileNode->OpenCount++; OpenedFileNode->HandleCount++; } FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); return OpenedFileNode; }
PVideoFrame __stdcall f3kdb_avisynth::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); // interleaved 16bit output needs extra alignment PVideoFrame dst = env->NewVideoFrame(vi, PLANE_ALIGNMENT * 2); if (vi.IsPlanar() && !vi.IsY8()) { if (!_mt) { process_plane(n, src, dst, dst->GetWritePtr(PLANAR_Y), PLANAR_Y, env); process_plane(n, src, dst, dst->GetWritePtr(PLANAR_U), PLANAR_U, env); process_plane(n, src, dst, dst->GetWritePtr(PLANAR_V), PLANAR_V, env); } else { bool new_thread = _mt_info == NULL; if (new_thread) { _mt_info = mt_info_create(); if (!_mt_info) { env->ThrowError("f3kdb_avisynth: Failed to allocate mt_info."); return NULL; } } // we must get write pointer before copying the frame pointer // otherwise NULL will be returned unsigned char* dstp_y = dst->GetWritePtr(PLANAR_Y); _mt_info->n = n; _mt_info->dstp_u = dst->GetWritePtr(PLANAR_U); _mt_info->dstp_v = dst->GetWritePtr(PLANAR_V); _mt_info->env = env; MemoryBarrier(); { auto info_nv = const_cast<mt_info*>(_mt_info); info_nv->dst = dst; info_nv->src = src; } MemoryBarrier(); if (!new_thread) { SetEvent(_mt_info->work_event); } else { _mt_info->thread_handle = (HANDLE)_beginthreadex(NULL, 0, mt_proc_wrapper, this, 0, NULL); if (!_mt_info->thread_handle) { int err = errno; mt_info_destroy(_mt_info); _mt_info = NULL; env->ThrowError("f3kdb_avisynth: Failed to create worker thread, code = %d.", err); return NULL; } } process_plane(n, src, dst, dstp_y, PLANAR_Y, env); WaitForSingleObject(_mt_info->work_complete_event, INFINITE); } } else { // Y8 process_plane(n, src, dst, dst->GetWritePtr(), PLANAR_Y, env); } return dst; }
~fenced_block() { #if defined( _MSC_VER ) && ( ( _MSC_VER < 1400 ) || !defined( MemoryBarrier ) ) MemoryBarrier(); #endif }
void SmallHeapBlockAllocator<TBlockType>::Clear() { TBlockType * heapBlock = this->heapBlock; if (heapBlock != nullptr) { Assert(heapBlock->isInAllocator); heapBlock->isInAllocator = false; FreeObject * remainingFreeObjectList = nullptr; if (this->endAddress != nullptr) { #ifdef RECYCLER_TRACK_NATIVE_ALLOCATED_OBJECTS TrackNativeAllocatedObjects(); lastNonNativeBumpAllocatedBlock = nullptr; #endif #ifdef PROFILE_RECYCLER_ALLOC // Need to tell the tracker this->bucket->heapInfo->recycler->TrackUnallocated((char *)this->freeObjectList, this->endAddress, this->bucket->sizeCat); #endif RecyclerMemoryTracking::ReportUnallocated(this->heapBlock->heapBucket->heapInfo->recycler, (char *)this->freeObjectList, this->endAddress, heapBlock->heapBucket->sizeCat); #ifdef RECYCLER_PERF_COUNTERS size_t unallocatedObjects = heapBlock->objectCount - ((char *)this->freeObjectList - heapBlock->address) / heapBlock->objectSize; size_t unallocatedObjectBytes = unallocatedObjects * heapBlock->GetObjectSize(); RECYCLER_PERF_COUNTER_ADD(LiveObject, unallocatedObjects); RECYCLER_PERF_COUNTER_ADD(LiveObjectSize, unallocatedObjectBytes); RECYCLER_PERF_COUNTER_SUB(FreeObjectSize, unallocatedObjectBytes); RECYCLER_PERF_COUNTER_ADD(SmallHeapBlockLiveObject, unallocatedObjects); RECYCLER_PERF_COUNTER_ADD(SmallHeapBlockLiveObjectSize, unallocatedObjectBytes); RECYCLER_PERF_COUNTER_SUB(SmallHeapBlockFreeObjectSize, unallocatedObjectBytes); #endif Assert(heapBlock->freeObjectList == nullptr); this->endAddress = nullptr; } else { remainingFreeObjectList = this->freeObjectList; heapBlock->freeObjectList = remainingFreeObjectList; } this->freeObjectList = nullptr; // this->freeObjectList and this->lastFreeCount are accessed in SmallHeapBlock::ResetMarks // the order of access there is first we see if lastFreeCount = 0, and if it is, we assert // that freeObjectList = null. Because of ARM's memory model, we need to insert barriers // so that the two variables can be accessed correctly across threads. Here, after we write // to this->freeObjectList, we insert a write barrier so that if this->lastFreeCount is 0, // this->freeObjectList must have been set to null. On the other end, we stick a read barrier // We use the MemoryBarrier macro because of ARMs lack of a separate read barrier #if defined(_M_ARM32_OR_ARM64) #if DBG MemoryBarrier(); #endif #endif if (remainingFreeObjectList == nullptr) { uint lastFreeCount = heapBlock->GetAndClearLastFreeCount(); heapBlock->heapBucket->heapInfo->uncollectedAllocBytes += lastFreeCount * heapBlock->GetObjectSize(); Assert(heapBlock->lastUncollectedAllocBytes == 0); DebugOnly(heapBlock->lastUncollectedAllocBytes = lastFreeCount * heapBlock->GetObjectSize()); } else { DebugOnly(heapBlock->SetIsClearedFromAllocator(true)); } this->heapBlock = nullptr; RECYCLER_SLOW_CHECK(heapBlock->CheckDebugFreeBitVector(false)); } else if (this->freeObjectList != nullptr) { // Explicit Free Object List #ifdef RECYCLER_MEMORY_VERIFY FreeObject* freeObject = this->freeObjectList; while (freeObject) { HeapBlock* heapBlock = this->bucket->GetRecycler()->FindHeapBlock((void*) freeObject); Assert(heapBlock != nullptr); Assert(!heapBlock->IsLargeHeapBlock()); TBlockType* smallBlock = (TBlockType*)heapBlock; smallBlock->ClearExplicitFreeBitForObject((void*) freeObject); freeObject = freeObject->GetNext(); } #endif this->freeObjectList = nullptr; } }
int local_win_socket::read(void* buf, size_t min_size, size_t max_size, time_t timeout) { time_t start = 0; char* dst = (char*)buf; size_t size = 0; Error = ok; if (timeout != WAIT_FOREVER) { start = time(NULL); timeout *= 1000; // convert seconds to miliseconds } while (size < min_size && state == ss_open) { RcvBuf->RcvWaitFlag = true; MemoryBarrier(); size_t begin = RcvBuf->DataBeg; size_t end = RcvBuf->DataEnd; size_t rcv_size = (begin <= end) ? end - begin : sizeof(RcvBuf->Data) - begin; if (rcv_size > 0) { RcvBuf->RcvWaitFlag = false; if (rcv_size >= max_size) { memcpy(dst, &RcvBuf->Data[begin], max_size); begin += max_size; size += max_size; } else { memcpy(dst, &RcvBuf->Data[begin], rcv_size); begin += rcv_size; dst += rcv_size; size += rcv_size; max_size -= rcv_size; } RcvBuf->DataBeg = (begin == sizeof(RcvBuf->Data)) ? 0 : (int)begin; MemoryBarrier(); if (RcvBuf->SndWaitFlag) { SetEvent(Signal[RTR]); } } else { HANDLE h[2]; h[0] = Signal[RD]; h[1] = Mutex; int rc = WaitForMultipleObjects(2, h, false, (DWORD)timeout); RcvBuf->RcvWaitFlag = false; if (rc != WAIT_OBJECT_0) { if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) { Error = broken_pipe; ReleaseMutex(Mutex); } else if (rc == WAIT_TIMEOUT) { return (int)size; } else { Error = GetLastError(); } return -1; } if (timeout != WAIT_FOREVER) { time_t now = time(NULL); timeout = timeout >= (now - start)*1000 ? timeout - (now - start)*1000 : 0; } } } return size < min_size ? -1 : (int)size; }