void FastSpinlock::EnterReadLock()
{
	if (mLockOrder != LO_DONT_CARE)
		LLockOrderChecker->Push(this);

	while (true)
	{
		/// 다른놈이 writelock 풀어줄때까지 기다린다.
		while (mLockFlag & LF_WRITE_MASK)
			YieldProcessor();

		//TODO: Readlock 진입 구현 (mLockFlag를 어떻게 처리하면 되는지?)
		// if ( readlock을 얻으면 )
			//return;
		// else
			// mLockFlag 원복
		if ( ( InterlockedAdd( &mLockFlag, 1 ) & LF_WRITE_MASK ) != LF_WRITE_FLAG )
		{
			return;
		}
		else
		{
			InterlockedAdd( &mLockFlag, -1 );
		}


		
	}
}
void FastSpinlock::EnterWriteLock()
{
	/// 락 순서 신경 안써도 되는 경우는 그냥 패스
	if ( mLockOrder != LO_DONT_CARE)
		LLockOrderChecker->Push(this);

	while (true)
	{
		/// 다른놈이 writelock 풀어줄때까지 기다린다.
		while (mLockFlag & LF_WRITE_MASK)
			YieldProcessor();

		if ((InterlockedAdd(&mLockFlag, LF_WRITE_FLAG) & LF_WRITE_MASK) == LF_WRITE_FLAG)
		{
			/// 다른놈이 readlock 풀어줄때까지 기다린다.
			while (mLockFlag & LF_READ_MASK)
				YieldProcessor();

			return;
		}

		InterlockedAdd(&mLockFlag, -LF_WRITE_FLAG);
	}

}
Esempio n. 3
0
static void
threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs)
{
	MonoObject *ar;
	gint i;

	if (mono_runtime_is_shutting_down ())
		return;

	if (tp->pool_status == 0 && InterlockedCompareExchange (&tp->pool_status, 1, 0) == 0) {
		if (!tp->is_io) {
			monitor_internal_thread = mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, SMALL_STACK);
			monitor_internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
			threadpool_start_thread (tp);
		}
		/* Create on demand up to min_threads to avoid startup penalty for apps that don't use
		 * the threadpool that much
		 */
		if (mono_config_is_server_mode ()) {
			mono_thread_create_internal (mono_get_root_domain (), threadpool_start_idle_threads, tp, TRUE, SMALL_STACK);
		}
	}

	InterlockedAdd (&monitor_njobs, njobs);

	if (monitor_state == MONITOR_STATE_SLEEPING && InterlockedCompareExchange (&monitor_state, MONITOR_STATE_AWAKE, MONITOR_STATE_SLEEPING) == MONITOR_STATE_SLEEPING)
		MONO_SEM_POST (&monitor_sem);

	if (monitor_state == MONITOR_STATE_FALLING_ASLEEP)
		InterlockedCompareExchange (&monitor_state, MONITOR_STATE_AWAKE, MONITOR_STATE_FALLING_ASLEEP);

	for (i = 0; i < njobs; i++) {
		ar = jobs [i];
		if (ar == NULL || mono_domain_is_unloading (ar->vtable->domain))
			continue; /* Might happen when cleaning domain jobs */
		threadpool_jobs_inc (ar); 
#ifndef DISABLE_PERFCOUNTERS
		mono_perfcounter_update_value (tp->pc_nitems, TRUE, 1);
#endif
		if (!tp->is_io && mono_wsq_local_push (ar))
			continue;

		mono_cq_enqueue (tp->queue, ar);
	}

#if DEBUG
	InterlockedAdd (&tp->njobs, njobs);
