1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2019 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/yield_policy.h" 11*d9f75844SAndroid Build Coastguard Worker 12*d9f75844SAndroid Build Coastguard Worker #include "absl/base/attributes.h" 13*d9f75844SAndroid Build Coastguard Worker #include "absl/base/config.h" 14*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 15*d9f75844SAndroid Build Coastguard Worker #if !defined(ABSL_HAVE_THREAD_LOCAL) && defined(WEBRTC_POSIX) 16*d9f75844SAndroid Build Coastguard Worker #include <pthread.h> 17*d9f75844SAndroid Build Coastguard Worker #endif 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker namespace rtc { 20*d9f75844SAndroid Build Coastguard Worker namespace { 21*d9f75844SAndroid Build Coastguard Worker 22*d9f75844SAndroid Build Coastguard Worker #if defined(ABSL_HAVE_THREAD_LOCAL) 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local YieldInterface* current_yield_policy = nullptr; 25*d9f75844SAndroid Build Coastguard Worker GetCurrentYieldPolicy()26*d9f75844SAndroid Build Coastguard WorkerYieldInterface* GetCurrentYieldPolicy() { 27*d9f75844SAndroid Build Coastguard Worker return current_yield_policy; 28*d9f75844SAndroid Build Coastguard Worker } 29*d9f75844SAndroid Build Coastguard Worker SetCurrentYieldPolicy(YieldInterface * ptr)30*d9f75844SAndroid Build Coastguard Workervoid SetCurrentYieldPolicy(YieldInterface* ptr) { 31*d9f75844SAndroid Build Coastguard Worker current_yield_policy = ptr; 32*d9f75844SAndroid Build Coastguard Worker } 33*d9f75844SAndroid Build Coastguard Worker 34*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX) 35*d9f75844SAndroid Build Coastguard Worker 36*d9f75844SAndroid Build Coastguard Worker // Emscripten does not support the C++11 thread_local keyword but does support 37*d9f75844SAndroid Build Coastguard Worker // the pthread thread-local storage API. 38*d9f75844SAndroid Build Coastguard Worker // https://github.com/emscripten-core/emscripten/issues/3502 39*d9f75844SAndroid Build Coastguard Worker 40*d9f75844SAndroid Build Coastguard Worker ABSL_CONST_INIT pthread_key_t g_current_yield_policy_tls = 0; 41*d9f75844SAndroid Build Coastguard Worker 42*d9f75844SAndroid Build Coastguard Worker void InitializeTls() { 43*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_EQ(pthread_key_create(&g_current_yield_policy_tls, nullptr), 0); 44*d9f75844SAndroid Build Coastguard Worker } 45*d9f75844SAndroid Build Coastguard Worker 46*d9f75844SAndroid Build Coastguard Worker pthread_key_t GetCurrentYieldPolicyTls() { 47*d9f75844SAndroid Build Coastguard Worker static pthread_once_t init_once = PTHREAD_ONCE_INIT; 48*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_EQ(pthread_once(&init_once, &InitializeTls), 0); 49*d9f75844SAndroid Build Coastguard Worker return g_current_yield_policy_tls; 50*d9f75844SAndroid Build Coastguard Worker } 51*d9f75844SAndroid Build Coastguard Worker 52*d9f75844SAndroid Build Coastguard Worker YieldInterface* GetCurrentYieldPolicy() { 53*d9f75844SAndroid Build Coastguard Worker return static_cast<YieldInterface*>( 54*d9f75844SAndroid Build Coastguard Worker pthread_getspecific(GetCurrentYieldPolicyTls())); 55*d9f75844SAndroid Build Coastguard Worker } 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker void SetCurrentYieldPolicy(YieldInterface* ptr) { 58*d9f75844SAndroid Build Coastguard Worker pthread_setspecific(GetCurrentYieldPolicyTls(), ptr); 59*d9f75844SAndroid Build Coastguard Worker } 60*d9f75844SAndroid Build Coastguard Worker 61*d9f75844SAndroid Build Coastguard Worker #else 62*d9f75844SAndroid Build Coastguard Worker #error Unsupported platform 63*d9f75844SAndroid Build Coastguard Worker #endif 64*d9f75844SAndroid Build Coastguard Worker 65*d9f75844SAndroid Build Coastguard Worker } // namespace 66*d9f75844SAndroid Build Coastguard Worker ScopedYieldPolicy(YieldInterface * policy)67*d9f75844SAndroid Build Coastguard WorkerScopedYieldPolicy::ScopedYieldPolicy(YieldInterface* policy) 68*d9f75844SAndroid Build Coastguard Worker : previous_(GetCurrentYieldPolicy()) { 69*d9f75844SAndroid Build Coastguard Worker SetCurrentYieldPolicy(policy); 70*d9f75844SAndroid Build Coastguard Worker } 71*d9f75844SAndroid Build Coastguard Worker ~ScopedYieldPolicy()72*d9f75844SAndroid Build Coastguard WorkerScopedYieldPolicy::~ScopedYieldPolicy() { 73*d9f75844SAndroid Build Coastguard Worker SetCurrentYieldPolicy(previous_); 74*d9f75844SAndroid Build Coastguard Worker } 75*d9f75844SAndroid Build Coastguard Worker YieldExecution()76*d9f75844SAndroid Build Coastguard Workervoid ScopedYieldPolicy::YieldExecution() { 77*d9f75844SAndroid Build Coastguard Worker YieldInterface* current = GetCurrentYieldPolicy(); 78*d9f75844SAndroid Build Coastguard Worker if (current) 79*d9f75844SAndroid Build Coastguard Worker current->YieldExecution(); 80*d9f75844SAndroid Build Coastguard Worker } 81*d9f75844SAndroid Build Coastguard Worker 82*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 83