condition_variable::condition_variable() : m_num_waiters(0) { #if _WIN32_WINNT == 0x0501 m_sem = CreateSemaphore(0, 0, INT_MAX, 0); #else m_sem = CreateSemaphoreEx(0, 0, INT_MAX, 0, 0, SEMAPHORE_ALL_ACCESS); #endif }
tsk_semaphore_handle_t* tsk_semaphore_create_2(int initial_val) { SEMAPHORE_T handle = tsk_null; #if TSK_UNDER_WINDOWS # if TSK_UNDER_WINDOWS_RT handle = CreateSemaphoreEx(NULL, initial_val, 0x7FFFFFFF, NULL, 0x00000000, SEMAPHORE_ALL_ACCESS); # else handle = CreateSemaphore(NULL, initial_val, 0x7FFFFFFF, NULL); # endif #else handle = tsk_calloc(1, sizeof(SEMAPHORE_S)); #if TSK_USE_NAMED_SEM named_sem_t * nsem = (named_sem_t*)handle; snprintf(nsem->name, (sizeof(nsem->name)/sizeof(nsem->name[0])) - 1, "/sem/%llu/%d.", tsk_time_epoch(), rand() ^ rand()); if ((nsem->sem = sem_open(nsem->name, O_CREAT /*| O_EXCL*/, S_IRUSR | S_IWUSR, initial_val)) == SEM_FAILED) { #else if (sem_init((SEMAPHORE_T)handle, 0, initial_val)) { #endif TSK_FREE(handle); TSK_DEBUG_ERROR("Failed to initialize the new semaphore (errno=%d).", errno); } #endif if (!handle) { TSK_DEBUG_ERROR("Failed to create new semaphore"); } return handle; } /**@ingroup tsk_semaphore_group * Increments a semaphore. * @param handle The semaphore to increment. * @retval Zero if succeed and otherwise the function returns -1 and sets errno to indicate the error. * @sa @ref tsk_semaphore_decrement. */ int tsk_semaphore_increment(tsk_semaphore_handle_t* handle) { int ret = EINVAL; if (handle) { #if TSK_UNDER_WINDOWS if((ret = ReleaseSemaphore((SEMAPHORE_T)handle, 1L, NULL) ? 0 : -1)) #else if((ret = sem_post((SEMAPHORE_T)GET_SEM(handle)))) #endif { TSK_DEBUG_ERROR("sem_post function failed: %d", ret); } } return ret; }
//---------------------------------------------------------------------------------------- amf_handle AMF_CDECL_CALL amf_create_semaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName) { if(iMaxCount == 0) { return NULL; } #if defined(METRO_APP) return CreateSemaphoreEx(NULL, iInitCount, iMaxCount, pName, 0, STANDARD_RIGHTS_ALL | SEMAPHORE_MODIFY_STATE); #else return CreateSemaphoreW(NULL, iInitCount, iMaxCount, pName); #endif }
void pthread_cond_init(pthread_cond_t *cv, const void * attr) { cv->waiters_count_ = 0; cv->was_broadcast_ = 0; cv->sema_ = CreateSemaphoreEx(NULL, // no security 0, // initially 0 0x7fffffff, // max count NULL, // unnamed 0, EVENT_ALL_ACCESS); InitializeCriticalSectionEx(&cv->waiters_count_lock_, 10, 0); cv->waiters_done_ = CreateEventEx(NULL, // no security NULL, // unnamed 0, // auto-reset, unsignalled EVENT_ALL_ACCESS); }
SemaphoreWindows::SemaphoreWindows() { #ifdef WINRT_ENABLED semaphore=CreateSemaphoreEx( NULL, 0, 0xFFFFFFF, //wathever NULL, 0, SEMAPHORE_ALL_ACCESS); #else semaphore=CreateSemaphore( NULL, 0, 0xFFFFFFF, //wathever NULL); #endif }
HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) { // don't allow making handles on empty keys if (key.isEmpty()) return 0; // Create it if it doesn't already exists. if (semaphore == 0) { #if defined(Q_OS_WINRT) semaphore = CreateSemaphoreEx(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16(), 0, SEMAPHORE_ALL_ACCESS); #else semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16()); #endif if (semaphore == NULL) setErrorString(QLatin1String("QSystemSemaphore::handle")); } return semaphore; }
static int XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) { HRESULT result = S_OK; WAVEFORMATEX waveformat; int valid_format = 0; SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format); IXAudio2 *ixa2 = NULL; IXAudio2SourceVoice *source = NULL; UINT32 devId = 0; /* 0 == system default device. */ if (iscapture) { return SDL_SetError("XAudio2: capture devices unsupported."); } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { return SDL_SetError("XAudio2: XAudio2Create() failed at open."); } if (devname != NULL) { UINT32 devcount = 0; UINT32 i = 0; if (i == devcount) { ixa2->Release(); return SDL_SetError("XAudio2: Requested device not found."); } } /* Initialize all variables that we clean on shutdown */ _this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *_this->hidden)); if (_this->hidden == NULL) { return SDL_OutOfMemory(); } SDL_memset(_this->hidden, 0, (sizeof *_this->hidden)); _this->hidden->ixa2 = ixa2; _this->hidden->semaphore = CreateSemaphoreEx(NULL, 1, 2, NULL, 0, 0); if (_this->hidden->semaphore == NULL) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: CreateSemaphore() failed!"); } while ((!valid_format) && (test_format)) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: case AUDIO_F32: _this->spec.format = test_format; valid_format = 1; break; } test_format = SDL_NextAudioFormat(); } if (!valid_format) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: Unsupported audio format"); } /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&_this->spec); /* We feed a Source, it feeds the Mastering, which feeds the device. */ _this->hidden->mixlen = _this->spec.size; _this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * _this->hidden->mixlen); if (_this->hidden->mixbuf == NULL) { XAUDIO2_CloseDevice(_this); return SDL_OutOfMemory(); } _this->hidden->nextbuf = _this->hidden->mixbuf; SDL_memset(_this->hidden->mixbuf, 0, 2 * _this->hidden->mixlen); /* We use XAUDIO2_DEFAULT_CHANNELS instead of _this->spec.channels. On Xbox360, _this means 5.1 output, but on Windows, it means "figure out what the system has." It might be preferable to let XAudio2 blast stereo output to appropriate surround sound configurations instead of clamping to 2 channels, even though we'll configure the Source Voice for whatever number of channels you supply. */ result = ixa2->CreateMasteringVoice(&_this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, _this->spec.freq, 0, nullptr, nullptr, AudioCategory_GameMedia); // XAUDIO2_DEFAULT_CHANNELS, // _this->spec.freq, 0, devId, NULL); if (result != S_OK) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: Couldn't create mastering voice"); } SDL_zero(waveformat); if (SDL_AUDIO_ISFLOAT(_this->spec.format)) { waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } else { waveformat.wFormatTag = WAVE_FORMAT_PCM; } waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(_this->spec.format); waveformat.nChannels = _this->spec.channels; waveformat.nSamplesPerSec = _this->spec.freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; static VoiceCallback callbacks; XAUDIO2_SEND_DESCRIPTOR descriptors[1]; descriptors[0].pOutputVoice = _this->hidden->mastering; descriptors[0].Flags = 0; XAUDIO2_VOICE_SENDS sends = {0}; sends.SendCount = 1; sends.pSends = descriptors; result = ixa2->CreateSourceVoice(&source, &waveformat, 0, 1.0f, &callbacks, &sends, nullptr); if (result != S_OK) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: Couldn't create source voice"); } _this->hidden->source = source; /* Start everything playing! */ result = ixa2->StartEngine(); if (result != S_OK) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: Couldn't start engine"); } result = source->Start(0, XAUDIO2_COMMIT_NOW); if (result != S_OK) { XAUDIO2_CloseDevice(_this); return SDL_SetError("XAudio2: Couldn't start source voice"); } return 0; /* good to go. */ }
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Allocate program memory g_program_memory.start = malloc(MAX_INTERNAL_MEMORY_SIZE); g_program_memory.free_memory = g_program_memory.start; // TODO: add checks for overflow when allocating // Main program state Program_State *state = (Program_State *)g_program_memory.allocate(sizeof(Program_State)); state->init(&g_program_memory, &g_pixel_buffer, (Raytrace_Work_Queue *)&g_raytrace_queue); // Create window class WNDCLASS WindowClass = {}; WindowClass.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; WindowClass.lpfnWndProc = Win32WindowProc; WindowClass.hInstance = hInstance; WindowClass.lpszClassName = "VMWindowClass"; // Set target sleep resolution { TIMECAPS tc; UINT wTimerRes; if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { OutputDebugStringA("Cannot set the sleep resolution\n"); exit(1); } wTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); // 1 ms timeBeginPeriod(wTimerRes); } QueryPerformanceFrequency(&gPerformanceFrequency); if (!RegisterClass(&WindowClass)) { // TODO: logging printf("Couldn't register window class\n"); exit(1); } // Create window so that its client area is exactly kWindowWidth/Height DWORD WindowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; RECT WindowRect = {}; WindowRect.right = state->kWindowWidth; WindowRect.bottom = state->kWindowHeight; AdjustWindowRect(&WindowRect, WindowStyle, 0); int WindowWidth = WindowRect.right - WindowRect.left; int WindowHeight = WindowRect.bottom - WindowRect.top; HWND Window = CreateWindow(WindowClass.lpszClassName, 0, WindowStyle, CW_USEDEFAULT, CW_USEDEFAULT, WindowWidth, WindowHeight, 0, 0, hInstance, 0); if (!Window) { printf("Couldn't create window\n"); exit(1); } // We're not going to release it as we use CS_OWNDC HDC hdc = GetDC(Window); g_running = true; // Set proper buffer values based on actual client size Win32ResizeClientWindow(Window); // Init OpenGL { PIXELFORMATDESCRIPTOR DesiredPixelFormat = {}; DesiredPixelFormat.nSize = sizeof(DesiredPixelFormat); DesiredPixelFormat.nVersion = 1; DesiredPixelFormat.iPixelType = PFD_TYPE_RGBA; DesiredPixelFormat.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; DesiredPixelFormat.cColorBits = 32; DesiredPixelFormat.cAlphaBits = 8; DesiredPixelFormat.iLayerType = PFD_MAIN_PLANE; int SuggestedPixelFormatIndex = ChoosePixelFormat(hdc, &DesiredPixelFormat); PIXELFORMATDESCRIPTOR SuggestedPixelFormat; DescribePixelFormat(hdc, SuggestedPixelFormatIndex, sizeof(SuggestedPixelFormat), &SuggestedPixelFormat); SetPixelFormat(hdc, SuggestedPixelFormatIndex, &SuggestedPixelFormat); HGLRC OpenGLRC = wglCreateContext(hdc); if (wglMakeCurrent(hdc, OpenGLRC)) { // Success glGenTextures(1, &gTextureHandle); typedef BOOL WINAPI wgl_swap_interval_ext(int interval); wgl_swap_interval_ext *wglSwapInterval = (wgl_swap_interval_ext *)wglGetProcAddress("wglSwapIntervalEXT"); if (wglSwapInterval) { wglSwapInterval(1); } else { // VSync not enabled or not supported assert(false); } } else { // Something's wrong assert(false); } } Cursor_Type current_cursor = Cursor_Type_Arrow; HCURSOR win_cursors[Cursor_Type__COUNT]; win_cursors[Cursor_Type_Arrow] = LoadCursor(NULL, IDC_ARROW); win_cursors[Cursor_Type_Cross] = LoadCursor(NULL, IDC_CROSS); win_cursors[Cursor_Type_Hand] = LoadCursor(NULL, IDC_HAND); win_cursors[Cursor_Type_Resize_Vert] = LoadCursor(NULL, IDC_SIZENS); win_cursors[Cursor_Type_Resize_Horiz] = LoadCursor(NULL, IDC_SIZEWE); User_Input inputs[2]; User_Input *old_input = &inputs[0]; User_Input *new_input = &inputs[1]; *new_input = {}; LARGE_INTEGER last_timestamp = Win32GetWallClock(); // Create worker threads { const int kNumThreads = 4; // Init work queue g_raytrace_queue.next_entry_to_add = 0; g_raytrace_queue.next_entry_to_do = 0; u32 initial_num_threads = 0; g_raytrace_queue.semaphore = CreateSemaphoreEx( 0, initial_num_threads, kNumThreads, 0, 0, SEMAPHORE_ALL_ACCESS); Thread_Info threads[kNumThreads]; for (int i = 0; i < kNumThreads; i++) { threads[i].thread_num = i + 1; HANDLE thread_handle = CreateThread( 0, // LPSECURITY_ATTRIBUTES lpThreadAttributes, 0, // SIZE_T dwStackSize, RaytraceWorkerThread, // LPTHREAD_START_ROUTINE lpStartAddress, &threads[i], // LPVOID lpParameter, 0, // DWORD dwCreationFlags, NULL // LPDWORD lpThreadId ); threads[i].thread_handle = thread_handle; if (thread_handle == NULL) { printf("CreateThread error: %d\n", GetLastError()); exit(1); } } } // Event loop while (g_running) { // Process messages MSG message; while (PeekMessage(&message, 0, 0, 0, PM_REMOVE)) { // Get keyboard messages switch (message.message) { case WM_QUIT: { g_running = false; } break; case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: { u32 vk_code = (u32)message.wParam; bool was_down = ((message.lParam & (1 << 30)) != 0); bool is_down = ((message.lParam & (1 << 31)) == 0); bool alt_key_was_down = (message.lParam & (1 << 29)) != 0; if ((vk_code == VK_F4) && alt_key_was_down) { g_running = false; } if (was_down == is_down) { break; // nothing has changed } if (vk_code == VK_ESCAPE) { new_input->buttons[IB_escape] = is_down; } if (vk_code == VK_UP) { new_input->buttons[IB_up] = is_down; } if (vk_code == VK_DOWN) { new_input->buttons[IB_down] = is_down; } if (vk_code == VK_LEFT) { new_input->buttons[IB_left] = is_down; } if (vk_code == VK_RIGHT) { new_input->buttons[IB_right] = is_down; } if (vk_code == VK_SHIFT) { new_input->buttons[IB_shift] = is_down; } // Handle symbols int symbol = (int)vk_code; if (vk_code == VK_NUMPAD0) symbol = '0'; else if (vk_code == VK_NUMPAD1) symbol = '1'; else if (vk_code == VK_NUMPAD2) symbol = '2'; else if (vk_code == VK_NUMPAD3) symbol = '3'; else if (vk_code == VK_NUMPAD4) symbol = '4'; else if (vk_code == VK_NUMPAD5) symbol = '5'; else if (vk_code == VK_NUMPAD6) symbol = '6'; else if (vk_code == VK_NUMPAD7) symbol = '7'; else if (vk_code == VK_NUMPAD8) symbol = '8'; else if (vk_code == VK_NUMPAD9) symbol = '9'; if (('A' <= symbol && symbol <= 'Z') || ('0' <= symbol && symbol <= '9')) { new_input->buttons[IB_key] = is_down; new_input->symbol = symbol; } } break; case WM_MOUSEWHEEL: { int delta = (int)message.wParam / (65536 * WHEEL_DELTA); new_input->scroll += delta; } break; default: { TranslateMessage(&message); DispatchMessageA(&message); } break; } } // Get mouse input { POINT mouse_pointer; GetCursorPos(&mouse_pointer); ScreenToClient(Window, &mouse_pointer); new_input->mouse = {mouse_pointer.x, mouse_pointer.y}; new_input->buttons[IB_mouse_left] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0; new_input->buttons[IB_mouse_right] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0; new_input->buttons[IB_mouse_middle] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0; } Update_Result result = update_and_render(&g_program_memory, state, new_input); #include "debug/ED_debug_draw.cpp" assert(0 <= result.cursor && result.cursor < Cursor_Type__COUNT); SetCursor(win_cursors[result.cursor]); Win32UpdateWindow(hdc); // Swap inputs User_Input *tmp = old_input; old_input = new_input; new_input = tmp; // Zero input *new_input = {}; new_input->old = old_input; // Save so we can refer to it later // Retain the button state for (size_t i = 0; i < COUNT_OF(new_input->buttons); i++) { new_input->buttons[i] = old_input->buttons[i]; } for (size_t i = 0; i < COUNT_OF(new_input->mouse_positions); i++) { new_input->mouse_positions[i] = old_input->mouse_positions[i]; } new_input->symbol = old_input->symbol; r32 ms_elapsed = Win32GetMillisecondsElapsed(last_timestamp, Win32GetWallClock()); g_FPS.value = (int)(1000.0f / ms_elapsed); last_timestamp = Win32GetWallClock(); } return 0; }
hl_semaphore_handle_t* hl_semaphore_create_2(int initial_val) { SEMAPHORE_T handle = hl_null; #if HL_UNDER_WINDOWS # if HL_UNDER_WINDOWS_RT handle = CreateSemaphoreEx(NULL, initial_val, 0x7FFFFFFF, NULL, 0x00000000, SEMAPHORE_ALL_ACCESS); # else handle = CreateSemaphore(NULL, initial_val, 0x7FFFFFFF, NULL); # endif #else handle = hl_memory_calloc(1, sizeof(SEMAPHORE_S)); #if HL_USE_NAMED_SEM named_sem_t * nsem = (named_sem_t*)handle; hl_sprintf(&(nsem->name), "/sem-%d", sem_count++); if ((nsem->sem = sem_open(nsem->name, O_CREAT /*| O_EXCL*/, S_IRUSR | S_IWUSR, initial_val)) == SEM_FAILED) { HL_MEMORY_FREE(nsem->name); #else if (sem_init((SEMAPHORE_T)handle, 0, initial_val)) { #endif HL_MEMORY_FREE(handle); HL_DEBUG_ERROR("Failed to initialize the new semaphore (errno=%d).", errno); } #endif if (!handle) { HL_DEBUG_ERROR("Failed to create new semaphore"); } return handle; } int hl_semaphore_increment(hl_semaphore_handle_t* handle) { int ret = EINVAL; if (handle) { #if HL_UNDER_WINDOWS if ((ret = ReleaseSemaphore((SEMAPHORE_T)handle, 1L, NULL) ? 0 : -1)) { #else if ((ret = sem_post((SEMAPHORE_T)GET_SEM(handle)))) { #endif HL_DEBUG_ERROR("sem_post function failed: %d", ret); } } return ret; } int hl_semaphore_decrement(hl_semaphore_handle_t* handle) { int ret = EINVAL; if (handle) { #if HL_UNDER_WINDOWS # if HL_UNDER_WINDOWS_RT ret = (WaitForSingleObjectEx((SEMAPHORE_T)handle, INFINITE, TRUE) == WAIT_OBJECT_0) ? 0 : -1; # else ret = (WaitForSingleObject((SEMAPHORE_T)handle, INFINITE) == WAIT_OBJECT_0) ? 0 : -1; #endif if(ret) { HL_DEBUG_ERROR("sem_wait function failed: %d", ret); } #else do { ret = sem_wait((SEMAPHORE_T)GET_SEM(handle)); } while ( errno == EINTR ); if (ret) { HL_DEBUG_ERROR("sem_wait function failed: %d", errno); } #endif } return ret; }