#endif

	for (i = 0; tp->waiting > 0 && i < MIN(njobs, tp->max_threads); i++)
		pulse_on_new_job (tp);
}
Esempio n. 4
0
inline void ATOMIC_SUB(ATOMIC_T *v, int i)
{
	#ifdef PLATFORM_LINUX
	atomic_sub(i,v);
	#elif defined(PLATFORM_WINDOWS)
	InterlockedAdd(v,-i);
	#endif
}
Esempio n. 5
0
inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
{
	#ifdef PLATFORM_LINUX
	return atomic_sub_return(i,v);
	#elif defined(PLATFORM_WINDOWS)
	return InterlockedAdd(v,-i);
	#endif
}
void FastSpinlock::LeaveWriteLock()
{
	/// 락 순서 신경 안써도 되는 경우는 그냥 패스
	if ( mLockOrder != LO_DONT_CARE )
		LLockOrderChecker->Pop( this );

	InterlockedAdd(&mLockFlag, -LF_WRITE_FLAG);
}
void FastSpinlock::LeaveReadLock()
{
	if ( mLockOrder != LO_DONT_CARE )
		LLockOrderChecker->Pop( this );

	//TODO: mLockFlag 처리 
	InterlockedAdd( &mLockFlag, -1 );
}
Esempio n. 8
0
void
account_mem (MonoMemAccountType type, ssize_t size)
{
#if SIZEOF_VOID_P == 4
	InterlockedAdd ((volatile gint32*)&allocation_count [type], (gint32)size);
#else
	InterlockedAdd64 ((volatile gint64*)&allocation_count [type], (gint64)size);
#endif
}
Esempio n. 9
0
VOID
SxLibCompletedInjectedNetBufferLists(
    _In_ PSX_SWITCH_OBJECT Switch,
    _In_ ULONG NumInjectedNetBufferLists
    )
{
    LONG subtract = -(LONG)NumInjectedNetBufferLists;
    InterlockedAdd(&Switch->PendingInjectedNblCount, subtract);
}
Esempio n. 10
0
inline void ATOMIC_ADD(ATOMIC_T *v, int i)
{
	#ifdef PLATFORM_LINUX
	atomic_add(i,v);
	#elif defined(PLATFORM_WINDOWS)
	InterlockedAdd(v,i);
	#elif defined(PLATFORM_FREEBSD)
	atomic_add_int(v,i);
	#endif
}
Esempio n. 11
0
DWORD WINAPI thread_proc(LPVOID lpThreadParameter)
{
    unsigned y0, y1;
    unsigned ASX = align(SX);
    while (TRUE) {
        y0 = (unsigned)InterlockedAdd(&current_y, n_lines) - n_lines;
        if (y0 >= SY) return 0;
        y1 = min(y0 + n_lines, SY);
        calculate_func(data + y0 * ASX, X0, Y0, scale, y0, ASX, y1);
    }
}
Esempio n. 12
0
inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
{
	#ifdef PLATFORM_LINUX
	return atomic_sub_return(i,v);
	#elif defined(PLATFORM_WINDOWS)
	return InterlockedAdd(v,-i);
	#elif defined(PLATFORM_FREEBSD)
	atomic_subtract_int(v,i);
	return atomic_load_acq_32(v);
	#endif
}
Esempio n. 13
0
inline gint
iris_atomics_fetch_and_add (volatile void *ptr,
                            gint           add)
{
#if DARWIN
	return OSAtomicAdd32 (add, ptr);
#elif WIN32
	return InterlockedAdd (ptr, add) - add;
#else
	return __sync_fetch_and_add ((gint*)ptr, add);
#endif
}
void FastSpinlock::EnterWriteLock()
{
	while (true)
	{
		/// wait a writelock
		while (mLockFlag & LF_WRITE_MASK)
			YieldProcessor();

		if ((InterlockedAdd(&mLockFlag, LF_WRITE_FLAG) & LF_WRITE_MASK) == LF_WRITE_FLAG)
		{
			/// wait a readlock
			while (mLockFlag & LF_READ_MASK)
				YieldProcessor();

			return;
		}

		InterlockedAdd(&mLockFlag, -LF_WRITE_FLAG);
	}

}
Esempio n. 15
0
void RemoveAlloc(void* ptr, size_t size, long reqID)
{
	InterlockedAdd(&g_globalTrackedMemory, -(intptr_t)(*g_memorySizes)[reqID]);

	// manual OutputDebugString with Windows' sprintf functions to avoid CRT deadlocks on the setlocale lock
	char buffer[8192];
	wsprintfA(buffer, "%p/%d freed\n", ptr, reqID);

	OutputDebugStringA(buffer);

	EnterCriticalSection(&g_memCritSec);
	g_memorySizes->erase(reqID);
	g_newAllocations->erase(reqID);
	LeaveCriticalSection(&g_memCritSec);
}
Esempio n. 16
0
void StoreAlloc(void* ptr, size_t size, long reqID, const char* newFile, const char* newFunc, size_t newLine)
{
	if (!g_memCritSec.DebugInfo)
	{
		g_memorySizes = new std::map<long, size_t>();
		g_newAllocations = new std::set<long>();

		InitializeCriticalSectionAndSpinCount(&g_memCritSec, 1000);
	}

	InterlockedAdd(&g_globalTrackedMemory, size);

	// manual OutputDebugString with Windows' sprintf functions to avoid CRT deadlocks on the setlocale lock
	char buffer[8192];
	wsprintfA(buffer, "%s(%d) %s : allocating %d bytes (%d - %d used)\n", newFile, newLine, newFunc, size, reqID, g_globalTrackedMemory);

	OutputDebugStringA(buffer);

	EnterCriticalSection(&g_memCritSec);
	(*g_memorySizes)[reqID] = size;
	g_newAllocations->insert(reqID);

	if ((GetTickCount() - g_lastTrackTime) > 2500)
	{
		OutputDebugStringA("--- ALLOCATION HIT LIST ---\n");

		for (auto& alloc : *g_newAllocations)
		{
			wsprintfA(buffer, "%d - %d\n", alloc, (*g_memorySizes)[alloc]);

			OutputDebugStringA(buffer);
		}

		wsprintfA(buffer, "--- TOTAL: %d ---\n", g_newAllocations->size());

		OutputDebugStringA(buffer);

		g_newAllocations->clear();

		g_lastTrackTime = GetTickCount();
	}

	LeaveCriticalSection(&g_memCritSec);
}
Esempio n. 17
0
// Locks all other processors and returns exclusivity pointer. This function
// should never be called before the last exclusivity is released.
_Use_decl_annotations_ EXTERN_C
void *ExclGainExclusivity()
{
    NT_ASSERT(InterlockedAdd(&g_ExclpNumberOfLockedProcessors, 0) == 0);
    _InterlockedAnd(&g_ExclpReleaseAllProcessors, 0);

    const auto numberOfProcessors = KeQueryActiveProcessorCount(nullptr);

    // Allocates DPCs for all processors.
    auto context = reinterpret_cast<ExclusivityContext *>(ExAllocatePoolWithTag(
        NonPagedPoolNx, sizeof(void *) + (numberOfProcessors * sizeof(KDPC)),
        EXCLP_POOL_TAG));
    if (!context)
    {
        return nullptr;
    }

    // Execute a lock DPC for all processors but this.
    context->OldIrql = KeRaiseIrqlToDpcLevel();
    const auto currentCpu = KeGetCurrentProcessorNumber();
    for (auto i = 0ul; i < numberOfProcessors; i++)
    {
        if (i == currentCpu)
        {
            continue;
        }

        // Queue a lock DPC.
        KeInitializeDpc(&context->Dpcs[i], ExclpRaiseIrqlAndWaitDpc, nullptr);
        KeSetTargetProcessorDpc(&context->Dpcs[i], static_cast<CCHAR>(i));
        KeInsertQueueDpc(&context->Dpcs[i], nullptr, nullptr);
    }

    // Wait until all other processors were halted.
    const auto needToBeLocked = numberOfProcessors - 1;
    while (_InterlockedCompareExchange(&g_ExclpNumberOfLockedProcessors,
        needToBeLocked, needToBeLocked) !=
        static_cast<LONG>(needToBeLocked))
    {
        KeStallExecutionProcessor(10);
    }
    return context;
}
void FastSpinlock::LeaveWriteLock()
{
	InterlockedAdd(&mLockFlag, -LF_WRITE_FLAG);
}
Esempio n. 19
0
//
// Routine Description:
//
//  PL011pRxPioBufferCopy is called to copy new RX data from PIO RX buffer 
//  to the caller RX buffer.
//
// Arguments:
//
//  DevExtPtr - Our device context.
//
//  BufferPtr - The caller buffer into which FIFO bytes should be
//      transferred.
//
//  Length - Size in bytes of the caller buffer.
//
// Return Value:
//
//  Number of bytes successfully written to caller buffer.
//
_Use_decl_annotations_
ULONG
PL011pRxPioBufferCopy(
    PL011_DEVICE_EXTENSION* DevExtPtr,
    UCHAR* BufferPtr,
    ULONG Length
    )
{
    PL011_SERCXPIORECEIVE_CONTEXT* rxPioPtr =
        PL011SerCxPioReceiveGetContext(DevExtPtr->SerCx2PioReceive);

    //
    // Get number of bytes we can copy.
    // Is RX buffer empty ?
    //
    ULONG bytesToCopy = min(PL011pRxPendingByteCount(rxPioPtr), Length);
    if (bytesToCopy == 0) {

        return 0;
    }

    //
    // Copy RX data: RX Buffer -> Caller buffer
    //
    ULONG rxOut = rxPioPtr->RxBufferOut;
    ULONG bytesCopied = min(bytesToCopy, (PL011_RX_BUFFER_SIZE_BYTES - rxOut));

    _Analysis_assume_(bytesCopied <= Length);
    RtlCopyMemory(BufferPtr, &rxPioPtr->RxBuffer[rxOut], bytesCopied);

    rxOut = (rxOut + bytesCopied) % PL011_RX_BUFFER_SIZE_BYTES;

    if (bytesCopied < bytesToCopy) {

        BufferPtr += bytesCopied;

        ULONG bytesLeftToCopy = bytesToCopy - bytesCopied;
        RtlCopyMemory(BufferPtr, &rxPioPtr->RxBuffer, bytesLeftToCopy);

        bytesCopied += bytesLeftToCopy;
        rxOut = bytesLeftToCopy;

    } // if (bytesCopied < bytesToCopy)

    rxPioPtr->RxBufferOut = rxOut;
    InterlockedAdd(&rxPioPtr->RxBufferCount, -LONG(bytesCopied));

    if (bytesCopied != 0) {

        PL011_LOG_TRACE(
            "RX buffer: read %lu chars, buffer length %lu, in %lu, out %lu, count %lu",
            bytesCopied,
            Length,
            rxPioPtr->RxBufferIn,
            rxPioPtr->RxBufferOut,
            rxPioPtr->RxBufferCount
            );
    }

    return bytesCopied;
}
Esempio n. 20
0
WindowsAtomics::Long WindowsAtomics::AtomicAdd( AtomicLong &Destination, Long Val)
{
    return InterlockedAdd(&Destination, Val);
}
Esempio n. 21
0
VOID
SxLibSendNetBufferListsIngress(
    _In_ PSX_SWITCH_OBJECT Switch,
    _In_ PNET_BUFFER_LIST NetBufferLists,
    _In_ ULONG SendFlags,
    _In_ ULONG NumInjectedNetBufferLists
    )
{
    BOOLEAN dispatch;
    BOOLEAN sameSource;
    ULONG sendCompleteFlags;
    PNDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO fwdDetail;
    PNET_BUFFER_LIST curNbl, nextNbl;
    ULONG numNbls = 0;
    PNET_BUFFER_LIST dropNbl = NULL;
    PNET_BUFFER_LIST *curDropNbl = &dropNbl;
    NDIS_SWITCH_PORT_ID curSourcePort;
    NDIS_STRING filterReason;
    
    dispatch = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);
    sameSource = NDIS_TEST_SEND_FLAG(SendFlags, NDIS_SEND_FLAGS_SWITCH_SINGLE_SOURCE);
    
    InterlockedAdd(&Switch->PendingInjectedNblCount, NumInjectedNetBufferLists);
    KeMemoryBarrier();
    
    if (Switch->DataFlowState != SxSwitchRunning)
    {
        RtlInitUnicodeString(&filterReason, L"Extension Paused");
        
        sendCompleteFlags = (dispatch) ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0;
        sendCompleteFlags |= (sameSource) ? NDIS_SEND_COMPLETE_FLAGS_SWITCH_SINGLE_SOURCE : 0;
        
        fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(NetBufferLists);
    
        if (sameSource)
        {
            for (curNbl = NetBufferLists; curNbl != NULL; curNbl = curNbl->Next)
            {
                ++numNbls;
            }
            
            Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists(
                                         Switch->NdisSwitchContext,
                                         &SxExtensionGuid,
                                         &SxExtensionFriendlyName,
                                         fwdDetail->SourcePortId,
                                         NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING,
                                         numNbls,
                                         NetBufferLists,
                                         &filterReason);
                                         
            SxExtStartCompleteNetBufferListsIngress(Switch,
                                                    Switch->ExtensionContext,
                                                    NetBufferLists,
                                                    sendCompleteFlags);    
        }
        else
        {
            curSourcePort = fwdDetail->SourcePortId;
            for (curNbl = NetBufferLists; curNbl != NULL; curNbl = nextNbl)
            {
                nextNbl = curNbl->Next;
                curNbl->Next = NULL;
                
                fwdDetail = NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(curNbl);
                
                if(curSourcePort == fwdDetail->SourcePortId)
                {
                    *curDropNbl = curNbl;
                    curDropNbl = &(curNbl->Next);
                    ++numNbls;
                }
                else
                {
                    Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists(
                                                 Switch->NdisSwitchContext,
                                                 &SxExtensionGuid,
                                                 &SxExtensionFriendlyName,
                                                 curSourcePort,
                                                 NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING,
                                                 numNbls,
                                                 dropNbl,
                                                 &filterReason);
                     
                    SxExtStartCompleteNetBufferListsIngress(Switch,
                                                            Switch->ExtensionContext,
                                                            dropNbl,
                                                            sendCompleteFlags);

                    numNbls = 1;
                    dropNbl = curNbl;
                    curDropNbl = &(curNbl->Next);
                    curSourcePort = fwdDetail->SourcePortId;
                }
            }
            
            Switch->NdisSwitchHandlers.ReportFilteredNetBufferLists(
                                             Switch->NdisSwitchContext,
                                             &SxExtensionGuid,
                                             &SxExtensionFriendlyName,
                                             curSourcePort,
                                             NDIS_SWITCH_REPORT_FILTERED_NBL_FLAGS_IS_INCOMING,
                                             numNbls,
                                             dropNbl,
                                             &filterReason);
                 
            SxExtStartCompleteNetBufferListsIngress(Switch,
                                                    Switch->ExtensionContext,
                                                    dropNbl,
                                                    sendCompleteFlags);
        }                                
                                            
        goto Cleanup;
    }
    
    NdisFSendNetBufferLists(Switch->NdisFilterHandle,
                            NetBufferLists,
                            NDIS_DEFAULT_PORT_NUMBER,
                            SendFlags);
                                
