示例#1
0
bool mp_create()
{
	size_t total = 0;
	for( int i = 0; i < MP_MAX_OBJECT_TYPE; ++i )
		total += s_entries[i].count * s_entries[i].size;

	s_base = VirtualAlloc( NULL, total, MEM_COMMIT, PAGE_READWRITE );
	if( s_base == NULL )
		return false;

	char* base = reinterpret_cast<char*>( s_base );
	for( int i = 0; i < MP_MAX_OBJECT_TYPE; ++i )
	{
		MP_OBJECT_ENTRY* entry = s_entries + i;
		InitializeSListHead( &entry->lsthdr );

		char* addr = base + entry->size * entry->count;
		addr -= MEMORY_ALLOCATION_ALIGNMENT;

		for( size_t j = 0; j < entry->count; ++j )
		{
			SLIST_ENTRY* node = reinterpret_cast<SLIST_ENTRY*>( addr );
			InterlockedPushEntrySList( &entry->lsthdr, node );
			addr -= entry->size;
		}

		base += entry->count * entry->size;
	}

	return true;
}
示例#2
0
void ReturnIOContext(
	PHTTP_IO_CONTEXT context
	)
{
	PLOOKASIDE cacheEntry = &IoContextCacheList[IO_CONTEXT_PROC_INDEX];
	InterlockedPushEntrySList(&cacheEntry->Header, &context->LookAsideEntry);		
}
示例#3
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT printer_irp_request(DEVICE* device, IRP* irp)
{
	PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device;
	InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry));
	SetEvent(printer_dev->event);
	return CHANNEL_RC_OK;
}
示例#4
0
VOID
BtrFreeLookaside(
	__in BTR_LOOKASIDE_TYPE Type,
	__in PVOID Ptr
	)
{
	PBTR_LOOKASIDE Lookaside;
	PSLIST_ENTRY ListEntry;
	USHORT Depth;

	if (!Ptr) {
		return;
	}

	Lookaside = &BtrLookaside[Type];
	InterlockedIncrement(&Lookaside->TotalFrees);

	Depth = QueryDepthSList(&Lookaside->ListHead);
	ListEntry = (PSLIST_ENTRY)((PUCHAR)Ptr - MEMORY_ALLOCATION_ALIGNMENT);

	if (Depth < Lookaside->MaximumDepth) {
		InterlockedPushEntrySList(&Lookaside->ListHead, ListEntry);
	} else {
		InterlockedIncrement(&Lookaside->FreeMisses);
		BtrAlignedFree(ListEntry);
	}
}
示例#5
0
文件: channels.c 项目: d0rian/FreeRDP
/* can be called from any thread */
static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData)
{
	int index;
	SYNC_DATA* item;
	rdpChannels* channels;
	struct channel_data* lchannel_data;

	channels = freerdp_channels_find_by_open_handle(openHandle, &index);

	if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
	{
		DEBUG_CHANNELS("error bad channel handle");
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;
	}

	if (!channels->is_connected)
	{
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}

	if (pData == 0)
	{
		DEBUG_CHANNELS("error bad pData");
		return CHANNEL_RC_NULL_DATA;
	}

	if (dataLength == 0)
	{
		DEBUG_CHANNELS("error bad dataLength");
		return CHANNEL_RC_ZERO_LENGTH;
	}

	lchannel_data = channels->channels_data + index;

	if (lchannel_data->flags != 2)
	{
		DEBUG_CHANNELS("error not open");
		return CHANNEL_RC_NOT_OPEN;
	}

	if (!channels->is_connected)
	{
		DEBUG_CHANNELS("error not connected");
		return CHANNEL_RC_NOT_CONNECTED;
	}

	item = (SYNC_DATA*) _aligned_malloc(sizeof(SYNC_DATA), MEMORY_ALLOCATION_ALIGNMENT);
	item->Data = pData;
	item->DataLength = dataLength;
	item->UserData = pUserData;
	item->Index = index;

	InterlockedPushEntrySList(channels->pSyncDataList, &(item->ItemEntry));

	/* set the event */
	SetEvent(channels->signal);

	return CHANNEL_RC_OK;
}
示例#6
0
static void printer_irp_request(DEVICE* device, IRP* irp)
{
    PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device;

    InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry));

    freerdp_thread_signal(printer_dev->thread);
}
示例#7
0
static void drive_irp_request(DEVICE* device, IRP* irp)
{
	DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;

	InterlockedPushEntrySList(disk->pIrpList, &(irp->ItemEntry));

	SetEvent(disk->irpEvent);
}
示例#8
0
	void Deallocate(OVERLAPPED* ovl)
	{
		cpu_AtomicAdd(&extant, -1);

		const uintptr_t address = uintptr_t(ovl);
		ENSURE(uintptr_t(storage) <= address && address < uintptr_t(storage)+storageSize);
		InterlockedPushEntrySList(&freelist, (PSLIST_ENTRY)(address - offsetof(Entry, ovl)));
	}
