|
|
|||
File indexing completed on 2025-11-19 09:50:49
0001 // ParkingLot is an internal API for building efficient synchronization 0002 // primitives like mutexes and events. 0003 // 0004 // The API and name is inspired by WebKit's WTF::ParkingLot, which in turn 0005 // is inspired Linux's futex API. 0006 // See https://webkit.org/blog/6161/locking-in-webkit/. 0007 // 0008 // The core functionality is an atomic "compare-and-sleep" operation along with 0009 // an atomic "wake-up" operation. 0010 0011 #ifndef Py_INTERNAL_PARKING_LOT_H 0012 #define Py_INTERNAL_PARKING_LOT_H 0013 #ifdef __cplusplus 0014 extern "C" { 0015 #endif 0016 0017 #ifndef Py_BUILD_CORE 0018 # error "this header requires Py_BUILD_CORE define" 0019 #endif 0020 0021 0022 enum { 0023 // The thread was unparked by another thread. 0024 Py_PARK_OK = 0, 0025 0026 // The value of `address` did not match `expected`. 0027 Py_PARK_AGAIN = -1, 0028 0029 // The thread was unparked due to a timeout. 0030 Py_PARK_TIMEOUT = -2, 0031 0032 // The thread was interrupted by a signal. 0033 Py_PARK_INTR = -3, 0034 }; 0035 0036 // Checks that `*address == *expected` and puts the thread to sleep until an 0037 // unpark operation is called on the same `address`. Otherwise, the function 0038 // returns `Py_PARK_AGAIN`. The comparison behaves like memcmp, but is 0039 // performed atomically with respect to unpark operations. 0040 // 0041 // The `address_size` argument is the size of the data pointed to by the 0042 // `address` and `expected` pointers (i.e., sizeof(*address)). It must be 0043 // 1, 2, 4, or 8. 0044 // 0045 // The `timeout_ns` argument specifies the maximum amount of time to wait, with 0046 // -1 indicating an infinite wait. 0047 // 0048 // `park_arg`, which can be NULL, is passed to the unpark operation. 0049 // 0050 // If `detach` is true, then the thread will detach/release the GIL while 0051 // waiting. 0052 // 0053 // Example usage: 0054 // 0055 // if (_Py_atomic_compare_exchange_uint8(address, &expected, new_value)) { 0056 // int res = _PyParkingLot_Park(address, &new_value, sizeof(*address), 0057 // timeout_ns, NULL, 1); 0058 // ... 0059 // } 0060 PyAPI_FUNC(int) 0061 _PyParkingLot_Park(const void *address, const void *expected, 0062 size_t address_size, PyTime_t timeout_ns, 0063 void *park_arg, int detach); 0064 0065 // Callback for _PyParkingLot_Unpark: 0066 // 0067 // `arg` is the data of the same name provided to the _PyParkingLot_Unpark() 0068 // call. 0069 // `park_arg` is the data provided to _PyParkingLot_Park() call or NULL if 0070 // no waiting thread was found. 0071 // `has_more_waiters` is true if there are more threads waiting on the same 0072 // address. May be true in cases where threads are waiting on a different 0073 // address that map to the same internal bucket. 0074 typedef void _Py_unpark_fn_t(void *arg, void *park_arg, int has_more_waiters); 0075 0076 // Unparks a single thread waiting on `address`. 0077 // 0078 // Note that fn() is called regardless of whether a thread was unparked. If 0079 // no threads are waiting on `address` then the `park_arg` argument to fn() 0080 // will be NULL. 0081 // 0082 // Example usage: 0083 // void callback(void *arg, void *park_arg, int has_more_waiters); 0084 // _PyParkingLot_Unpark(address, &callback, arg); 0085 PyAPI_FUNC(void) 0086 _PyParkingLot_Unpark(const void *address, _Py_unpark_fn_t *fn, void *arg); 0087 0088 // Unparks all threads waiting on `address`. 0089 PyAPI_FUNC(void) _PyParkingLot_UnparkAll(const void *address); 0090 0091 // Resets the parking lot state after a fork. Forgets all parked threads. 0092 PyAPI_FUNC(void) _PyParkingLot_AfterFork(void); 0093 0094 #ifdef __cplusplus 0095 } 0096 #endif 0097 #endif /* !Py_INTERNAL_PARKING_LOT_H */
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|