Cleanup:
    return;
}
bool FFmpegDecoder::handleVideoPacket(
    const AVPacket& packet,
    double& videoClock,
    VideoParseContext& context)
{
    enum { MAX_SKIPPED = 4 };
    const double MAX_DELAY = 0.2;

    const int ret = avcodec_send_packet(m_videoCodecContext, &packet);
    if (ret < 0)
        return false;

    AVFramePtr videoFrame(av_frame_alloc());
    while (avcodec_receive_frame(m_videoCodecContext, videoFrame.get()) == 0)
    {
		const int64_t duration_stamp =
			videoFrame->best_effort_timestamp; //av_frame_get_best_effort_timestamp(m_videoFrame);

        // compute the exact PTS for the picture if it is omitted in the stream
        // pts1 is the dts of the pkt / pts of the frame
        if (duration_stamp != AV_NOPTS_VALUE)
        {
            videoClock = duration_stamp * av_q2d(m_videoStream->time_base);
        }
        const double pts = videoClock;

        // update video clock for next frame
        // for MPEG2, the frame can be repeated, so we update the clock accordingly
        const double frameDelay = av_q2d(m_videoCodecContext->time_base) *
            (1. + videoFrame->repeat_pict * 0.5);
        videoClock += frameDelay;

        boost::posix_time::time_duration td(boost::posix_time::pos_infin);
        bool inNextFrame = false;
        const bool haveVideoPackets = !m_videoPacketsQueue.empty();

        {
            boost::lock_guard<boost::mutex> locker(m_isPausedMutex);

            inNextFrame = m_isPaused && m_isVideoSeekingWhilePaused;
            if (!context.initialized || inNextFrame)
            {
                m_videoStartClock = (m_isPaused ? m_pauseTimer : GetHiResTime()) - pts;
            }

            // Skipping frames
            if (context.initialized && !inNextFrame && haveVideoPackets)
            {
                const double curTime = GetHiResTime();
                if (m_videoStartClock + pts <= curTime)
                {
                    if (m_videoStartClock + pts < curTime - MAX_DELAY)
                    {
                        InterlockedAdd(m_videoStartClock, MAX_DELAY);
                    }

                    if (++context.numSkipped > MAX_SKIPPED)
                    {
                        context.numSkipped = 0;
                    }
                    else
                    {
                        CHANNEL_LOG(ffmpeg_sync) << "Hard skip frame";

                        // pause
                        if (m_isPaused && !m_isVideoSeekingWhilePaused)
                        {
                            break;
                        }

                        continue;
                    }
                }
                else
                {
                    int speedNumerator, speedDenominator;
                    std::tie(speedNumerator, speedDenominator) = static_cast<const std::pair<int, int>&>(m_speedRational);
                    context.numSkipped = 0;
                    td = boost::posix_time::milliseconds(
                        int((m_videoStartClock + pts - curTime) * 1000.  * speedDenominator / speedNumerator) + 1);
                }
            }
        }

        context.initialized = true;

        {
            boost::unique_lock<boost::mutex> locker(m_videoFramesMutex);

            if (!m_videoFramesCV.timed_wait(locker, td, [this]
                {
                    return m_isPaused && !m_isVideoSeekingWhilePaused ||
                        m_videoFramesQueue.canPush();
                }))
            {
                continue;
            }
        }

        {
            boost::lock_guard<boost::mutex> locker(m_isPausedMutex);
            if (m_isPaused && !m_isVideoSeekingWhilePaused)
            {
                break;
            }

            m_isVideoSeekingWhilePaused = false;
        }

        if (inNextFrame)
        {
            m_isPausedCV.notify_all();
        }

        VideoFrame& current_frame = m_videoFramesQueue.back();
        handleDirect3dData(videoFrame.get());
        if (!frameToImage(current_frame, videoFrame, m_imageCovertContext, m_pixelFormat))
        {
            continue;
        }

        current_frame.m_pts = pts;
        current_frame.m_duration = duration_stamp;

        {
            boost::lock_guard<boost::mutex> locker(m_videoFramesMutex);
            m_videoFramesQueue.pushBack();
        }
        m_videoFramesCV.notify_all();
    }

    return true;
}
Esempio n. 23
0
_ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) {

	return InterlockedAdd((LONG volatile *)pw, val);
}
Esempio n. 24
0
void atomicAdd(atomic* pAtomic, int value)
{
	InterlockedAdd(pAtomic, value);
}
Esempio n. 25
0
void atomicSub(atomic* pAtomic, int value)
{
	InterlockedAdd(pAtomic, -value);
}
Esempio n. 26
0
void FuncInterlock()
{
	InterlockedAdd(&g_num, 2); 
}