示例#9
0
static void parallel_irp_request(DEVICE* device, IRP* irp)
{
	PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device;

	InterlockedPushEntrySList(parallel->pIrpList, &(irp->ItemEntry));

	freerdp_thread_signal(parallel->thread);
}
示例#10
0
DWORD InterfaceUtils::AddEntry(ULONG NTEContext) {
	pProgramItem = (PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
	if (NULL == pProgramItem)
	{
		printf("Memory allocation failed.\n");
		return -1;
	}
	pProgramItem->NTEContext = NTEContext;
	pFirstEntry = InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry));
	return NO_ERROR;
}
示例#11
0
void mp_free( int objtype, void* mem )
{
	if( mem == NULL )
		return;

	MP_OBJECT_ENTRY* entry = s_entries + objtype;
	char* p = reinterpret_cast<char*>( mem );
	p += entry->size - MEMORY_ALLOCATION_ALIGNMENT;

	SLIST_ENTRY* node = reinterpret_cast<SLIST_ENTRY*>( p );
	InterlockedPushEntrySList( &s_entries[objtype].lsthdr, node );
}
示例#12
0
	void IConcurrentPool::Init()
	{
		mWork = std::make_shared<boost::asio::io_service::work>( mDispatcher );

		const auto f = [ = ]()
		{
			LThreadId = GetCurrentThreadId();

			LThreadCallHistory = std::make_shared<ThreadCallHistory>( LThreadId );
			InterlockedPushEntrySList( &GThreadCallHistory, reinterpret_cast<PSLIST_ENTRY>(LThreadCallHistory.get()) );

			LThreadCallElapsedRecord = std::make_shared<ThreadCallElapsedRecord>( LThreadId );
			InterlockedPushEntrySList( &GThreadCallElapsedRecord, reinterpret_cast<PSLIST_ENTRY>(LThreadCallElapsedRecord.get()) );

			InitThread();
			Run();
		};

		for( std::size_t i = 0; i < mPoolSize; ++i )
		{
			mGroup.create_thread( f );
		}
	}
