⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.cpp

📁 C语言库函数的原型,有用的拿去
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        if (UMSSchedulingContext::OnPrimary())
        {
            DebugBreak();
            return;
        }

        if (pContext != NULL && pContext->GetScheduler() != NULL) {
            swprintf_s(buffer, size, L"[%d:%d:%d:%d(%d)] %S: !!!!!!!Assert Failed(%S: %d)\n",
                pContext->GetVirtualProcessorId(),
                pContext->GetId(),
                pContext->GetScheduleGroupId(),
                pContext->ScheduleGroupRefCount(),
                GetCurrentThreadId(),
                value,
                filename,
                lineno);
        }
        else
            swprintf_s(buffer, size, L"[%d] %S: !!!!!!!Assert Failed(%S: %d)\n",
                GetCurrentThreadId(),
                value,
                filename,
                lineno);

        buffer[1024] = 0;

        fwprintf(g_DebugOutFilePtr, buffer);
        fflush(g_DebugOutFilePtr);

        OutputDebugStringW(buffer);
        DebugBreak();
        exit(-8);
    }

    void _ConcRT_CoreAssert(const char *value, const char* filename, int lineno)
    {
        //
        // Nothing here can block in any way.
        //
        DebugBreak();
    }

    template <size_t size>
    void 
    ConcRT_FillBuffer(
        wchar_t (&buffer)[size],
        const wchar_t * format,
        va_list args
        )
    {
        // Format the prefix giving the current context, thread, and vproc IDs
        int lenPrefix = 0;
        ContextBase * pContext = SchedulerBase::SafeFastCurrentContext();
        if (pContext != NULL && pContext->GetScheduler() != NULL) {
            lenPrefix = swprintf_s(buffer, size, L"[%d:%d:%d:%d(%d)] ",
                                   pContext->GetVirtualProcessorId(),
                                   pContext->GetId(),
                                   pContext->GetScheduleGroupId(),
                                   pContext->ScheduleGroupRefCount(),
                                   GetCurrentThreadId());
            if (lenPrefix < 0) {
                // Error in swprintf_s, don't bother with a prefix
                lenPrefix = 0;
            }
        } 

        // Format the trace message
        vswprintf_s(buffer + lenPrefix,
                    DIM(buffer) - lenPrefix,
                    format, args);

        // Append the trailing newline if missing
        int lenBuffer = static_cast<int>(wcslen(buffer));
        if (lenBuffer > 0 && buffer[lenBuffer - 1] != L'\n')
        {
            if (lenBuffer < DIM(buffer) - 1)
            {
                buffer[lenBuffer] = L'\n';
                buffer[lenBuffer + 1] = L'\0';
            }
            else
            {
                buffer[lenBuffer - 1] = L'\n';
            }
        }
    }

    void
    _ConcRT_DumpMessage(
        const wchar_t * format,
        ...
        )
    {
        wchar_t buffer[1024+1];
        va_list args;
        va_start(args, format);
        ConcRT_FillBuffer(buffer, format, args);
        va_end(args);
        buffer[1024] = 0;
        OutputDebugStringW(buffer);
        fwprintf(stderr, buffer);
    }

    // Trace -- Used for tracing and debugging
    void
    _ConcRT_Trace(
        int trace_level,
        const wchar_t * format,
        ...
        )
    {
        InitializeUtilityRoutines();

        // Check if tracing is disabled
        if ((g_DesiredTraceLevel & trace_level) == 0) {
            return;
        }

        wchar_t buffer[1024+1];

        va_list args;
        va_start(args, format);
        ConcRT_FillBuffer(buffer, format, args);
        va_end(args);

        buffer[1024] = 0;

        if (g_DebugOutFilePtr != NULL)
        {
            fwprintf(g_DebugOutFilePtr, buffer);
            if (g_CommitFrequency > 0 && (g_TraceCount++ % g_CommitFrequency) == 0)
                fflush(g_DebugOutFilePtr);
        }
        else
        {
            OutputDebugStringW(buffer);
        }
    }

#if _UMSTRACE
    void _ConcRT_VMTrace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
    {
        if (pVproc != NULL)
            reinterpret_cast<VirtualProcessor *>(pVproc)->Trace(traceEvt, pCtx, pVproc, data);
    }

    void _ConcRT_CMTrace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
    {
        if (pCtx != NULL)
            reinterpret_cast<InternalContextBase *>(pCtx)->Trace(traceEvt, pCtx, pVproc, data);
    }

    void _ConcRT_RVMTrace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
    {
        if (pVproc != NULL)
            reinterpret_cast<UMSFreeVirtualProcessorRoot *>(pVproc)->Trace(traceEvt, pCtx, pVproc, data);
    }

    void _ConcRT_RPMTrace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
    {
        if (pCtx != NULL)
            reinterpret_cast<UMSThreadProxy *>(pCtx)->Trace(traceEvt, pCtx, pVproc, data);
    }
