Пример #1
0
/*
 * Get memory 
 */
LOCAL void* imalloc( size_t size, IMACB *imacb )
{
	QUEUE	*q;
	VP	mem;
	UW	imask;

	/* If it is smaller than the minimum fragment size,
	   allocate the minimum size to it. */
	if ( size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	}
	size = ROUND(size);

	DI(imask);  /* Exclusive control by interrupt disable */
	SpinLock(&MemLockObj);

	/* Search FreeQue */
	q = searchFreeArea(size, imacb);
	if ( q != &imacb->freeque ) {
		/* There is free area: Split from FreeQue once */
		removeFreeQue(q);

		q = q - 1;
	} else {
		/* Reserve new pages because there is no free space */
		QUEUE	*e;
		size_t	n;

		/* Reserve pages */
		SpinUnlock(&MemLockObj);
		EI(imask);
		n = PageCount(size + sizeof(QUEUE) * 2);
		q = GetSysMemBlk(n, imacb->mematr);
		if ( q == NULL ) {
			goto err_ret;  /* Insufficient memory */
		}
		DI(imask);
		SpinLock(&MemLockObj);

		/* Register on AreaQue */
		e = (QUEUE*)((VB*)q + n * pagesz) - 1;
		insertAreaQue(&imacb->areaque, e);
		insertAreaQue(&imacb->areaque, q);
		setAreaFlag(q, AREA_TOP);
		setAreaFlag(e, AREA_END);
	}

	/* Allocate memory */
	mem = mem_alloc(q, size, imacb);

	SpinUnlock(&MemLockObj);
	EI(imask);
	return mem;

err_ret:
	BMS_DEBUG_PRINT(("imalloc error\n"));
	return NULL;
}
Пример #2
0
/*! Allocate PID info structure
	\param ppid - parent process id
	\return on success - pid info structure
			on failure - null
*/
PID_INFO_PTR AllocatePidInfo(int ppid)
{
	PID_INFO_PTR pid_info, pid_free;

	pid_info = AllocateBuffer(&pid_cache, CACHE_ALLOC_SLEEP);
	if ( pid_info == NULL )
		return NULL;

	SpinLock( &pid_info_lock );
	
	pid_free = STRUCT_ADDRESS_FROM_MEMBER( pid_zero.free_list.next, PID_INFO, free_list );

	assert( pid_free != NULL );
	assert( pid_free->free_count > 0 );
	pid_free->free_count--;
	
	/*use the first available pid*/
	pid_info->pid = pid_free->pid + 1;
	pid_info->ppid = ppid;
	pid_info->free_count = pid_free->free_count;
	if ( pid_free->free_count > 0 )
		AddToList( &pid_free->free_list, &pid_info->free_list );
	RemoveFromList( &pid_free->free_list );

	/*add to the used pid list*/
	AddToList( &pid_free->inuse_list, &pid_info->inuse_list );
	/*add to the tree*/
	InsertNodeIntoAvlTree( &pid_root, &pid_info->tree_node, 0, compare_pid_info );
	SpinUnlock( &pid_info_lock );

	return pid_info;
}
Пример #3
0
void FreePidInfo(PID_INFO_PTR pid_info)
{
	PID_INFO_PTR prev_used_pid, prev_free_pid;

	assert( pid_info != NULL );
	assert( pid_info != &pid_zero );

	SpinLock( &pid_info_lock );
	prev_used_pid = STRUCT_ADDRESS_FROM_MEMBER( &pid_info->inuse_list.prev,	PID_INFO, inuse_list.prev );
	prev_free_pid = STRUCT_ADDRESS_FROM_MEMBER( &pid_info->free_list.prev,	PID_INFO, free_list.prev );

	/*transfer free pids to previous node*/
	prev_used_pid->free_count = pid_info->free_count + 1;
	if ( pid_info->free_count > 0 )
	{
		AddToList( &prev_used_pid->free_list, &pid_info->free_list );
		RemoveFromList(  &pid_info->free_list );
	}
	else
		AddToList( &prev_used_pid->free_list, &pid_zero.free_list );

	RemoveFromList(  &pid_info->inuse_list );
	RemoveNodeFromAvlTree( &pid_root, &pid_info->tree_node, 0, compare_pid_info);
	SpinUnlock( &pid_info_lock );

	FreeBuffer( pid_info, &pid_cache );
}
Пример #4
0
 bool Label::ConditionalInit(const char *name)
 {
     SpinLock(g_labelLock);
     if(!m_name) Init(name);
     SpinUnlock(g_labelLock);
     return true;
 }
    // Flushes all available packets over the network... returns number of bytes sent
    bool AsyncStream::Flush(Socket &s)
    {
        OVR_CAPTURE_CPU_ZONE(AsyncStream_Flush);

        bool okay = true;

        // Take ownership of any pending data...
        SpinLock(m_bufferLock);
        Swap(m_cacheBegin, m_flushBegin);
        Swap(m_cacheTail,  m_flushTail);
        Swap(m_cacheEnd,   m_flushEnd);
        SpinUnlock(m_bufferLock);

        // Signal that we just swapped in a new buffer... wake up any threads that were waiting on us to flush.
        m_gate.Open();

        if(m_flushTail > m_flushBegin)
        {
            const size_t sendSize = (size_t)(m_flushTail-m_flushBegin);

            // first send stream header...
            StreamHeaderPacket streamheader;
            streamheader.threadID   = m_threadID;
            streamheader.streamSize = sendSize;
            okay = s.Send(&streamheader, sizeof(streamheader));

            // This send payload...
            okay = okay && s.Send(m_flushBegin, sendSize);
            m_flushTail = m_flushBegin;
        }

        OVR_CAPTURE_ASSERT(m_flushBegin == m_flushTail); // should be empty at this point...

        return okay;
    }
Пример #6
0
/*
 * Free memory
 *	It may be called during interrupt disable. In this case, need to wait
 *	 until interrupt is enabled and until free.
 */
LOCAL void ifree( void *ptr, IMACB *imacb )
{
	QUEUE	*aq;
	UW	imask;

	DI(imask);  /* Exclusive control by interrupt disable */
	SpinLock(&MemLockObj);

	aq = (QUEUE*)ptr - 1;
	clrAreaFlag(aq, AREA_USE);

	if ( !chkAreaFlag(aq->next, AREA_END|AREA_USE) ) {
		/* Merge with free area in after location */
		removeFreeQue(aq->next + 1);
		removeAreaQue(aq->next);
	}

	if ( !chkAreaFlag(aq, AREA_TOP) && !chkAreaFlag(aq->prev, AREA_USE) ) {
		/* Merge with free area in front location */
		aq = aq->prev;
		removeFreeQue(aq + 1);
		removeAreaQue(aq->next);
	}

	/* If the whole page is free, then free the page.
	 * However, do not free the page if it is called during
	 * interrupt disabled.
	 */
	if ( !isDI(imask) && chkAreaFlag(aq, AREA_TOP) && chkAreaFlag(aq->next, AREA_END) ) {
		/* Free pages */
		removeAreaQue(aq->next);
		removeAreaQue(aq);
		SpinUnlock(&MemLockObj);
		EI(imask);
		RelSysMemBlk(aq);
		DI(imask);
		SpinLock(&MemLockObj);
	} else {
		/* Register free area to FreeQue */
		appendFreeArea(aq, imacb);
	}

	SpinUnlock(&MemLockObj);
	EI(imask);
}
Пример #7
0
	CLzoWorkBuffer::~CLzoWorkBuffer()
	{
		SpinLock( &m_hLock );
		while( !m_stkBuffer.empty() )
		{
			delete[] reinterpret_cast<lzo_align_t*>( m_stkBuffer.top() );
			m_stkBuffer.pop();
		}
		SpinUnlock( &m_hLock );

		TLS_DestroyKey( m_tlsKey );
		DestroySpinLock( &m_hLock );
	}
Пример #8
0
/*! Creates and initalizes a vm descriptor
	\param vmap - virtual map of this descriptor
	\param start - starting va address of this descriptor range
	\param end - ending va address of this descriptor range
	\param vm_unit - vm unit which is backing this descriptor
	\param protection - protection for this range
	\return on success pointer to vm descriptor
			on failure null
*/
VM_DESCRIPTOR_PTR CreateVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR start, VADDR end, VM_UNIT_PTR vm_unit, VM_PROTECTION_PTR protection)
{
	VM_DESCRIPTOR_PTR vd;
	
	assert( PAGE_ALIGN_UP(end-start) <= PAGE_ALIGN_UP(vm_unit->size) );
	
	SpinLock(&vmap->lock);
	vmap->reference_count++;
	SpinUnlock(&vmap->lock);
	
	start = PAGE_ALIGN(start);
	//end = PAGE_ALIGN_UP(end)-1;
	
	vd = (VM_DESCRIPTOR_PTR)kmalloc(sizeof(VM_DESCRIPTOR), KMEM_NO_FAIL);
	//vd = AllocateBuffer( &vm_descriptor_cache, 0 );
	InitVmDescriptor( vd, vmap, start, end, vm_unit, protection);
	SpinLock(&vm_unit->lock);
	vm_unit->reference_count++;
	SpinUnlock(&vm_unit->lock);
	vd->reference_count++;
	return vd;
}
Пример #9
0
void *
mythread(void *arg)
{       
    char *letter = arg;
    printf("%s: begin\n", letter);
    int i;
    for (i = 0; i < max; i++) {
	SpinLock(&mutex);
	balance = balance + 1;
	SpinUnlock(&mutex);
    }
    printf("%s: done\n", letter);
    return NULL;
}
Пример #10
0
bool CTrThreadMsgBuffer::HandleAllLeftMsg()
{
	SpinLock(&m_Lock);
	std::swap(m_pWaitingLeftControlMsg, m_pDoingLeftControlMsg);
	SpinUnlock(&m_Lock);

	const size_t stSize = m_pDoingLeftControlMsg->size();
	for(size_t i = 0; i < stSize; i++)
	{
		ETrBallMsg eMsg = m_pDoingLeftControlMsg->at(i);
		HandleLeftControlMsg(eMsg);
	}

	m_pDoingLeftControlMsg->clear();

	return m_bQuit;
}
Пример #11
0
	char* CLzoWorkBuffer::GetBuffer()
	{
		char* pMem=reinterpret_cast<char*>( TLS_GetValue( m_tlsKey ) );

		if( !pMem )
		{
			//为什么要new这么多内存,参考testmini.c中的例子,这个文件是minilzo附带的.
			pMem=reinterpret_cast<char*>
				(new lzo_align_t[((LZO1X_1_MEM_COMPRESS) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)]);

			SpinLock( &m_hLock );
			m_stkBuffer.push( pMem );
			SpinUnlock( &m_hLock );

			TLS_SetValue( m_tlsKey, pMem );
		}
		return pMem;
	}
Пример #12
0
void CTrMsgBufferSwapper::HandleAllRightMsg()
{
	SpinLock(&m_Lock);
	std::swap(m_pWaitingRightControlMsg, m_pDoingRightControlMsg);
	SpinUnlock(&m_Lock);

	size_t stSize = m_pDoingRightControlMsg->size();

	for(size_t i = 0; i < stSize; i++)
	{
		IndexMsgPair_t& Value = m_pDoingRightControlMsg->at(i);
		CTrThreadMsgBuffer* pBuffer = m_vecTrBuffer[Value.first];

		pBuffer->HandleRightControlMsg((ETrBallMsg)Value.second);
	}
	
	m_pDoingRightControlMsg->clear();
}
Пример #13
0
void CTrMsgBufferSwapper::AddControlMsg(uint32 uIndex, uint32 uMsg)
{
	SpinLock(&m_Lock);
	m_pWaitingRightControlMsg->push_back(IndexMsgPair_t(uIndex, uMsg));
	SpinUnlock(&m_Lock);
}
Пример #14
0
/*
 * @brief
 *    BSP_ReleaseSpinlockIrqRestore: 解锁给定ID的自旋锁,恢复上下文。
 * @param		id:自旋锁编号
 * @param[in]	无。
 * @param[out]	无。
 * @returns:	0,解锁成功。
 * <p>			-1,自旋锁ID不合法。
 */
int BSP_ReleaseSpinlockIrqRestore(int id)
{
	BSP_EnableIntIrqRestore();
	return SpinUnlock(id);
}
Пример #15
0
/*
 * @brief
 *    BSP_ReleaseSpinlock: 解锁给定ID的自旋锁。
 * @param		id:自旋锁编号
 * @param[in]	无。
 * @param[out]	无。
 * @returns:	0,解锁成功。
 * <p>			-1,自旋锁ID不合法。
 */
