HRESULT HttpListenerInitializeThreadPool(PHTTP_LISTENER listener) { DWORD dwResult; TP_CALLBACK_ENVIRON tpCalbackEnviron; PTP_POOL pThreadPool; //I nitialize the threadPool environment ZeroMemory(&( tpCalbackEnviron ), sizeof( TP_CALLBACK_ENVIRON ) ); InitializeThreadpoolEnvironment(&tpCalbackEnviron); // Create the threadpool pThreadPool = CreateThreadpool(NULL); if(pThreadPool == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } else { SetThreadpoolCallbackPool(&tpCalbackEnviron, pThreadPool); dwResult = HRESULT_FROM_WIN32(GetLastError()); } listener->pThreadPool = pThreadPool; listener->errorCode = dwResult; return dwResult; }
void OnCreatePool() { // Sanity checks if (g_pThreadPool != NULL) { OnDeletePool(); } // Initialize the private thread pool g_pThreadPool = CreateThreadpool(NULL); if (g_pThreadPool == NULL) { MessageBox( NULL, TEXT("Impossible to create private thread pool"), TEXT("Initialization error"), MB_ICONERROR | MB_OK ); return; } // Change min=2 / max=4 thread pool parameters SetThreadpoolThreadMaximum(g_pThreadPool, 4); if (!SetThreadpoolThreadMinimum(g_pThreadPool, 2)) { MessageBox( NULL, TEXT("SetThreadpoolThreadMinimum failed."), TEXT("Initialization error"), MB_ICONERROR | MB_OK ); return; } // Reset the callback environment // Note: this is an inline function from winbase.h // that calls TpInitializeCallbackEnviron() in winnt.h. // --> // CallbackEnviron->Version = 1; // CallbackEnviron->Pool = NULL; // CallbackEnviron->CleanupGroup = NULL; // CallbackEnviron->CleanupGroupCancelCallback = NULL; // CallbackEnviron->RaceDll = NULL; // CallbackEnviron->ActivationContext = NULL; // CallbackEnviron->FinalizationCallback = NULL; // CallbackEnviron->u.Flags = 0; InitializeThreadpoolEnvironment(&g_callbackEnvironment); // Associate our private thread pool with the callback environment // Note: this is an inline function from winbase.h // that calls TpSetCallbackThreadpool() in winnt.h. // --> // CallbackEnviron->Pool = Pool; SetThreadpoolCallbackPool(&g_callbackEnvironment, g_pThreadPool); }
int TestPoolThread(int argc, char* argv[]) { TP_POOL* pool; pool = CreateThreadpool(NULL); SetThreadpoolThreadMinimum(pool, 8); /* default is 0 */ SetThreadpoolThreadMaximum(pool, 64); /* default is 500 */ CloseThreadpool(pool); return 0; }
void CThreadPools::CreateThreadPools(int nThreadCount) { BOOL bRet = FALSE; InitializeThreadpoolEnvironment(&m_CallBackEnviron); // Create a custom, dedicated thread pool m_pPool = CreateThreadpool(NULL); if (NULL==m_pPool) { CloseThreadPools(); } m_nRollback = 1; // pool creation succeeded // The thread pool is made persistent simply by setting // both the minimum and maximum threads to 1. SetThreadpoolThreadMaximum(m_pPool, nThreadCount); bRet = SetThreadpoolThreadMinimum(m_pPool, 1); if (FALSE==bRet) { CloseThreadPools(); } //Create a cleanup group for this thread pool m_pCleanupGroup = CreateThreadpoolCleanupGroup(); if (NULL==m_pCleanupGroup) { CloseThreadPools(); } m_nRollback = 2; // Cleanup group creation succeeded // Associate the callback environment with our thread pool. SetThreadpoolCallbackPool(&m_CallBackEnviron, m_pPool); // Associate the cleanup group with our thread pool. // Objects created with the same callback environment // as the cleanup group become members of the cleanup group. SetThreadpoolCallbackCleanupGroup(&m_CallBackEnviron, m_pCleanupGroup, NULL); m_nRollback = 3; // Creation of work succeeded }
bool test_new_thread_pool() {//success is true, failure is false int sockErr; WSADATA lpWSAData={0}; sockErr=WSAStartup(0x202, &lpWSAData); sListen=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if(INVALID_SOCKET==sListen){ DebugBreak(); } GUID GuidDisconnectEx = WSAID_DISCONNECTEX; DWORD dwBytes; WSAIoctl(sListen, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidDisconnectEx, sizeof (GuidDisconnectEx), &DisconnectEx, sizeof (DisconnectEx), &dwBytes, NULL, NULL); InitializeThreadpoolEnvironment(&tEnvrion); pMainPool=CreateThreadpool(NULL); pCleanup=CreateThreadpoolCleanupGroup(); SetThreadpoolCallbackCleanupGroup(&tEnvrion, pCleanup, 0); SetThreadpoolCallbackPool(&tEnvrion, pMainPool); pListen=CreateThreadpoolIo((HANDLE)sListen, acceptingIoThreadProc, 0, &tEnvrion); sockaddr_in service={0}; service.sin_family=AF_INET; service.sin_port=htons(8080); sockErr=bind(sListen, (SOCKADDR *) &service, sizeof(service)); if(SOCKET_ERROR==sockErr){ DebugBreak(); } sockErr=listen(sListen, SOMAXCONN); if(SOCKET_ERROR==sockErr){ DebugBreak(); } for(int i=0; i<numSockets; i++){ ntpAddAcceptSocket(sListen); } OutputDebugString(TEXT("CloseThreadpoolCleanupGroupMembers waiting\n")); SleepEx(INFINITE, TRUE); CloseThreadpoolCleanupGroupMembers(pCleanup, FALSE, NULL); OutputDebugString(TEXT("CloseThreadpoolCleanupGroupMembers done\n")); return false; }
UINT32 HlprThreadPoolDataPopulate(_Inout_ THREADPOOL_DATA* pThreadPoolData, _In_ const PTP_CLEANUP_GROUP_CANCEL_CALLBACK pGroupCancelFn) { ASSERT(pThreadPoolData); UINT32 status = NO_ERROR; InitializeThreadpoolEnvironment(&(pThreadPoolData->callbackEnvironment)); pThreadPoolData->pThreadPool = CreateThreadpool(0); if(pThreadPoolData->pThreadPool == 0) { status = GetLastError(); HlprLogError(L"HlprThreadPoolDataPopulate : CreateThreadPool() [status: %#x]", status); HLPR_BAIL; } pThreadPoolData->pCleanupGroup = CreateThreadpoolCleanupGroup(); if(pThreadPoolData->pCleanupGroup == 0) { status = GetLastError(); HlprLogError(L"HlprThreadPoolDataPopulate : CreateThreadPool() [status: %#x]", status); HLPR_BAIL; } SetThreadpoolCallbackPool(&(pThreadPoolData->callbackEnvironment), pThreadPoolData->pThreadPool); SetThreadpoolCallbackCleanupGroup(&(pThreadPoolData->callbackEnvironment), pThreadPoolData->pCleanupGroup, pGroupCancelFn); HLPR_BAIL_LABEL: if(status != NO_ERROR) HlprThreadPoolDataPurge(pThreadPoolData); return status; }
BOOL CTreadPool::Create( int nMaxThreads, int nMinThreads ) { m_pPool = CreateThreadpool(NULL); if (m_pPool==NULL) { OutputDebugString(TEXT("Create Thread Pool failed \n")); return FALSE; } m_nMinThreads = nMinThreads; m_nMaxThreads = nMaxThreads; SetThreadpoolThreadMaximum(m_pPool, nMaxThreads); SetThreadpoolThreadMinimum(m_pPool, nMinThreads); m_pTp_callback_environ = new TP_CALLBACK_ENVIRON; InitializeThreadpoolEnvironment(m_pTp_callback_environ); SetThreadpoolCallbackPool(m_pTp_callback_environ, m_pPool); return TRUE; }
__declspec(noinline) bool benchmark_ntp_fs_stat() { TP_CALLBACK_ENVIRON env; InitializeThreadpoolEnvironment(&env); PTP_POOL pool{nullptr}; pool = CreateThreadpool(nullptr); SetThreadpoolThreadMaximum(pool, 48); SetThreadpoolThreadMinimum(pool, 12); PTP_CLEANUP_GROUP group = CreateThreadpoolCleanupGroup(); SetThreadpoolCallbackPool(&env, pool); SetThreadpoolCallbackCleanupGroup(&env, group, nullptr); PTP_WORK work_fs_stat = CreateThreadpoolWork(WorkCallback_fs_stat, nullptr, &env); SubmitThreadpoolWork(work_fs_stat); WaitForThreadpoolWorkCallbacks(work_fs_stat, false); CloseThreadpoolWork(work_fs_stat); CloseThreadpool(pool); return false; }
HRESULT FxInterruptThreadpool::Initialize( ) { HRESULT hr = S_OK; DWORD error; BOOL bRet; // // Create a thread pool using win32 APIs // m_Pool = CreateThreadpool(NULL); if (m_Pool == NULL) { error = GetLastError(); hr = HRESULT_FROM_WIN32(error); DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, "Threadpool creation failed, %!winerr!", error); return hr; } // // Set maximum thread count to equal the total number of interrupts. // Set minimum thread count (persistent threads) to equal the lower of // number of interrupt and number of processors. // // We want minimum number of persistent threads to be at least equal to the // number of interrupt objects so that there is no delay in servicing the // interrupt if there are processors available (the delay can come due to // thread pool delay in allocating and initializing a new thread). However, // there is not much benefit in having more persistent threads than // processors, as threads would have to wait for processor to become // available anyways. Therefore, we chose to have the number of persistent // equal to the Min(number of interrupts, number of processors). // // In the current design, if there are more interrupts than // processors, as soon as one thread finishes servicing the interrupt, both // the thread and processor will be available to service the next queued // interrupt. Note that thread pool will queue all the waits and will // satisfy them in a FIFO manner. // // Since we don't know the number of interrupts in the beginning, we will // start with one and update it when we know the actual number of interrupts // after processing driver's OnPrepareHardware callback. // // Note on interrupt servicing: // When fx connects the interrupt, it queues an event-based wait block // to thread pool for each interrupt, so that the interrupt can get serviced // using one of the thread pool threads when the auto-reset event shared // with reflector is set by reflector in the DpcForIsr routine queued by Isr. // While the interrupt is being serviced by one of the threads, no wait block // is queued to thread pool for that interrupt, so arrival of same interrupt // signals the event in DpcForIsr but doesn't cause new threads to pick up // the servicing. Note that other interrupts still have their wait blocks // queued so they will be serviced as they arrive. // // When previous servicing is over (i.e. the ISR callback has been // invoked and it has returned), Fx queues another wait block to thread pool // for that interrupt. If the event is already signalled, it would result in // the same thread (or another) picking up servicing immediately. // // This means the interrupt ISR routine can never run concurrently // for same interrupt. Therefore, there is no need to have more than one // thread for each interrupt. // SetThreadpoolThreadMaximum(m_Pool, 1); // // Create one persistent thread since atleast one interrupt is the most // likely scenario. We will update this number to have either the same // number of threads as there are interrupts, or the number of // processors on the machine. // bRet = SetThreadpoolThreadMinimum(m_Pool, m_MinimumThreadCount); if (bRet == FALSE) { error = GetLastError(); hr = HRESULT_FROM_WIN32(error); DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, "%!FUNC!: Failed to set minimum threads (%d) in threadpool," " %!winerr!", m_MinimumThreadCount, error); goto cleanup; } // // Associate thread pool with callback environment. // SetThreadpoolCallbackPool(&m_CallbackEnvironment, m_Pool); cleanup: if (FAILED(hr)) { CloseThreadpool(m_Pool); m_Pool = NULL; } return hr; }
RFX_CONTEXT* rfx_context_new(void) { HKEY hKey; LONG status; DWORD dwType; DWORD dwSize; DWORD dwValue; SYSTEM_INFO sysinfo; RFX_CONTEXT* context; context = (RFX_CONTEXT*) malloc(sizeof(RFX_CONTEXT)); ZeroMemory(context, sizeof(RFX_CONTEXT)); context->priv = (RFX_CONTEXT_PRIV*) malloc(sizeof(RFX_CONTEXT_PRIV)); ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV)); context->priv->TilePool = Queue_New(TRUE, -1, -1); context->priv->TileQueue = Queue_New(TRUE, -1, -1); /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) * * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * 4 = 16384 (0x4000) * dwt_buffer: 32 * 32 * 2 * 2 * 4 = 16384, maximum sub-band width is 32 */ context->priv->BufferPool = BufferPool_New(TRUE, 16384, 16); #ifdef _WIN32 { BOOL isVistaOrLater; OSVERSIONINFOA verinfo; ZeroMemory(&verinfo, sizeof(OSVERSIONINFOA)); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; context->priv->UseThreads = isVistaOrLater; } #else context->priv->UseThreads = TRUE; #endif GetNativeSystemInfo(&sysinfo); context->priv->MinThreadCount = sysinfo.dwNumberOfProcessors; context->priv->MaxThreadCount = 0; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\RemoteFX"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) { if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->MaxThreadCount = dwValue; RegCloseKey(hKey); } if (context->priv->UseThreads) { /* Call primitives_get here in order to avoid race conditions when using primitives_get */ /* from multiple threads. This call will initialize all function pointers correctly */ /* before any decoding threads are started */ primitives_get(); context->priv->ThreadPool = CreateThreadpool(NULL); InitializeThreadpoolEnvironment(&context->priv->ThreadPoolEnv); SetThreadpoolCallbackPool(&context->priv->ThreadPoolEnv, context->priv->ThreadPool); if (context->priv->MinThreadCount) SetThreadpoolThreadMinimum(context->priv->ThreadPool, context->priv->MinThreadCount); if (context->priv->MaxThreadCount) SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount); } /* initialize the default pixel format */ rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_B8G8R8A8); /* create profilers for default decoding routines */ rfx_profiler_create(context); /* set up default routines */ context->quantization_decode = rfx_quantization_decode; context->quantization_encode = rfx_quantization_encode; context->dwt_2d_decode = rfx_dwt_2d_decode; context->dwt_2d_encode = rfx_dwt_2d_encode; RFX_INIT_SIMD(context); return context; }
int TestPoolWork(int argc, char* argv[]) { int index; PTP_POOL pool; PTP_WORK work; PTP_CLEANUP_GROUP cleanupGroup; TP_CALLBACK_ENVIRON environment; printf("Global Thread Pool\n"); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } /** * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete. * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads. */ for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolWork(work); printf("Private Thread Pool\n"); if (!(pool = CreateThreadpool(NULL))) { printf("CreateThreadpool failure\n"); return -1; } if (!SetThreadpoolThreadMinimum(pool, 4)) { printf("SetThreadpoolThreadMinimum failure\n"); return -1; } SetThreadpoolThreadMaximum(pool, 8); InitializeThreadpoolEnvironment(&environment); SetThreadpoolCallbackPool(&environment, pool); cleanupGroup = CreateThreadpoolCleanupGroup(); if (!cleanupGroup) { printf("CreateThreadpoolCleanupGroup failure\n"); return -1; } SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL); CloseThreadpoolCleanupGroup(cleanupGroup); DestroyThreadpoolEnvironment(&environment); /** * See Remarks at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx * If there is a cleanup group associated with the work object, * it is not necessary to call CloseThreadpoolWork ! * calling the CloseThreadpoolCleanupGroupMembers function releases the work, wait, * and timer objects associated with the cleanup group. */ /* CloseThreadpoolWork(work); // this would segfault, see comment above. */ CloseThreadpool(pool); return 0; }
void VSyncWin::VSyncInit() { Self = this; CoInitialize(NULL); HRESULT hr; //hr = CreateDXGIFactory2(__uuidof(IDXGIFactory1), (void**)(&pFactory)); //if (FAILED(hr)) //{ // exit(0); //} //UINT i = 0; ////IDXGIAdapter1*> vAdapters; //while (pFactory->EnumAdapters1(i, &m_pAdapter) != DXGI_ERROR_NOT_FOUND) //{ // //vAdapters.push_back(pAdapter); // //pAdapter->EnumOutputs() // ++i; // break; //we want the first adapter //} //if (m_pAdapter->EnumOutputs(0, &m_pOutput) == DXGI_ERROR_NOT_FOUND) //{ // //error // exit(0); //} RECT rc; GetClientRect(gHwnd, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; // for d2d support.. make it 0 not work UINT createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE(driverTypes); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; UINT numFeatureLevels = ARRAYSIZE(featureLevels); for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { mDriverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice(nullptr, mDriverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &m_pD3dDevice, &mFeatureLevel, &m_pImmediateContext); if (hr == E_INVALIDARG) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice(nullptr, mDriverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &m_pD3dDevice, &mFeatureLevel, &m_pImmediateContext); } if (SUCCEEDED(hr)) break; } if (FAILED(hr)) exit(0); const double rate = 1000 / 60.0; mSoftwareVsyncRate = FromMilliseconds(rate); mPrevVsync = Now(); /*hr = pFactory->CreateSwapChain(m_pD3dDevice, &scd, &m_pSwapChain); if ( FAILED(hr) ) exit(0); */ hr = m_pD3dDevice->QueryInterface(__uuidof(IDXGIDevice2), (void **)&m_pDXGIDevice); if (FAILED(hr)) { exit(0); } IDXGIAdapter * pDXGIAdapter; hr = m_pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter); if (FAILED(hr)) { exit(0); } pDXGIAdapter->GetParent(__uuidof(IDXGIFactory2), (void **)& pFactory); if (FAILED(hr)) { exit(0); } hr = pFactory->EnumAdapters1(0, &m_pAdapter); if (FAILED(hr)) exit(0); hr = m_pAdapter->EnumOutputs(0, &m_pOutput); if (FAILED(hr)) exit(0); DXGI_OUTPUT_DESC desc; hr = m_pOutput->GetDesc(&desc); if (FAILED(hr)) exit(0); RECT r; GetClientRect(gHwnd, &r); gHeight = r.bottom - r.top; gWidth = r.right - r.left; DXGI_SWAP_CHAIN_DESC1 scd = { 0 }; //scd.BufferDesc.Width = gWidth; //scd.BufferDesc.Height = gHeight; //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; //scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; //scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //scd.SampleDesc.Count = 1; //scd.SampleDesc.Quality = 0; //scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //scd.BufferCount = 3; //1 //scd.OutputWindow = gHwnd; //scd.Windowed = true; //scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;// DXGI_SWAP_EFFECT_SEQUENTIAL;//DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; //scd.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; scd.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT; // how the swap chain should be used scd.BufferCount = 3; // a front buffer and a back buffer scd.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // the most common swap chain format scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // the recommended flip mode scd.SampleDesc.Count = 1; scd.Scaling = DXGI_SCALING_NONE; scd.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE; scd.Width = gWidth; scd.Height = gHeight; hr = pFactory->CreateSwapChainForHwnd(m_pD3dDevice, gHwnd, &scd, NULL, NULL, &m_pSwapChain); if (FAILED(hr)) { exit(0); } hr = m_pSwapChain->GetBuffer(0, __uuidof(m_pBackBuffer), reinterpret_cast<void**>(&m_pBackBuffer)); if (FAILED(hr)) exit(0); hr = m_pD3dDevice->CreateRenderTargetView(m_pBackBuffer, NULL, &m_pRenderTarget ); if (FAILED(hr)) exit(0); m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTarget, NULL); DXGI_MODE_DESC requestedMode; requestedMode.Width = gWidth; requestedMode.Height = gHeight; requestedMode.RefreshRate.Numerator = 0; requestedMode.RefreshRate.Denominator = 0; requestedMode.Format = DXGI_FORMAT_B8G8R8A8_UNORM; requestedMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; requestedMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; DXGI_MODE_DESC mode; hr = m_pOutput->FindClosestMatchingMode(&requestedMode, &mode, m_pD3dDevice); if (FAILED(hr)) throw - 1; hr = m_pSwapChain->ResizeTarget(&mode); if (FAILED(hr)) throw -1; mode.RefreshRate.Numerator = 0; mode.RefreshRate.Denominator = 0; hr = m_pSwapChain->ResizeTarget(&mode); if (FAILED(hr)) throw - 1; D2D1_FACTORY_OPTIONS options; ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS)); hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&m_pD2D1Factory); if (FAILED(hr)) { exit(0); } hr = m_pD2D1Factory->CreateDevice(m_pDXGIDevice, &m_pD2D1Device); if (FAILED(hr)) { exit(0); } hr = m_pD2D1Device->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_pD2DContext ); if (FAILED(hr)) { exit(0); } // Direct2D needs the dxgi version of the backbuffer surface pointer. hr = m_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&m_pDxgiBackBuffer)); if (FAILED(hr)) exit(0); auto d2dRTProps = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), 96.0, 96.0); /*D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 96.0, 96.0 );*/ // Get a D2D surface from the DXGI back buffer to use as the D2D render target. /*hr = m_pD2DContext->CreateBitmapFromDxgiSurface( m_pDxgiBackBuffer, d2dRTProps, &m_pD2DTargetBitmap ); if (FAILED(hr)) exit(0);*/ hr = m_pD2D1Factory->CreateDxgiSurfaceRenderTarget(m_pDxgiBackBuffer, &d2dRTProps, &m_pD2DRenderTarget); if (FAILED(hr)) exit(0); //m_pD2DContext->SetTarget(m_pD2DTargetBitmap); //m_pDXGIDevice->SetMaximumFrameLatency(3); #if 0//VSYNC //Creating a thread std::thread vsync([this] { this->VSyncLoop(); }); vsync.detach(); #endif #if 0//USING_DWM_FLUSH std::thread VSyncBlit([this] { this->BlittingThread(); }); VSyncBlit.detach(); #endif HDC hdc = GetDC(gHwnd); mDCBitmap1 = CreateCompatibleDC(hdc); mDCBitmap2 = CreateCompatibleDC(hdc); mDCBitmap3 = CreateCompatibleDC(hdc); //HDC hdc = GetDC(hWnd); RECT rect; GetWindowRect(gHwnd, &rect); gWidth = rect.right - rect.left; gHeight = rect.bottom - rect.top; mBitmap1 = CreateCompatibleBitmap(hdc, gWidth, gHeight); mBitmap2 = CreateCompatibleBitmap(hdc, gWidth, gHeight); mBitmap3 = CreateCompatibleBitmap(hdc, gWidth, gHeight); SelectObject(mDCBitmap1, mBitmap1); SelectObject(mDCBitmap2, mBitmap2); SelectObject(mDCBitmap3, mBitmap3); DeleteDC(hdc); InitializeThreadpoolEnvironment(&mCallBackEnviron); mPool = CreateThreadpool(NULL); if (NULL == mPool) { OutputDebugStringA("CreateThreadpool failed. LastError: %u\n"); exit(0); } //SetThreadpoolThreadMaximum(mPool, 1); //SetThreadpoolCallbackPool(&mCallBackEnviron, mPool); }
RFX_CONTEXT* rfx_context_new(BOOL encoder) { HKEY hKey; LONG status; DWORD dwType; DWORD dwSize; DWORD dwValue; SYSTEM_INFO sysinfo; RFX_CONTEXT* context; wObject *pool; RFX_CONTEXT_PRIV *priv; context = (RFX_CONTEXT*)calloc(1, sizeof(RFX_CONTEXT)); if (!context) return NULL; context->encoder = encoder; context->priv = priv = (RFX_CONTEXT_PRIV *)calloc(1, sizeof(RFX_CONTEXT_PRIV) ); if (!priv) goto error_priv; WLog_Init(); priv->log = WLog_Get("com.freerdp.codec.rfx"); WLog_OpenAppender(priv->log); #ifdef WITH_DEBUG_RFX WLog_SetLogLevel(priv->log, WLOG_DEBUG); #endif priv->TilePool = ObjectPool_New(TRUE); if (!priv->TilePool) goto error_tilePool; pool = ObjectPool_Object(priv->TilePool); pool->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init; if (context->encoder) { pool->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new; pool->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free; } else { pool->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new; pool->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free; } /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) * * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * sizeof(INT16) = 8192 (0x2000) * dwt_buffer: 32 * 32 * 2 * 2 * sizeof(INT16) = 8192, maximum sub-band width is 32 * * Additionally we add 32 bytes (16 in front and 16 at the back of the buffer) * in order to allow optimized functions (SEE, NEON) to read from positions * that are actually in front/beyond the buffer. Offset calculations are * performed at the BufferPool_Take function calls in rfx_encode/decode.c. * * We then multiply by 3 to use a single, partioned buffer for all 3 channels. */ priv->BufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); if (!priv->BufferPool) goto error_BufferPool; #ifdef _WIN32 { BOOL isVistaOrLater; OSVERSIONINFOA verinfo; ZeroMemory(&verinfo, sizeof(OSVERSIONINFOA)); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; priv->UseThreads = isVistaOrLater; } #else priv->UseThreads = TRUE; #endif GetNativeSystemInfo(&sysinfo); priv->MinThreadCount = sysinfo.dwNumberOfProcessors; priv->MaxThreadCount = 0; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\RemoteFX"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) { dwSize = sizeof(dwValue); if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->MaxThreadCount = dwValue; RegCloseKey(hKey); } if (priv->UseThreads) { /* Call primitives_get here in order to avoid race conditions when using primitives_get */ /* from multiple threads. This call will initialize all function pointers correctly */ /* before any decoding threads are started */ primitives_get(); priv->ThreadPool = CreateThreadpool(NULL); if (!priv->ThreadPool) goto error_threadPool; InitializeThreadpoolEnvironment(&priv->ThreadPoolEnv); SetThreadpoolCallbackPool(&priv->ThreadPoolEnv, priv->ThreadPool); if (priv->MinThreadCount) if (!SetThreadpoolThreadMinimum(priv->ThreadPool, priv->MinThreadCount)) goto error_threadPool_minimum; if (priv->MaxThreadCount) SetThreadpoolThreadMaximum(priv->ThreadPool, priv->MaxThreadCount); } /* initialize the default pixel format */ rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_B8G8R8A8); /* create profilers for default decoding routines */ rfx_profiler_create(context); /* set up default routines */ context->quantization_decode = rfx_quantization_decode; context->quantization_encode = rfx_quantization_encode; context->dwt_2d_decode = rfx_dwt_2d_decode; context->dwt_2d_encode = rfx_dwt_2d_encode; RFX_INIT_SIMD(context); context->state = RFX_STATE_SEND_HEADERS; return context; error_threadPool_minimum: CloseThreadpool(priv->ThreadPool); error_threadPool: BufferPool_Free(priv->BufferPool); error_BufferPool: ObjectPool_Free(priv->TilePool); error_tilePool: free(priv); error_priv: free(context); return NULL; }
int TestPoolWork(int argc, char* argv[]) { int index; PTP_POOL pool; PTP_WORK work; PTP_CLEANUP_GROUP cleanupGroup; TP_CALLBACK_ENVIRON environment; printf("Global Thread Pool\n"); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } /** * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete. * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads. */ for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolWork(work); printf("Private Thread Pool\n"); pool = CreateThreadpool(NULL); SetThreadpoolThreadMinimum(pool, 4); SetThreadpoolThreadMaximum(pool, 8); InitializeThreadpoolEnvironment(&environment); SetThreadpoolCallbackPool(&environment, pool); cleanupGroup = CreateThreadpoolCleanupGroup(); if (!cleanupGroup) { printf("CreateThreadpoolCleanupGroup failure\n"); return -1; } SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL); CloseThreadpoolCleanupGroup(cleanupGroup); DestroyThreadpoolEnvironment(&environment); CloseThreadpoolWork(work); CloseThreadpool(pool); return 0; }
// // This function is invoked only with Airplane mode change, but not with NFC radio state change. // STDMETHODIMP CNfcRadioManager::OnSystemRadioStateChange( _In_opt_ SYSTEM_RADIO_STATE sysRadioState, _In_ UINT32 uTimeoutSec) { UNREFERENCED_PARAMETER(sysRadioState); UNREFERENCED_PARAMETER(uTimeoutSec); TRACE_METHOD_ENTRY(LEVEL_VERBOSE); HRESULT hr = S_OK; PTP_POOL threadPool = NULL; TP_CALLBACK_ENVIRON callbackEnviron; PTP_CLEANUP_GROUP ptpCleanupGroup = NULL; // Create threadpool to handle all of the radios threadPool = CreateThreadpool(NULL); if (NULL == threadPool) { hr = HRESULT_FROM_WIN32(GetLastError()); } if (SUCCEEDED(hr)) { SetThreadpoolThreadMaximum(threadPool, 50); InitializeThreadpoolEnvironment(&callbackEnviron); SetThreadpoolCallbackPool(&callbackEnviron, threadPool); ptpCleanupGroup = CreateThreadpoolCleanupGroup(); if (NULL == ptpCleanupGroup) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { // Associate the cleanup group with our thread pool SetThreadpoolCallbackCleanupGroup(&callbackEnviron, ptpCleanupGroup, NULL ); } } // Lock so that any adds or removes will not cause list changes during system airplane mode EnterCriticalSection(&m_csAddRemoveLock); if (SUCCEEDED(hr)) { UINT32 i, count = 0; SYSTEM_STATE_SWITCH_CONTEXT* pContext = NULL; hr = m_nfcRadioCollection->GetCount(&count); if (count > 0) { if (SUCCEEDED(hr)) { pContext = (SYSTEM_STATE_SWITCH_CONTEXT*)malloc(count * sizeof(SYSTEM_STATE_SWITCH_CONTEXT)); if (NULL == pContext) { hr = E_OUTOFMEMORY; } } for (i = 0; (SUCCEEDED(hr) && (i < count)); i++) { PTP_WORK ptpThreadWork = NULL; pContext[i].sysRadioState = sysRadioState; m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&(pContext[i].pRadioInstance)); ptpThreadWork = CreateThreadpoolWork( (PTP_WORK_CALLBACK)&CNfcRadioManager::AsyncRadioChange, &(pContext[i]), &(callbackEnviron) ); if (ptpThreadWork == NULL) { // pRadioInstance context was not successfully added to threadpool. hr = pContext[i].pRadioInstance->SetSystemState(sysRadioState); pContext[i].pRadioInstance->Release(); } else { ::SubmitThreadpoolWork(ptpThreadWork); } } } // Wait for all threadpools to drain and clean up threads CloseThreadpoolCleanupGroupMembers(ptpCleanupGroup, FALSE, NULL); if (NULL != pContext) { free(pContext); } } else { // Failed to set up threadpool for parallel system radio change. Only choice is to do it serially now UINT32 i, count = 0; CNfcRadioInstance* pRadioInstance = NULL; hr = m_nfcRadioCollection->GetCount(&count); for (i = 0; (SUCCEEDED(hr) && (i < count)); i++) { hr = m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&pRadioInstance); if (SUCCEEDED(hr)) { hr = pRadioInstance->SetSystemState(sysRadioState); } pRadioInstance->Release(); } } LeaveCriticalSection(&m_csAddRemoveLock); DestroyThreadpoolEnvironment(&callbackEnviron); if(ptpCleanupGroup) { CloseThreadpoolCleanupGroup(ptpCleanupGroup); ptpCleanupGroup = NULL; } if(threadPool) { CloseThreadpool(threadPool); threadPool = NULL; } TRACE_METHOD_EXIT_HR(LEVEL_COND, hr); return hr; }
int _tmain1(int argc, _TCHAR* argv[]) { if (depth == 0) { Display("%d(%d)************\n", GetCurrentProcessId(), GetCurrentThreadId()); return 1; } int multiply = 1; if (argc > 2) { multiply = _ttoi(argv[2]); if (multiply < 1) { Display("multiply should be greater than 1\n"); return -2; } } TP_CALLBACK_ENVIRON CallBackEnviron; InitializeThreadpoolEnvironment(&CallBackEnviron); PTP_POOL pool = CreateThreadpool(NULL); if (NULL == pool) { _tprintf(_T("CreateThreadpool failed. LastError: %u\n"), GetLastError()); } SetThreadpoolThreadMaximum(pool, 100); BOOL bRet = SetThreadpoolThreadMinimum(pool, 20); if (!bRet) { _tprintf(_T("SetThreadpoolThreadMinimum failed. LastError: %u\n"), GetLastError()); } PTP_CLEANUP_GROUP cleanupgroup = CreateThreadpoolCleanupGroup(); if (NULL == cleanupgroup) { _tprintf(_T("CreateThreadpoolCleanupGroup failed. LastError: %u\n"), GetLastError()); } SetThreadpoolCallbackPool(&CallBackEnviron, pool); SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL); struct ProcSetup { PROCESS_INFORMATION pi; HANDLE hEvent; HANDLE hWait; HANDLE hOutputRead; HANDLE hErrorRead; HANDLE hInputWrite; int rc; ProcSetup(PROCESS_INFORMATION _pi, HANDLE _hEvent, HANDLE _hWait, HANDLE _hOutputRead, HANDLE _hErrorRead, HANDLE _hInputWrite) : pi(_pi), hEvent(_hEvent), hWait(_hWait), hOutputRead(_hOutputRead), hErrorRead(_hErrorRead), hInputWrite(_hInputWrite) {} }; ProcSetup* pss = (ProcSetup*)calloc(multiply, sizeof(ProcSetup)); for (int i = 0; i < multiply; i++) { Display("%d(%d) Multiply %d out of %d\n", GetCurrentProcessId(), GetCurrentThreadId(), i, multiply); HANDLE hOutputRead, hOutputWrite; HANDLE hErrorRead, hErrorWrite; HANDLE hInputRead, hInputWrite; SECURITY_ATTRIBUTES sa; // Set up the security attributes struct. sa.nLength= sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; STARTUPINFO startup_info; ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION process_info; ZeroMemory(&process_info, sizeof(process_info)); TCHAR cmd[1024]; _stprintf(cmd, _T("%s %d"), argv[0], depth-1); BOOL result = CreateProcess(NULL, // ApplicationName cmd, NULL, // ProcessAttributes NULL, // ThreadAttributes TRUE, // InheritHandles CREATE_SUSPENDED, // | CREATE_BREAKAWAY_FROM_JOB, // CreationFlags NULL, NULL, &startup_info, &process_info); pss[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); pss[i].pi = process_info; PTP_WAIT myWait = CreateThreadpoolWait(callback, new WaiterParams(process_info, pss[i].hEvent, &pss[i].rc), &CallBackEnviron); SetThreadpoolWait(myWait, process_info.hProcess, NULL); ResumeThread(process_info.hThread); } HANDLE* events = (HANDLE*)calloc(multiply, sizeof(HANDLE)); for (int i = 0; i < multiply; i++) { events[i] = pss[i].hEvent; } WaitForMultipleObjects(multiply, events, true, INFINITE); int exit_code; for (int i = 0; i < multiply; i++) { PROCESS_INFORMATION* process_info = &pss[i].pi; int texit_code; BOOL ok = GetExitCodeThread(process_info->hThread, reinterpret_cast<DWORD*>(&texit_code)); if (!ok) { printf("*** GetExitCodeThread failed %d\n", GetLastError()); } ok = GetExitCodeProcess(process_info->hProcess, reinterpret_cast<DWORD*>(&exit_code)); if (!ok) { printf("*** GetExitCodeProcess failed %d\n", GetLastError()); } if (texit_code != exit_code) { printf("*** Thread %d exit code %x didn't match process %d exit code %x\n", process_info->dwThreadId, texit_code, process_info->dwProcessId, exit_code); } CloseHandle(process_info->hProcess); CloseHandle(process_info->hThread); // *wp->pRC = exit_code; // exit_code = pss[i].rc; if (exit_code != 1) { printf("Failed to get correct exit code. Got %d instead\n", exit_code); } } for (int i = 0; i < multiply; i++) { CloseHandle(pss[i].hEvent); } free(events); CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL); CloseThreadpoolCleanupGroup(cleanupgroup); CloseThreadpool(pool); DestroyThreadpoolEnvironment(&CallBackEnviron); return exit_code; }