File indexing completed on 2025-11-19 09:50:50
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef Py_INTERNAL_QSBR_H
0010 #define Py_INTERNAL_QSBR_H
0011
0012 #include <stdbool.h>
0013 #include <stdint.h>
0014 #include "pycore_lock.h" // PyMutex
0015
0016 #ifdef __cplusplus
0017 extern "C" {
0018 #endif
0019
0020 #ifndef Py_BUILD_CORE
0021 # error "this header requires Py_BUILD_CORE define"
0022 #endif
0023
0024
0025
0026
0027
0028 #define QSBR_OFFLINE 0
0029 #define QSBR_INITIAL 1
0030 #define QSBR_INCR 2
0031
0032
0033
0034
0035 #define QSBR_LT(a, b) ((int64_t)((a)-(b)) < 0)
0036 #define QSBR_LEQ(a, b) ((int64_t)((a)-(b)) <= 0)
0037
0038 struct _qsbr_shared;
0039 struct _PyThreadStateImpl;
0040
0041
0042 struct _qsbr_thread_state {
0043
0044 uint64_t seq;
0045
0046
0047 struct _qsbr_shared *shared;
0048
0049
0050 PyThreadState *tstate;
0051
0052
0053 int deferrals;
0054
0055
0056 bool allocated;
0057 struct _qsbr_thread_state *freelist_next;
0058 };
0059
0060
0061 struct _qsbr_pad {
0062 struct _qsbr_thread_state qsbr;
0063 char __padding[64 - sizeof(struct _qsbr_thread_state)];
0064 };
0065
0066
0067 struct _qsbr_shared {
0068
0069 uint64_t wr_seq;
0070
0071
0072 uint64_t rd_seq;
0073
0074
0075 struct _qsbr_pad *array;
0076 Py_ssize_t size;
0077
0078
0079 PyMutex mutex;
0080 struct _qsbr_thread_state *freelist;
0081 };
0082
0083 static inline uint64_t
0084 _Py_qsbr_shared_current(struct _qsbr_shared *shared)
0085 {
0086 return _Py_atomic_load_uint64_acquire(&shared->wr_seq);
0087 }
0088
0089
0090
0091 static inline void
0092 _Py_qsbr_quiescent_state(struct _qsbr_thread_state *qsbr)
0093 {
0094 uint64_t seq = _Py_qsbr_shared_current(qsbr->shared);
0095 _Py_atomic_store_uint64_release(&qsbr->seq, seq);
0096 }
0097
0098
0099
0100 static inline bool
0101 _Py_qbsr_goal_reached(struct _qsbr_thread_state *qsbr, uint64_t goal)
0102 {
0103 uint64_t rd_seq = _Py_atomic_load_uint64(&qsbr->shared->rd_seq);
0104 return QSBR_LEQ(goal, rd_seq);
0105 }
0106
0107
0108
0109
0110 extern uint64_t
0111 _Py_qsbr_advance(struct _qsbr_shared *shared);
0112
0113
0114
0115
0116 extern uint64_t
0117 _Py_qsbr_deferred_advance(struct _qsbr_thread_state *qsbr);
0118
0119
0120
0121 extern bool
0122 _Py_qsbr_poll(struct _qsbr_thread_state *qsbr, uint64_t goal);
0123
0124
0125 extern void
0126 _Py_qsbr_attach(struct _qsbr_thread_state *qsbr);
0127
0128
0129 extern void
0130 _Py_qsbr_detach(struct _qsbr_thread_state *qsbr);
0131
0132
0133 extern Py_ssize_t
0134 _Py_qsbr_reserve(PyInterpreterState *interp);
0135
0136
0137 extern void
0138 _Py_qsbr_register(struct _PyThreadStateImpl *tstate,
0139 PyInterpreterState *interp, Py_ssize_t index);
0140
0141
0142 extern void
0143 _Py_qsbr_unregister(PyThreadState *tstate);
0144
0145 extern void
0146 _Py_qsbr_fini(PyInterpreterState *interp);
0147
0148 extern void
0149 _Py_qsbr_after_fork(struct _PyThreadStateImpl *tstate);
0150
0151 #ifdef __cplusplus
0152 }
0153 #endif
0154 #endif