int BSP_ReleaseSpinlock(int id)
{
	return SpinUnlock(id);
}
Пример #16
0
void CTrThreadMsgBuffer::AddControlMsg(ETrBallMsg eMsg)
{
	SpinLock(&m_Lock);
	m_pWaitingLeftControlMsg->push_back(eMsg);
	SpinUnlock(&m_Lock);
}
Пример #17
0
// Dispatch function
NTSTATUS DriverDispatch(DEVICE_OBJECT *device_object, IRP *irp)
{
	NTSTATUS ret = STATUS_SUCCESS;
	IO_STACK_LOCATION *stack;
	void *buf;
	bool ok;
	// Validate arguments
	if (wfp == NULL || device_object == NULL || irp == NULL || wfp->Halting)
	{
		return NDIS_STATUS_FAILURE;
	}

	// Get the IRP stack
	stack = IoGetCurrentIrpStackLocation(irp);

	// Initialize the number of bytes
	irp->IoStatus.Information = 0;
	irp->IoStatus.Status = STATUS_SUCCESS;

	buf = irp->UserBuffer;

	if (wfp->Halting != FALSE)
	{
		// Device driver is terminating
		irp->IoStatus.Information = STATUS_UNSUCCESSFUL;
		IoCompleteRequest(irp, IO_NO_INCREMENT);
		return STATUS_UNSUCCESSFUL;
	}

	ok = false;

	// Branch to each operation
	switch (stack->MajorFunction)
	{
	case IRP_MJ_CREATE:	// Open
		ok = true;
		break;

	case IRP_MJ_CLOSE:	// Close
		ok = true;
		break;

	case IRP_MJ_READ:	// Read
		ResetEvent(wfp->Event);
		break;

	case IRP_MJ_WRITE:	// Write
		if ((stack->Parameters.Write.Length % sizeof(WFP_LOCAL_IP)) == 0)
		{
			// Address check
			bool check_ok = true;
			__try
			{
				ProbeForRead(buf, stack->Parameters.Write.Length, 1);
			}
			__except (EXCEPTION_EXECUTE_HANDLER)
			{
				check_ok = false;
			}

			if (check_ok)
			{
				MDL *mdl = IoAllocateMdl(buf, stack->Parameters.Write.Length, false, false, NULL);
				UINT size = MIN(WFP_MAX_LOCAL_IP_COUNT * sizeof(WFP_LOCAL_IP), stack->Parameters.Write.Length);
				UCHAR *copied_buf = Malloc(size);
				UCHAR *old_buf;

				if (mdl != NULL)
				{
					MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
				}

				Copy(copied_buf, buf, size);

				SpinLock(wfp->LocalIPListLock);
				{
					old_buf = wfp->LocalIPListData;
					wfp->LocalIPListData = copied_buf;
					wfp->LocalIPListSize = size;
				}
				SpinUnlock(wfp->LocalIPListLock);

				if (old_buf != NULL)
				{
					Free(old_buf);
				}

				if (mdl != NULL)
				{
					MmUnlockPages(mdl);
					IoFreeMdl(mdl);
				}
			}
		}
		irp->IoStatus.Information = stack->Parameters.Write.Length;
		ok = true;
		break;
	}
Пример #18
0
            virtual void OnThreadExecute(void)
            {
                SetThreadName("OVR::Capture");
                while(m_listenSocket && !QuitSignaled())
                {
                    // try and accept a new socket connection...
                    SocketAddress streamAddr;
                    m_streamSocket = m_listenSocket->Accept(streamAddr);

                    // If no connection was established, something went totally wrong and we should just abort...
                    if(!m_streamSocket)
                        break;
                    
                    // Before we start sending capture data... first must exchange connection headers...
                    // First attempt to read in the request header from the Client...
                    ConnectionHeaderPacket clientHeader = {0};
                    if(!m_streamSocket->Receive(&clientHeader, sizeof(clientHeader)))
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }

                    // Load our connection flags...
                    const UInt32 connectionFlags = clientHeader.flags & g_initFlags;
                    
                    // Build and send return header... We *always* send the return header so that if we don't
                    // like something (like version number or feature flags), the client has some hint as to
                    // what we didn't like.
                    ConnectionHeaderPacket serverHeader = {0};
                    serverHeader.size    = sizeof(serverHeader);
                    serverHeader.version = ConnectionHeaderPacket::s_version;
                    serverHeader.flags   = connectionFlags;
                    if(!m_streamSocket->Send(&serverHeader, sizeof(serverHeader)))
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }

                    // Check version number...
                    if(clientHeader.version != serverHeader.version)
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }

                    // Check that we have any capture features even turned on...
                    if(!connectionFlags)
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }

                    // Finally, send our packet descriptors...
                    const PacketDescriptorPacket packetDescs[] =
                    {
                        BuildPacketDescriptorPacket<ThreadNamePacket>(),
                        BuildPacketDescriptorPacket<LabelPacket>(),
                        BuildPacketDescriptorPacket<FramePacket>(),
                        BuildPacketDescriptorPacket<VSyncPacket>(),
                        BuildPacketDescriptorPacket<CPUZoneEnterPacket>(),
                        BuildPacketDescriptorPacket<CPUZoneLeavePacket>(),
                        BuildPacketDescriptorPacket<GPUZoneEnterPacket>(),
                        BuildPacketDescriptorPacket<GPUZoneLeavePacket>(),
                        BuildPacketDescriptorPacket<GPUClockSyncPacket>(),
                        BuildPacketDescriptorPacket<SensorRangePacket>(),
                        BuildPacketDescriptorPacket<SensorPacket>(),
                        BuildPacketDescriptorPacket<FrameBufferPacket>(),
                        BuildPacketDescriptorPacket<LogPacket>(),
                    };
                    const PacketDescriptorHeaderPacket packetDescHeader = { sizeof(packetDescs) / sizeof(packetDescs[0]) };
                    if(!m_streamSocket->Send(&packetDescHeader, sizeof(packetDescHeader)))
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }
                    if(!m_streamSocket->Send(&packetDescs, sizeof(packetDescs)))
                    {
                        m_streamSocket->Release();
                        m_streamSocket = NULL;
                        continue;
                    }
                    
                    // Connection established!

                    // Signal that we are connected!
                    AtomicExchange(g_connectionFlags, connectionFlags);

                    // Technically any Labels that get initialized on another thread bettween the barrier and loop
                    // will get sent over the network twice, but OVRMonitor will handle that.
                    SpinLock(g_labelLock);
                    for(Label *l=Label::GetHead(); l; l=l->GetNext())
                    {
                        SendLabelPacket(*l);
                    }
                    SpinUnlock(g_labelLock);

                    // Start CPU/GPU/Thermal sensors...
                    StandardSensors stdsensors;
                    if(CheckConnectionFlag(Enable_CPU_Clocks) || CheckConnectionFlag(Enable_GPU_Clocks) || CheckConnectionFlag(Enable_Thermal_Sensors))
                    {
                        stdsensors.Start();
                    }

                    // Spin as long as we are connected flushing data from our data stream...
                    while(!QuitSignaled())
                    {
                        const UInt64 flushBeginTime = GetNanoseconds();
                        if(!AsyncStream::FlushAll(*m_streamSocket))
                        {
                            // Error occured... shutdown the connection.
                            AtomicExchange(g_connectionFlags, (UInt32)0);
                            m_streamSocket->Shutdown();
                            break;
                        }
                        const UInt64 flushEndTime   = GetNanoseconds();
                        const UInt64 flushDeltaTime = flushEndTime - flushBeginTime;
                        const UInt64 sleepTime      = 5000000; // 5ms
                        if(flushDeltaTime < sleepTime)
                        {
                            // Sleep just a bit to keep the thread from killing a core and to let a good chunk of data build up
                            ThreadSleepNanoseconds(sleepTime - flushDeltaTime);
                        }
                    }

                    // TODO: should we call AsyncStream::Shutdown() here???

                    // Close down our sensor thread...
                    stdsensors.QuitAndWait();

                    // Connection was closed at some point, lets clean up our socket...
                    m_streamSocket->Release();
                    m_streamSocket = NULL;

                } // while(m_listenSocket && !QuitSignaled())
            }