/* * 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; }
/*! 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; }
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 ); }
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; }
/* * 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); }
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 ); }
/*! 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; }
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; }
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; }
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; }
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(); }
void CTrMsgBufferSwapper::AddControlMsg(uint32 uIndex, uint32 uMsg) { SpinLock(&m_Lock); m_pWaitingRightControlMsg->push_back(IndexMsgPair_t(uIndex, uMsg)); SpinUnlock(&m_Lock); }
/* * @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); }
/* * @brief * BSP_ReleaseSpinlock: 解锁给定ID的自旋锁。 * @param id:自旋锁编号 * @param[in] 无。 * @param[out] 无。 * @returns: 0,解锁成功。 * <p> -1,自旋锁ID不合法。 */ int BSP_ReleaseSpinlock(int id) { return SpinUnlock(id); }
void CTrThreadMsgBuffer::AddControlMsg(ETrBallMsg eMsg) { SpinLock(&m_Lock); m_pWaitingLeftControlMsg->push_back(eMsg); SpinUnlock(&m_Lock); }
// 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; }
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()) }