示例#13
0
// ******************************************************************
// * 0x003A - InterlockedPushEntrySList()
// ******************************************************************
// Source:ReactOS
XBSYSAPI EXPORTNUM(58) xboxkrnl::PSLIST_ENTRY FASTCALL xboxkrnl::KRNL(InterlockedPushEntrySList)
(
	IN PSLIST_HEADER ListHead,
	IN PSLIST_ENTRY ListEntry
)
{
	LOG_FUNC_BEGIN
		LOG_FUNC_ARG(ListHead)
		LOG_FUNC_ARG(ListEntry)
		LOG_FUNC_END;

	PSLIST_ENTRY res = (PSLIST_ENTRY)InterlockedPushEntrySList((::PSLIST_HEADER)ListHead, (::PSLIST_ENTRY)ListEntry);

	RETURN(res);
}
示例#14
0
static void CALLBACK
cubeb_buffer_callback(HWAVEOUT waveout, UINT msg, DWORD_PTR user_ptr, DWORD_PTR p1, DWORD_PTR p2)
{
  cubeb_stream * stm = (cubeb_stream *) user_ptr;
  struct cubeb_stream_item * item;

  if (msg != WOM_DONE) {
    return;
  }

  item = _aligned_malloc(sizeof(struct cubeb_stream_item), MEMORY_ALLOCATION_ALIGNMENT);
  assert(item);
  item->stream = stm;
  InterlockedPushEntrySList(stm->context->work, &item->head);

  SetEvent(stm->context->event);
}
示例#15
0
void cp_parallelized_crypt(
	   int   is_encrypt, xts_key *key, fc_callback on_complete, 
	   void *param, const unsigned char *in, unsigned char *out, u32 len, u64 offset)
{
	req_item *item;
	req_part *part;
	u32       part_sz;
	u32       part_of;

	if ( (len < F_OP_THRESOLD) ||
		 ((item = ExAllocateFromNPagedLookasideList(&pool_req_mem)) == NULL) )
	{
		if (is_encrypt != 0) {
			xts_encrypt(in, out, len, offset, key);
		} else {
			xts_decrypt(in, out, len, offset, key);
		}
		on_complete(param); return;
	}
	item->is_encrypt = is_encrypt;
	item->length = len;
	item->in  = in;
	item->out = out;
	item->offset      = offset;
	item->on_complete = on_complete;
	item->param = param;
	item->key   = key;

	part_sz = _align(len / dc_cpu_count, F_MIN_REQ);
	part_of = 0; part = &item->parts[0];
	do
	{
		part_sz      = min(part_sz, len);
		part->item   = item;
		part->offset = part_of;
		part->length = part_sz;

		InterlockedPushEntrySList(&pool_head, &part->entry);

		part_of += part_sz; len -= part_sz; part++;
	} while (len != 0);

	KeSetEvent(&pool_signal_event, IO_NO_INCREMENT, FALSE);
}
示例#16
0
static void smartcard_irp_request(DEVICE* device, IRP* irp)
{
	COMPLETIONIDINFO* CompletionIdInfo;
	SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) device;

	/* Begin TS Client defect workaround. */

	CompletionIdInfo = (COMPLETIONIDINFO*) malloc(sizeof(COMPLETIONIDINFO));
	ZeroMemory(CompletionIdInfo, sizeof(COMPLETIONIDINFO));

	CompletionIdInfo->ID = irp->CompletionId;

	WaitForSingleObject(smartcard->CompletionIdsMutex, INFINITE);
	smartcard_mark_duplicate_id(smartcard, irp->CompletionId);
	list_enqueue(smartcard->CompletionIds, CompletionIdInfo);
	ReleaseMutex(smartcard->CompletionIdsMutex);

	/* Overwrite the previous assignment made in irp_new() */
	irp->Complete = smartcard_irp_complete;

	/* End TS Client defect workaround. */

	if ((irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) && smartcard_async_op(irp))
	{
		/* certain potentially long running operations get their own thread */
		SMARTCARD_IRP_WORKER* irpWorker = malloc(sizeof(SMARTCARD_IRP_WORKER));

		irpWorker->thread = CreateThread(NULL, 0,
				(LPTHREAD_START_ROUTINE) smartcard_process_irp_thread_func,
				irpWorker, CREATE_SUSPENDED, NULL);

		irpWorker->smartcard = smartcard;
		irpWorker->irp = irp;

		ResumeThread(irpWorker->thread);

		return;
	}

	InterlockedPushEntrySList(smartcard->pIrpList, &(irp->ItemEntry));

	SetEvent(smartcard->irpEvent);
}
示例#17
0
VOID
NTAPI
DbgLogEvent(PSLIST_HEADER pslh, LOG_EVENT_TYPE nEventType, LPARAM lParam)
{
    PLOGENTRY pLogEntry;

    /* Log a maximum of 100 events */
    if (QueryDepthSList(pslh) >= 1000) return;

    /* Allocate a logentry */
    pLogEntry = EngAllocMem(0, sizeof(LOGENTRY), 'golG');
    if (!pLogEntry) return;

    /* Set type */
    pLogEntry->nEventType = nEventType;
    pLogEntry->ulUnique = InterlockedIncrement((LONG*)&gulLogUnique);
    pLogEntry->dwProcessId = HandleToUlong(PsGetCurrentProcessId());
    pLogEntry->dwThreadId = HandleToUlong(PsGetCurrentThreadId());
    pLogEntry->lParam = lParam;

    /* Capture a backtrace */
    DbgCaptureStackBackTace(pLogEntry->apvBackTrace, 20);

    switch (nEventType)
    {
        case EVENT_ALLOCATE:
        case EVENT_CREATE_HANDLE:
        case EVENT_REFERENCE:
        case EVENT_DEREFERENCE:
        case EVENT_LOCK:
        case EVENT_UNLOCK:
        case EVENT_DELETE:
        case EVENT_FREE:
        case EVENT_SET_OWNER:
        default:
            break;
    }

    /* Push it on the list */
    InterlockedPushEntrySList(pslh, &pLogEntry->sleLink);
}
示例#18
0
	void Push( __out_opt SNI_Packet *pPacket)
	{
		if( QueryDepthSList(&m_SListHeader) < MAX_PACKET_CACHE_SIZE - 1 )
		{
			SLIST_ENTRY* pEntry = static_cast<SLIST_ENTRY*>(SNIPacketGetDescriptor(pPacket));
			InterlockedPushEntrySList(&m_SListHeader, pEntry);
		}
		else
		{
			// Strategy: Don't make an effort to clean up the "extra" entries, but don't push this one onto the stack
			// if it will go over. This guarantees an *approximate* maximum 
			// (bounded above by MAX_PACKET_CACHE_SIZE + ConcurrentThreadsAccessingTheStack)
			
			// It would cost a lot of performance to put a stronger guarantee on the maximal size, since
			// we would need to synchronize access to two variables (stack head, stack size), which we 
			// don't know how to do without using a true [....] primitive, rather than the two separate
			// Interlocked operations which are all that's required to maintain consistency of the list header and 
			// an *approximate* depth guarantee.
			SNIPacketDelete(pPacket);
		}
	}
