示例#1
0
  // 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;
}
示例#3
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
}
示例#5
0
/**
 * 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);
}
示例#6
0
文件: dirbuf.c 项目: os12/winfsp
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);
}
示例#7
0
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);
}
示例#8
0
//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();
}
示例#9
0
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;
}
示例#10
0
/*
 * http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx
 */
gint
(g_atomic_int_get) (const volatile gint *atomic)
{
  MemoryBarrier ();
  return *atomic;
}
示例#11
0
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;
}
示例#12
0
 void Memory::Fence() {
     MemoryBarrier();
 }
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
    ~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;
    }

}
示例#17
0
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;
}