blob: ce5ef3e2ebd7ce2e52ededc41cae28c9e4c9011e [file] [log] [blame]
scroggo@google.com4177ef42012-10-31 15:52:16 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkCondVar.h"
9
mtkleindb8d0e52014-11-03 17:25:54 -080010#if defined(SK_BUILD_FOR_WIN32)
11 static void (WINAPI *initialize_condition_variable)(PCONDITION_VARIABLE);
12 static BOOL (WINAPI *sleep_condition_variable)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
13 static void (WINAPI *wake_condition_variable)(PCONDITION_VARIABLE);
14 static void (WINAPI *wake_all_condition_variable)(PCONDITION_VARIABLE);
15
16 template <typename T>
17 static void set_fn_ptr(T* ptr, FARPROC fn) { *ptr = reinterpret_cast<T>(fn); }
18#endif
19
20bool SkCondVar::Supported() {
21#ifdef SK_USE_POSIX_THREADS
22 return true;
23#elif defined(SK_BUILD_FOR_WIN32)
24 // If we're >= Vista we'll find these functions. Otherwise (XP) SkCondVar is not supported.
25 HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
26 set_fn_ptr(&initialize_condition_variable,
27 GetProcAddress(kernel32, "InitializeConditionVariable"));
28 set_fn_ptr(&sleep_condition_variable,
29 GetProcAddress(kernel32, "SleepConditionVariableCS"));
30 set_fn_ptr(&wake_condition_variable,
31 GetProcAddress(kernel32, "WakeConditionVariable"));
32 set_fn_ptr(&wake_all_condition_variable,
33 GetProcAddress(kernel32, "WakeAllConditionVariable"));
34 return initialize_condition_variable
35 && sleep_condition_variable
36 && wake_condition_variable
37 && wake_all_condition_variable;
38#else
39 return false;
40#endif
41}
42
scroggo@google.com4177ef42012-10-31 15:52:16 +000043SkCondVar::SkCondVar() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000044#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000045 pthread_mutex_init(&fMutex, NULL /* default mutex attr */);
46 pthread_cond_init(&fCond, NULL /* default cond attr */);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000047#elif defined(SK_BUILD_FOR_WIN32)
48 InitializeCriticalSection(&fCriticalSection);
mtkleindb8d0e52014-11-03 17:25:54 -080049 SkASSERT(initialize_condition_variable);
50 initialize_condition_variable(&fCondition);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000051#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000052}
53
54SkCondVar::~SkCondVar() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000055#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000056 pthread_mutex_destroy(&fMutex);
57 pthread_cond_destroy(&fCond);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000058#elif defined(SK_BUILD_FOR_WIN32)
59 DeleteCriticalSection(&fCriticalSection);
60 // No need to clean up fCondition.
61#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000062}
63
64void SkCondVar::lock() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000065#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000066 pthread_mutex_lock(&fMutex);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000067#elif defined(SK_BUILD_FOR_WIN32)
68 EnterCriticalSection(&fCriticalSection);
69#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000070}
71
72void SkCondVar::unlock() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000073#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000074 pthread_mutex_unlock(&fMutex);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000075#elif defined(SK_BUILD_FOR_WIN32)
76 LeaveCriticalSection(&fCriticalSection);
77#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000078}
79
80void SkCondVar::wait() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000081#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000082 pthread_cond_wait(&fCond, &fMutex);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000083#elif defined(SK_BUILD_FOR_WIN32)
mtkleindb8d0e52014-11-03 17:25:54 -080084 SkASSERT(sleep_condition_variable);
85 sleep_condition_variable(&fCondition, &fCriticalSection, INFINITE);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000086#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000087}
88
89void SkCondVar::signal() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000090#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +000091 pthread_cond_signal(&fCond);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000092#elif defined(SK_BUILD_FOR_WIN32)
mtkleindb8d0e52014-11-03 17:25:54 -080093 SkASSERT(wake_condition_variable);
94 wake_condition_variable(&fCondition);
scroggo@google.com4d3c2812012-10-31 19:29:13 +000095#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +000096}
97
98void SkCondVar::broadcast() {
scroggo@google.com4d3c2812012-10-31 19:29:13 +000099#ifdef SK_USE_POSIX_THREADS
scroggo@google.com4177ef42012-10-31 15:52:16 +0000100 pthread_cond_broadcast(&fCond);
scroggo@google.com4d3c2812012-10-31 19:29:13 +0000101#elif defined(SK_BUILD_FOR_WIN32)
mtkleindb8d0e52014-11-03 17:25:54 -0800102 SkASSERT(wake_all_condition_variable);
103 wake_all_condition_variable(&fCondition);
scroggo@google.com4d3c2812012-10-31 19:29:13 +0000104#endif
scroggo@google.com4177ef42012-10-31 15:52:16 +0000105}