示例#19
0
HRESULT CConnectionPool::Return(HANDLE connection)
{
    HRESULT hr;
    PCONNECTION_ENTRY entry = NULL;

    if (this->count >= this->maxPoolSize)
    {
        CloseHandle(connection);
    }
    else
    {
        ErrorIf(NULL == (entry = (PCONNECTION_ENTRY)_aligned_malloc(sizeof(CONNECTION_ENTRY), MEMORY_ALLOCATION_ALIGNMENT)), ERROR_NOT_ENOUGH_MEMORY);
        entry->connection = connection;
        entry->timestamp = GetTickCount();
        InterlockedPushEntrySList(this->list, &(entry->listEntry));
        InterlockedIncrement(&this->count);
    }

    return S_OK;
Error:

    return hr;
}
示例#20
0
VOID
NTAPI
IopFreeMiniPacket(PIOP_MINI_COMPLETION_PACKET Packet)
{
    PKPRCB Prcb = KeGetCurrentPrcb();
    PNPAGED_LOOKASIDE_LIST List;

    /* Use the P List */
    List = (PNPAGED_LOOKASIDE_LIST)Prcb->
            PPLookasideList[LookasideCompletionList].P;
    List->L.TotalFrees++;

    /* Check if the Free was within the Depth or not */
    if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
    {
        /* Let the balancer know */
        List->L.FreeMisses++;

        /* Use the L List */
        List = (PNPAGED_LOOKASIDE_LIST)Prcb->
                PPLookasideList[LookasideCompletionList].L;
        List->L.TotalFrees++;

        /* Check if the Free was within the Depth or not */
        if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
        {
            /* All lists failed, use the pool */
            List->L.FreeMisses++;
            ExFreePool(Packet);
            return;
        }
    }

    /* The free was within dhe Depth */
    InterlockedPushEntrySList(&List->L.ListHead, (PSLIST_ENTRY)Packet);
}
示例#21
0
    /// <summary>
    ///     Handles the completion of a UMS thread.
    /// </summary>
    /// <param name="pCompletion">
    ///     The thread which was noticed on the completion list
    /// </param>
    /// <returns>
    ///     An indication as to whether the thread moved to the transfer list (true).  If false is returned, the thread was special
    ///     (e.g.: a critically blocked thread) and was handled through a different path.
    /// </returns>
    bool UMSSchedulerProxy::HandleCompletion(UMSThreadProxy *pCompletion)
    {
        //
        // We need to make absolutely certain that we know *WHY* the context blocked so we can tell what to do when it comes off the completion list.
        // This is not known until the primary which was invoked sets appropriate flags and then notifies the proxy that it is blocked.  In order to
        // read those bits, we must spin until the proxy has set those flags.
        //
        UMSThreadProxy::BlockingType blockingType = pCompletion->SpinOnAndReturnBlockingType();

        //
        // We are allowing thread termination on the way out of the RM's main loop in order to retire virtual processors and threads simultaneously
        // (a necessary condition in order to work around a win7 issue).  This means that terminated threads can come back on the completion list.  We
        // do not want to pop this back for the scheduler -- the scheduler should already know (this is *NOT* TerminateThread friendly).
        //
        // Termination will take the same path as critical blocking.  We must ensure elsewhere in the scheduler that threads we allow to terminate in
        // this manner are in hyper-critical regions.
        //
        CONCRT_COREASSERT(!pCompletion->IsTerminated() || blockingType == UMSThreadProxy::BlockingCritical);

#if defined(_DEBUG)
        if (pCompletion->IsTerminated())
        {
            pCompletion->m_UMSDebugBits |= UMS_DEBUGBIT_COMPLETIONTERMINATED;
        }
#endif // _DEBUG

        RPMTRACE(MTRACE_EVT_PULLEDFROMCOMPLETION, pCompletion, NULL, blockingType);

#if defined(_DEBUG)
        CONCRT_COREASSERT(pCompletion->m_UMSDebugBits != UMS_DEBUGBIT_YIELDED);
#endif // _DEBUG

        if (blockingType == UMSThreadProxy::BlockingCritical)
        {
#if defined(_DEBUG)
            pCompletion->m_UMSDebugBits |= UMS_DEBUGBIT_CRITICALNOTIFY;
#endif // _DEBUG
            pCompletion->m_pLastRoot->CriticalNotify();
        }
        else if (!pCompletion->MessagedYield())
        {
#if defined(_DEBUG)
            pCompletion->m_UMSDebugBits |= UMS_DEBUGBIT_TRANSFERLIST;
#endif // _DEBUG

            //
            // Right now, just move the entry to the transfer list.
            //
            InterlockedPushEntrySList(&m_transferList, &(pCompletion->m_listEntry));

            //
            // Set the transferlist event that should wake up vprocs that are deactivated
            //
            if (InterlockedIncrement(&m_pushedBackCount) == 1)
            {
                SetEvent(m_hTransferListEvent);
            }

            return true;
        }
        else
        {
#if defined(_DEBUG)
            pCompletion->m_UMSDebugBits |= UMS_DEBUGBIT_SKIPPEDCOMPLETION;
#endif // _DEBUG
        }

        return false;
    }