#endif // _UMSTRACE

    //
    // _SpinLock
    //
    _CRTIMP _SpinLock::_SpinLock(volatile long& flag)
        : _M_flag(flag)
    {
        if ( _InterlockedCompareExchange(&_M_flag, 1, 0) != 0 )
        {
            _SpinWaitBackoffNone spinWait;
            do 
            {
                spinWait._SpinOnce();
            } while ( _InterlockedCompareExchange(&_M_flag, 1, 0) != 0 );
        }
    }

    _CRTIMP _SpinLock::~_SpinLock()
    {
        _InterlockedExchange(&_M_flag, 0);
    }



    _CRTIMP unsigned long Log2(size_t n) {
        unsigned long r;
#if defined(_M_X64)
        _BitScanReverse64(&r, n);
#else
        _BitScanReverse(&r, n);
#endif
        return r;
    }


    // Globals used for ConcRT shutdown
    volatile LONG LoadLibraryCount = 0;
    HMODULE HostModule = NULL;

    //
    // Adds a reference on a DLL where ConcRT is hosted, if it is a DLL, otherwise does nothing.
    // This is used to shutdown ConcRT on our own terms and not be forced into a difficult synchronous
    // shutdown by user's call to FreeLibrary. Note that this does not matter if a process shutdown
    // happens because all threads and ConcRT along with them are rudely terminated by the OS.
    //
    void ReferenceLoadLibrary()
    {
        HMODULE currentModuleHandle = (HMODULE) &__ImageBase;
        HMODULE currentExeHandle = GetModuleHandle(NULL);

        // Do this only if ConcRT is hosted inside a DLL
        if (currentModuleHandle != currentExeHandle)
        {
            WCHAR wcDllPath[MAX_PATH];

            if (GetModuleFileNameW(currentModuleHandle, wcDllPath, MAX_PATH))
            {
                HostModule = LoadLibraryW(wcDllPath);
            }
            else
            {
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }
        }
    }

    //
    // Adds a reference to a host module and then creates the thread. First reference is managed by LoadLibrary,
    // and all subsequent ones are reference counted internally to avoid LoadLibrary call overhead.
    //
    HANDLE LoadLibraryAndCreateThread
    (
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        SIZE_T dwStackSize,
        LPTHREAD_START_ROUTINE lpStartAddress,
        LPVOID lpParameter,
        DWORD dwCreationFlags,
        LPDWORD lpThreadId
    )
    {
        // Make sure that library (DLL) is not unloaded while ConcRT threads are still running
        if (InterlockedIncrement(&LoadLibraryCount) == 1)
        {
            ReferenceLoadLibrary();
            SchedulerBase::ReferenceStaticOneShot();
        }

        HANDLE threadHandle = CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);

        // Make sure the background thread is properly created
        if (threadHandle == NULL)
        {
            throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        return threadHandle;
    }

    //
    // Removes a reference count on a host module and in the case of last reference frees the library.
    //
    void FreeLibraryAndDestroyThread(DWORD exitCode)
    {
        // If this is the last ConcRT thread leaving the process try to cleanup
        if (InterlockedDecrement(&LoadLibraryCount) == 0)
        {
            SchedulerBase::CheckOneShotStaticDestruction();

            // If this is a DLL release the last LoadLibrary reference
            if (HostModule != NULL)
            {
                FreeLibraryAndExitThread(HostModule, exitCode);
            }
        }
    }

// We will use the GS cookie as a starting point
extern "C" uintptr_t __security_cookie;

    //
    // Initializes the cookie used to encode global data
    //
    ULONG_PTR  Security::InitializeCookie()
    {
        CORE_ASSERT(Security::s_initialized == 0);
        Security::s_initialized = 1;

        // Take advantage of ASLR and per-process cookie
        ULONG_PTR cookie = (ULONG_PTR)::EncodePointer((PVOID)&Security::s_cookie);

        // security cookie should be initialized before us.
        cookie ^= (ULONG_PTR)__security_cookie;

        // Add other randomization factors such as the thread creation time.

        FILETIME creationTime;
        FILETIME notused;

        if (GetThreadTimes(GetCurrentThread(), &creationTime, &notused, &notused, &notused))
        {
#if defined(_WIN64)
            ULARGE_INTEGER ul;

            ul.LowPart = creationTime.dwLowDateTime;
            ul.HighPart = creationTime.dwHighDateTime;
            cookie ^= ul.QuadPart;
#else
            cookie ^= creationTime.dwLowDateTime;
            cookie ^= creationTime.dwHighDateTime;
#endif
        }

        return cookie;
    }

    //
    // Encode the given pointer value
    //
    PVOID Security::EncodePointer(PVOID ptr)
    {
        CORE_ASSERT(Security::s_initialized != 0);
        return (PVOID)((ULONG_PTR)(ptr) ^ Security::s_cookie);
    }

    //
    // Decode the given pointer value
    //
    PVOID Security::DecodePointer(PVOID ptr)
    {
        return EncodePointer(ptr);
    }

} // namespace details
} // namespace Concurrency

//
// ConcRT static cleanup:
//
extern "C"
void __cdecl _concrt_static_cleanup(void);

_CRTALLOC(".CRT$XPB") static _PVFV pterm = _concrt_static_cleanup;

extern "C"
void __cdecl _concrt_static_cleanup(void)
{
    // Cleanup the TLS unless inside an EXE
    if (HostModule != NULL)
    {
        SchedulerBase::CheckOneShotStaticDestruction();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -