|
|
|||
File indexing completed on 2025-12-16 09:40:42
0001 // Copyright 2017 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // Core interfaces and definitions used by by low-level interfaces such as 0016 // SpinLock. 0017 0018 #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ 0019 #define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ 0020 0021 #include "absl/base/internal/raw_logging.h" 0022 #include "absl/base/internal/scheduling_mode.h" 0023 #include "absl/base/macros.h" 0024 0025 // The following two declarations exist so SchedulingGuard may friend them with 0026 // the appropriate language linkage. These callbacks allow libc internals, such 0027 // as function level statics, to schedule cooperatively when locking. 0028 extern "C" bool __google_disable_rescheduling(void); 0029 extern "C" void __google_enable_rescheduling(bool disable_result); 0030 0031 namespace absl { 0032 ABSL_NAMESPACE_BEGIN 0033 class CondVar; 0034 class Mutex; 0035 0036 namespace synchronization_internal { 0037 int MutexDelay(int32_t c, int mode); 0038 } // namespace synchronization_internal 0039 0040 namespace base_internal { 0041 0042 class SchedulingHelper; // To allow use of SchedulingGuard. 0043 class SpinLock; // To allow use of SchedulingGuard. 0044 0045 // SchedulingGuard 0046 // Provides guard semantics that may be used to disable cooperative rescheduling 0047 // of the calling thread within specific program blocks. This is used to 0048 // protect resources (e.g. low-level SpinLocks or Domain code) that cooperative 0049 // scheduling depends on. 0050 // 0051 // Domain implementations capable of rescheduling in reaction to involuntary 0052 // kernel thread actions (e.g blocking due to a pagefault or syscall) must 0053 // guarantee that an annotated thread is not allowed to (cooperatively) 0054 // reschedule until the annotated region is complete. 0055 // 0056 // It is an error to attempt to use a cooperatively scheduled resource (e.g. 0057 // Mutex) within a rescheduling-disabled region. 0058 // 0059 // All methods are async-signal safe. 0060 class SchedulingGuard { 0061 public: 0062 // Returns true iff the calling thread may be cooperatively rescheduled. 0063 static bool ReschedulingIsAllowed(); 0064 SchedulingGuard(const SchedulingGuard&) = delete; 0065 SchedulingGuard& operator=(const SchedulingGuard&) = delete; 0066 0067 private: 0068 // Disable cooperative rescheduling of the calling thread. It may still 0069 // initiate scheduling operations (e.g. wake-ups), however, it may not itself 0070 // reschedule. Nestable. The returned result is opaque, clients should not 0071 // attempt to interpret it. 0072 // REQUIRES: Result must be passed to a pairing EnableScheduling(). 0073 static bool DisableRescheduling(); 0074 0075 // Marks the end of a rescheduling disabled region, previously started by 0076 // DisableRescheduling(). 0077 // REQUIRES: Pairs with innermost call (and result) of DisableRescheduling(). 0078 static void EnableRescheduling(bool disable_result); 0079 0080 // A scoped helper for {Disable, Enable}Rescheduling(). 0081 // REQUIRES: destructor must run in same thread as constructor. 0082 struct ScopedDisable { 0083 ScopedDisable() { disabled = SchedulingGuard::DisableRescheduling(); } 0084 ~ScopedDisable() { SchedulingGuard::EnableRescheduling(disabled); } 0085 0086 bool disabled; 0087 }; 0088 0089 // A scoped helper to enable rescheduling temporarily. 0090 // REQUIRES: destructor must run in same thread as constructor. 0091 class ScopedEnable { 0092 public: 0093 ScopedEnable(); 0094 ~ScopedEnable(); 0095 0096 private: 0097 int scheduling_disabled_depth_; 0098 }; 0099 0100 // Access to SchedulingGuard is explicitly permitted. 0101 friend class absl::CondVar; 0102 friend class absl::Mutex; 0103 friend class SchedulingHelper; 0104 friend class SpinLock; 0105 friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode); 0106 }; 0107 0108 //------------------------------------------------------------------------------ 0109 // End of public interfaces. 0110 //------------------------------------------------------------------------------ 0111 0112 inline bool SchedulingGuard::ReschedulingIsAllowed() { 0113 return false; 0114 } 0115 0116 inline bool SchedulingGuard::DisableRescheduling() { 0117 return false; 0118 } 0119 0120 inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { 0121 return; 0122 } 0123 0124 inline SchedulingGuard::ScopedEnable::ScopedEnable() 0125 : scheduling_disabled_depth_(0) {} 0126 inline SchedulingGuard::ScopedEnable::~ScopedEnable() { 0127 ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning"); 0128 } 0129 0130 } // namespace base_internal 0131 ABSL_NAMESPACE_END 0132 } // namespace absl 0133 0134 #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|