示例#22
0
VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, PTRANSFER_PACKET Pkt)
{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
    PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
    KIRQL oldIrql;
    ULONG newNumPkts;
    
    ASSERT(!Pkt->SlistEntry.Next);

    InterlockedPushEntrySList(&fdoData->FreeTransferPacketsList, &Pkt->SlistEntry);
    newNumPkts = InterlockedIncrement(&fdoData->NumFreeTransferPackets);
    ASSERT(newNumPkts <= fdoData->NumTotalTransferPackets);

    /*
     *  If the total number of packets is larger than MinWorkingSetTransferPackets,
     *  that means that we've been in stress.  If all those packets are now
     *  free, then we are now out of stress and can free the extra packets.
     *  Free down to MaxWorkingSetTransferPackets immediately, and
     *  down to MinWorkingSetTransferPackets lazily (one at a time).
     */
    if (fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets){

        /*
         *  1.  Immediately snap down to our UPPER threshold.
         */
        if (fdoData->NumTotalTransferPackets > MaxWorkingSetTransferPackets){
            SINGLE_LIST_ENTRY pktList;
            PSINGLE_LIST_ENTRY slistEntry;
            PTRANSFER_PACKET pktToDelete;

            DBGTRACE(ClassDebugTrace, ("Exiting stress, block freeing (%d-%d) packets.", fdoData->NumTotalTransferPackets, MaxWorkingSetTransferPackets));

            /*
             *  Check the counter again with lock held.  This eliminates a race condition
             *  while still allowing us to not grab the spinlock in the common codepath.
             *
             *  Note that the spinlock does not synchronize with threads dequeuing free
             *  packets to send (DequeueFreeTransferPacket does that with a lightweight
             *  interlocked exchange); the spinlock prevents multiple threads in this function
             *  from deciding to free too many extra packets at once.
             */
            SimpleInitSlistHdr(&pktList);
            KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
            while ((fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets) && 
                   (fdoData->NumTotalTransferPackets > MaxWorkingSetTransferPackets)){
                   
                pktToDelete = DequeueFreeTransferPacket(Fdo, FALSE);   
                if (pktToDelete){
                    SimplePushSlist(&pktList, &pktToDelete->SlistEntry);
                    InterlockedDecrement(&fdoData->NumTotalTransferPackets);    
                }
                else {
                    DBGTRACE(ClassDebugTrace, ("Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (1).", MaxWorkingSetTransferPackets, Fdo, fdoData->NumTotalTransferPackets));
                    break;
                }
            }
            KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

            while (slistEntry = SimplePopSlist(&pktList)){
                pktToDelete = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
                DestroyTransferPacket(pktToDelete);
            }

        }

        /*
         *  2.  Lazily work down to our LOWER threshold (by only freeing one packet at a time).
         */
        if (fdoData->NumTotalTransferPackets > MinWorkingSetTransferPackets){
            /*
             *  Check the counter again with lock held.  This eliminates a race condition
             *  while still allowing us to not grab the spinlock in the common codepath.
             *
             *  Note that the spinlock does not synchronize with threads dequeuing free
             *  packets to send (DequeueFreeTransferPacket does that with a lightweight
             *  interlocked exchange); the spinlock prevents multiple threads in this function
             *  from deciding to free too many extra packets at once.
             */
            PTRANSFER_PACKET pktToDelete = NULL; 

            DBGTRACE(ClassDebugTrace, ("Exiting stress, lazily freeing one of %d/%d packets.", fdoData->NumTotalTransferPackets, MinWorkingSetTransferPackets));
            
            KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
            if ((fdoData->NumFreeTransferPackets >= fdoData->NumTotalTransferPackets) &&
                (fdoData->NumTotalTransferPackets > MinWorkingSetTransferPackets)){
                
                pktToDelete = DequeueFreeTransferPacket(Fdo, FALSE);
                if (pktToDelete){
                    InterlockedDecrement(&fdoData->NumTotalTransferPackets);    
                }
                else {
                    DBGTRACE(ClassDebugTrace, ("Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (2).", MinWorkingSetTransferPackets, Fdo, fdoData->NumTotalTransferPackets));
                }
            }
            KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);

            if (pktToDelete){
                DestroyTransferPacket(pktToDelete);
            }
        }

    }
  
}
void SmallSizeMemoryPool::Push(MemAllocInfo* ptr)
{
	InterlockedPushEntrySList(&mFreeList, (PSLIST_ENTRY)ptr);
	InterlockedDecrement(&mAllocCount);
}
示例#24
0
void HttpInputQueueEnqueue(PHTTP_LISTENER listener, 
							PHTTP_IO_CONTEXT context)
{
	InterlockedPushEntrySList(&listener->HttpInputQueue->Header,
							 &context->LookAsideEntry);
}
示例#25
0
int TestInterlockedSList(int argc, char* argv[])
{
	ULONG Count;
	WINPR_PSLIST_ENTRY pFirstEntry;
	WINPR_PSLIST_ENTRY pListEntry;
	WINPR_PSLIST_HEADER pListHead;
	PPROGRAM_ITEM pProgramItem;

	/* Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. */
	pListHead = (WINPR_PSLIST_HEADER) _aligned_malloc(sizeof(WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);

	if (!pListHead)
	{
		printf("Memory allocation failed.\n");
		return -1;
	}

	InitializeSListHead(pListHead);

	/* Insert 10 items into the list. */
	for (Count = 1; Count <= 10; Count += 1)
	{
		pProgramItem = (PPROGRAM_ITEM) _aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT);

		if (!pProgramItem)
		{
			printf("Memory allocation failed.\n");
			return -1;
		}

		pProgramItem->Signature = Count;
		pFirstEntry = InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry));
	}

	/* Remove 10 items from the list and display the signature. */
	for (Count = 10; Count >= 1; Count -= 1)
	{
		pListEntry = InterlockedPopEntrySList(pListHead);

		if (!pListEntry)
		{
			printf("List is empty.\n");
			return -1;
		}
  
		pProgramItem = (PPROGRAM_ITEM) pListEntry;
		printf("Signature is %d\n", (int) pProgramItem->Signature);

		/* 
		 * This example assumes that the SLIST_ENTRY structure is the 
		 * first member of the structure. If your structure does not 
		 * follow this convention, you must compute the starting address 
		 * of the structure before calling the free function.
		 */

		_aligned_free(pListEntry);
	}

	/* Flush the list and verify that the items are gone. */
	pListEntry = InterlockedFlushSList(pListHead);
	pFirstEntry = InterlockedPopEntrySList(pListHead);

	if (pFirstEntry)
	{
		printf("Error: List is not empty.\n");
		return -1;
	}

	_aligned_free(pListHead);

	return 0;
}
示例#26
0
BOOLEAN
ExRemoveHeadNBQueue (
    IN PVOID Header,
    OUT PULONG64 Value
    )

/*++

Routine Description:

    This function removes a queue entry from the head of the specified
    non-blocking queue and returns the associated data value.

Arguments:

    Header - Supplies an opaque pointer to a non-blocking queue header.

    Value - Supplies a pointer to a variable that receives the queue
        element value.

Return Value:

    If an entry is removed from the specified non-blocking queue, then
    TRUE is returned as the function value. Otherwise, FALSE is returned.

--*/

{

    NBQUEUE_POINTER Head;
    PNBQUEUE_NODE HeadNode;
    NBQUEUE_POINTER Insert;
    NBQUEUE_POINTER Next;
    PNBQUEUE_NODE NextNode;
    PNBQUEUE_HEADER QueueHead;
    NBQUEUE_POINTER Tail;
    PNBQUEUE_NODE TailNode;

    //
    // The following loop is executed until an entry can be removed from
    // the specified non-blocking queue or until it can be determined that
    // the queue is empty.
    //

    QueueHead = (PNBQUEUE_HEADER)Header;
    do {

        //
        // Read the head queue pointer, the tail queue pointer, and the
        // next queue pointer of the head queue pointer making sure the
        // three pointers are coherent.
        //

        Head.Data = ReadForWriteAccess((volatile LONG64 *)(&QueueHead->Head.Data));
        Tail.Data = *((volatile LONG64 *)(&QueueHead->Tail.Data));
        HeadNode = UnpackNBQPointer(&Head);
        Next.Data = *((volatile LONG64 *)(&HeadNode->Next.Data));
        if (Head.Data == *((volatile LONG64 *)(&QueueHead->Head.Data))) {

            //
            // If the queue header node is equal to the queue tail node,
            // then either the queue is empty or the tail pointer is falling
            // behind. Otherwise, there is an entry in the queue that can
            // be removed.
            //

            NextNode = UnpackNBQPointer(&Next);
            TailNode = UnpackNBQPointer(&Tail);
            if (HeadNode == TailNode) {

                //
                // If the next node of head pointer is NULL, then the queue
                // is empty. Otherwise, attempt to move the tail forward.
                //

                if (NextNode == NULL) {
                    return FALSE;

                } else {
                    PackNBQPointer(&Insert, NextNode);
                    Insert.Count = Tail.Count + 1;
                    InterlockedCompareExchange64(&QueueHead->Tail.Data,
                                                 Insert.Data,
                                                 Tail.Data);
                }

            } else {

                //
                // There is an entry in the queue that can be removed.
                //

                *Value = NextNode->Value;
                PackNBQPointer(&Insert, NextNode);
                Insert.Count = Head.Count + 1;
                if (InterlockedCompareExchange64(&QueueHead->Head.Data,
                                                 Insert.Data,
                                                 Head.Data) == Head.Data) {

                    break;
                }
            }
        }

    } while (TRUE);

    //
    // Free the node that was removed for the list by inserting the node
    // in the associated SLIST.
    //

    InterlockedPushEntrySList(QueueHead->SlistHead,
                              (PSLIST_ENTRY)HeadNode);

    return TRUE;
}
示例#27
0
ULONG
NTAPI
MiFreePoolPages(IN PVOID StartingVa)
{
    PMMPTE PointerPte, StartPte;
    PMMPFN Pfn1, StartPfn;
    PFN_COUNT FreePages, NumberOfPages;
    KIRQL OldIrql;
    PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
    ULONG i, End;
    ULONG_PTR Offset;

    //
    // Handle paged pool
    //
    if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
    {
        //
        // Calculate the offset from the beginning of paged pool, and convert it
        // into pages
        //
        Offset = (ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart;
        i = (ULONG)(Offset >> PAGE_SHIFT);
        End = i;

        //
        // Now use the end bitmap to scan until we find a set bit, meaning that
        // this allocation finishes here
        //
        while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;

        //
        // Now calculate the total number of pages this allocation spans. If it's
        // only one page, add it to the S-LIST instead of freeing it
        //
        NumberOfPages = End - i + 1;
        if ((NumberOfPages == 1) &&
                (ExQueryDepthSList(&MiPagedPoolSListHead) < MiPagedPoolSListMaximum))
        {
            InterlockedPushEntrySList(&MiPagedPoolSListHead, StartingVa);
            return 1;
        }

        /* Delete the actual pages */
        PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i;
        FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL);
        ASSERT(FreePages == NumberOfPages);

        //
        // Acquire the paged pool lock
        //
        KeAcquireGuardedMutex(&MmPagedPoolMutex);

        //
        // Clear the allocation and free bits
        //
        RtlClearBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End);
        RtlClearBits(MmPagedPoolInfo.PagedPoolAllocationMap, i, NumberOfPages);

        //
        // Update the hint if we need to
        //
        if (i < MmPagedPoolInfo.PagedPoolHint) MmPagedPoolInfo.PagedPoolHint = i;

        //
        // Release the lock protecting the bitmaps
        //
        KeReleaseGuardedMutex(&MmPagedPoolMutex);

        //
        // And finally return the number of pages freed
        //
        return NumberOfPages;
    }
示例#28
0
	void SListImpl::push(SListEntry* entry)
	{
		InterlockedPushEntrySList(getDetail(this), reinterpret_cast<SLIST_ENTRY*>(entry));
	}