aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_ctypes/_ctypes_test.c4
-rw-r--r--Modules/_ctypes/cfield.c4
-rw-r--r--Modules/_ctypes/ctypes.h2
-rw-r--r--Modules/_interpchannelsmodule.c6
-rw-r--r--Modules/_interpqueuesmodule.c6
-rw-r--r--Modules/_interpretersmodule.c28
-rw-r--r--Modules/_opcode.c2
-rw-r--r--Modules/_remote_debugging_module.c83
-rw-r--r--Modules/_stat.c4
-rw-r--r--Modules/_testinternalcapi.c5
-rw-r--r--Modules/blake2module.c74
-rw-r--r--Modules/clinic/_remote_debugging_module.c.h40
-rw-r--r--Modules/clinic/blake2module.c.h14
-rw-r--r--Modules/clinic/mathmodule.c.h36
-rw-r--r--Modules/clinic/sha3module.c.h14
-rw-r--r--Modules/hmacmodule.c21
-rw-r--r--Modules/mathmodule.c20
-rw-r--r--Modules/posixmodule.c3
-rw-r--r--Modules/sha3module.c9
19 files changed, 253 insertions, 122 deletions
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index d28e5708b44..66338805007 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -23,7 +23,7 @@
# define _Py_thread_local __thread
#endif
-#if defined(Py_FFI_SUPPORT_C_COMPLEX)
+#if defined(_Py_FFI_SUPPORT_C_COMPLEX)
# include <complex.h> // csqrt()
# undef I // for _ctypes_test_generated.c.h
#endif
@@ -457,7 +457,7 @@ EXPORT(double) my_sqrt(double a)
return sqrt(a);
}
-#if defined(Py_FFI_SUPPORT_C_COMPLEX)
+#if defined(_Py_FFI_SUPPORT_C_COMPLEX)
EXPORT(double complex) my_csqrt(double complex a)
{
return csqrt(a);
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index 163b9264261..547e2471a1c 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -759,7 +759,7 @@ d_get(void *ptr, Py_ssize_t size)
return PyFloat_FromDouble(val);
}
-#if defined(Py_FFI_SUPPORT_C_COMPLEX)
+#if defined(_Py_FFI_SUPPORT_C_COMPLEX)
/* We don't use _Complex types here, using arrays instead, as the C11+
standard says: "Each complex type has the same representation and alignment
@@ -1599,7 +1599,7 @@ for base_code, base_c_type in [
///////////////////////////////////////////////////////////////////////////
TABLE_ENTRY_SW(d, &ffi_type_double);
-#if defined(Py_FFI_SUPPORT_C_COMPLEX)
+#if defined(_Py_FFI_SUPPORT_C_COMPLEX)
if (Py_FFI_COMPLEX_AVAILABLE) {
TABLE_ENTRY(D, &ffi_type_complex_double);
TABLE_ENTRY(F, &ffi_type_complex_float);
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index 6a45c11e61a..5b4f97d43b8 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -23,7 +23,7 @@
// Do we support C99 complex types in ffi?
// For Apple's libffi, this must be determined at runtime (see gh-128156).
-#if defined(Py_FFI_SUPPORT_C_COMPLEX)
+#if defined(_Py_FFI_SUPPORT_C_COMPLEX)
# if USING_APPLE_OS_LIBFFI && defined(__has_builtin)
# if __has_builtin(__builtin_available)
# define Py_FFI_COMPLEX_AVAILABLE __builtin_available(macOS 10.15, *)
diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c
index ee5e2b005e0..9c1f8615161 100644
--- a/Modules/_interpchannelsmodule.c
+++ b/Modules/_interpchannelsmodule.c
@@ -3614,8 +3614,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
{
module_state *state = get_module_state(mod);
assert(state != NULL);
- (void)traverse_module_state(state, visit, arg);
- return 0;
+ return traverse_module_state(state, visit, arg);
}
static int
@@ -3625,8 +3624,7 @@ module_clear(PyObject *mod)
assert(state != NULL);
// Now we clear the module state.
- (void)clear_module_state(state);
- return 0;
+ return clear_module_state(state);
}
static void
diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c
index de06b8b41fe..e5afe746f90 100644
--- a/Modules/_interpqueuesmodule.c
+++ b/Modules/_interpqueuesmodule.c
@@ -1952,8 +1952,7 @@ static int
module_traverse(PyObject *mod, visitproc visit, void *arg)
{
module_state *state = get_module_state(mod);
- (void)traverse_module_state(state, visit, arg);
- return 0;
+ return traverse_module_state(state, visit, arg);
}
static int
@@ -1962,8 +1961,7 @@ module_clear(PyObject *mod)
module_state *state = get_module_state(mod);
// Now we clear the module state.
- (void)clear_module_state(state);
- return 0;
+ return clear_module_state(state);
}
static void
diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c
index e201ccd53da..e7feaa7f186 100644
--- a/Modules/_interpretersmodule.c
+++ b/Modules/_interpretersmodule.c
@@ -1039,8 +1039,8 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *id, *updates;
int restricted = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "OO|$p:" MODULE_NAME_STR ".set___main___attrs",
- kwlist, &id, &updates, &restricted))
+ "OO!|$p:" MODULE_NAME_STR ".set___main___attrs",
+ kwlist, &id, &PyDict_Type, &updates, &restricted))
{
return NULL;
}
@@ -1054,16 +1054,14 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs)
}
// Check the updates.
- if (updates != Py_None) {
- Py_ssize_t size = PyObject_Size(updates);
- if (size < 0) {
- return NULL;
- }
- if (size == 0) {
- PyErr_SetString(PyExc_ValueError,
- "arg 2 must be a non-empty mapping");
- return NULL;
- }
+ Py_ssize_t size = PyDict_Size(updates);
+ if (size < 0) {
+ return NULL;
+ }
+ if (size == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "arg 2 must be a non-empty dict");
+ return NULL;
}
_PyXI_session *session = _PyXI_NewSession();
@@ -1708,8 +1706,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
{
module_state *state = get_module_state(mod);
assert(state != NULL);
- (void)traverse_module_state(state, visit, arg);
- return 0;
+ return traverse_module_state(state, visit, arg);
}
static int
@@ -1717,8 +1714,7 @@ module_clear(PyObject *mod)
{
module_state *state = get_module_state(mod);
assert(state != NULL);
- (void)clear_module_state(state);
- return 0;
+ return clear_module_state(state);
}
static void
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index c295f7b3152..ef271b6ef56 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -5,7 +5,7 @@
#include "Python.h"
#include "compile.h"
#include "opcode.h"
-#include "pycore_ceval.h"
+#include "pycore_ceval.h" // SPECIAL_MAX
#include "pycore_code.h"
#include "pycore_compile.h"
#include "pycore_intrinsics.h"
diff --git a/Modules/_remote_debugging_module.c b/Modules/_remote_debugging_module.c
index c2421cac6bd..ce7189637c2 100644
--- a/Modules/_remote_debugging_module.c
+++ b/Modules/_remote_debugging_module.c
@@ -64,12 +64,14 @@
#endif
#ifdef Py_GIL_DISABLED
-#define INTERP_STATE_MIN_SIZE MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \
- offsetof(PyInterpreterState, tlbc_indices.tlbc_generation) + sizeof(uint32_t)), \
- offsetof(PyInterpreterState, threads.head) + sizeof(void*))
+#define INTERP_STATE_MIN_SIZE MAX(MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \
+ offsetof(PyInterpreterState, tlbc_indices.tlbc_generation) + sizeof(uint32_t)), \
+ offsetof(PyInterpreterState, threads.head) + sizeof(void*)), \
+ offsetof(PyInterpreterState, _gil.last_holder) + sizeof(PyThreadState*))
#else
-#define INTERP_STATE_MIN_SIZE MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \
- offsetof(PyInterpreterState, threads.head) + sizeof(void*))
+#define INTERP_STATE_MIN_SIZE MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \
+ offsetof(PyInterpreterState, threads.head) + sizeof(void*)), \
+ offsetof(PyInterpreterState, _gil.last_holder) + sizeof(PyThreadState*))
#endif
#define INTERP_STATE_BUFFER_SIZE MAX(INTERP_STATE_MIN_SIZE, 256)
@@ -206,6 +208,7 @@ typedef struct {
uint64_t code_object_generation;
_Py_hashtable_t *code_object_cache;
int debug;
+ int only_active_thread;
RemoteDebuggingState *cached_state; // Cached module state
#ifdef Py_GIL_DISABLED
// TLBC cache invalidation tracking
@@ -2496,6 +2499,7 @@ _remote_debugging.RemoteUnwinder.__init__
pid: int
*
all_threads: bool = False
+ only_active_thread: bool = False
debug: bool = False
Initialize a new RemoteUnwinder object for debugging a remote Python process.
@@ -2504,6 +2508,8 @@ Args:
pid: Process ID of the target Python process to debug
all_threads: If True, initialize state for all threads in the process.
If False, only initialize for the main thread.
+ only_active_thread: If True, only sample the thread holding the GIL.
+ Cannot be used together with all_threads=True.
debug: If True, chain exceptions to explain the sequence of events that
lead to the exception.
@@ -2514,15 +2520,33 @@ Raises:
PermissionError: If access to the target process is denied
OSError: If unable to attach to the target process or access its memory
RuntimeError: If unable to read debug information from the target process
+ ValueError: If both all_threads and only_active_thread are True
[clinic start generated code]*/
static int
_remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
int pid, int all_threads,
+ int only_active_thread,
int debug)
-/*[clinic end generated code: output=3982f2a7eba49334 input=48a762566b828e91]*/
+/*[clinic end generated code: output=13ba77598ecdcbe1 input=8f8f12504e17da04]*/
{
+ // Validate that all_threads and only_active_thread are not both True
+ if (all_threads && only_active_thread) {
+ PyErr_SetString(PyExc_ValueError,
+ "all_threads and only_active_thread cannot both be True");
+ return -1;
+ }
+
+#ifdef Py_GIL_DISABLED
+ if (only_active_thread) {
+ PyErr_SetString(PyExc_ValueError,
+ "only_active_thread is not supported when Py_GIL_DISABLED is not defined");
+ return -1;
+ }
+#endif
+
self->debug = debug;
+ self->only_active_thread = only_active_thread;
self->cached_state = NULL;
if (_Py_RemoteDebug_InitProcHandle(&self->handle, pid) < 0) {
set_exception_cause(self, PyExc_RuntimeError, "Failed to initialize process handle");
@@ -2602,13 +2626,18 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
@critical_section
_remote_debugging.RemoteUnwinder.get_stack_trace
-Returns a list of stack traces for all threads in the target process.
+Returns a list of stack traces for threads in the target process.
Each element in the returned list is a tuple of (thread_id, frame_list), where:
- thread_id is the OS thread identifier
- frame_list is a list of tuples (function_name, filename, line_number) representing
the Python stack frames for that thread, ordered from most recent to oldest
+The threads returned depend on the initialization parameters:
+- If only_active_thread was True: returns only the thread holding the GIL
+- If all_threads was True: returns all threads
+- Otherwise: returns only the main thread
+
Example:
[
(1234, [
@@ -2632,7 +2661,7 @@ Raises:
static PyObject *
_remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self)
-/*[clinic end generated code: output=666192b90c69d567 input=331dbe370578badf]*/
+/*[clinic end generated code: output=666192b90c69d567 input=f756f341206f9116]*/
{
PyObject* result = NULL;
// Read interpreter state into opaque buffer
@@ -2655,6 +2684,28 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
_Py_hashtable_clear(self->code_object_cache);
}
+ // If only_active_thread is true, we need to determine which thread holds the GIL
+ PyThreadState* gil_holder = NULL;
+ if (self->only_active_thread) {
+ // The GIL state is already in interp_state_buffer, just read from there
+ // Check if GIL is locked
+ int gil_locked = GET_MEMBER(int, interp_state_buffer,
+ self->debug_offsets.interpreter_state.gil_runtime_state_locked);
+
+ if (gil_locked) {
+ // Get the last holder (current holder when GIL is locked)
+ gil_holder = GET_MEMBER(PyThreadState*, interp_state_buffer,
+ self->debug_offsets.interpreter_state.gil_runtime_state_holder);
+ } else {
+ // GIL is not locked, return empty list
+ result = PyList_New(0);
+ if (!result) {
+ set_exception_cause(self, PyExc_MemoryError, "Failed to create empty result list");
+ }
+ goto exit;
+ }
+ }
+
#ifdef Py_GIL_DISABLED
// Check TLBC generation and invalidate cache if needed
uint32_t current_tlbc_generation = GET_MEMBER(uint32_t, interp_state_buffer,
@@ -2666,7 +2717,10 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
#endif
uintptr_t current_tstate;
- if (self->tstate_addr == 0) {
+ if (self->only_active_thread && gil_holder != NULL) {
+ // We have the GIL holder, process only that thread
+ current_tstate = (uintptr_t)gil_holder;
+ } else if (self->tstate_addr == 0) {
// Get threads head from buffer
current_tstate = GET_MEMBER(uintptr_t, interp_state_buffer,
self->debug_offsets.interpreter_state.threads_head);
@@ -2700,10 +2754,14 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self
if (self->tstate_addr) {
break;
}
+
+ // If we're only processing the GIL holder, we're done after one iteration
+ if (self->only_active_thread && gil_holder != NULL) {
+ break;
+ }
}
exit:
- _Py_RemoteDebug_ClearCache(&self->handle);
return result;
}
@@ -2827,11 +2885,9 @@ _remote_debugging_RemoteUnwinder_get_all_awaited_by_impl(RemoteUnwinderObject *s
goto result_err;
}
- _Py_RemoteDebug_ClearCache(&self->handle);
return result;
result_err:
- _Py_RemoteDebug_ClearCache(&self->handle);
Py_XDECREF(result);
return NULL;
}
@@ -2898,11 +2954,9 @@ _remote_debugging_RemoteUnwinder_get_async_stack_trace_impl(RemoteUnwinderObject
goto cleanup;
}
- _Py_RemoteDebug_ClearCache(&self->handle);
return result;
cleanup:
- _Py_RemoteDebug_ClearCache(&self->handle);
Py_XDECREF(result);
return NULL;
}
@@ -2928,7 +2982,6 @@ RemoteUnwinder_dealloc(PyObject *op)
}
#endif
if (self->handle.pid != 0) {
- _Py_RemoteDebug_ClearCache(&self->handle);
_Py_RemoteDebug_CleanupProcHandle(&self->handle);
}
PyObject_Del(self);
diff --git a/Modules/_stat.c b/Modules/_stat.c
index f11ca7d23b4..1dabf2f6d5b 100644
--- a/Modules/_stat.c
+++ b/Modules/_stat.c
@@ -57,7 +57,7 @@ typedef unsigned short mode_t;
* Only the names are defined by POSIX but not their value. All common file
* types seems to have the same numeric value on all platforms, though.
*
- * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK
+ * fileutils.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK
*/
#ifndef S_IFBLK
@@ -86,7 +86,7 @@ typedef unsigned short mode_t;
/* S_ISXXX()
- * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR()
+ * fileutils.h defines S_ISDIR(), S_ISREG() and S_ISCHR()
*/
#ifndef S_ISBLK
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index 804cb4e4d1c..fdf22a0c994 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -21,6 +21,7 @@
#include "pycore_fileutils.h" // _Py_normpath()
#include "pycore_flowgraph.h" // _PyCompile_OptimizeCfg()
#include "pycore_frame.h" // _PyInterpreterFrame
+#include "pycore_function.h" // _PyFunction_GET_BUILTINS
#include "pycore_gc.h" // PyGC_Head
#include "pycore_hashtable.h" // _Py_hashtable_new()
#include "pycore_import.h" // _PyImport_ClearExtension()
@@ -1022,7 +1023,7 @@ get_code_var_counts(PyObject *self, PyObject *_args, PyObject *_kwargs)
globalsns = PyFunction_GET_GLOBALS(codearg);
}
if (builtinsns == NULL) {
- builtinsns = PyFunction_GET_BUILTINS(codearg);
+ builtinsns = _PyFunction_GET_BUILTINS(codearg);
}
codearg = PyFunction_GET_CODE(codearg);
}
@@ -1190,7 +1191,7 @@ verify_stateless_code(PyObject *self, PyObject *args, PyObject *kwargs)
globalsns = PyFunction_GET_GLOBALS(codearg);
}
if (builtinsns == NULL) {
- builtinsns = PyFunction_GET_BUILTINS(codearg);
+ builtinsns = _PyFunction_GET_BUILTINS(codearg);
}
codearg = PyFunction_GET_CODE(codearg);
}
diff --git a/Modules/blake2module.c b/Modules/blake2module.c
index 6c4349ac06b..163f238a426 100644
--- a/Modules/blake2module.c
+++ b/Modules/blake2module.c
@@ -43,25 +43,25 @@
// SIMD256 can't be compiled on macOS ARM64, and performance of SIMD128 isn't
// great; but when compiling a universal2 binary, autoconf will set
-// HACL_CAN_COMPILE_SIMD128 and HACL_CAN_COMPILE_SIMD256 because they *can* be
-// compiled on x86_64. If we're on macOS ARM64, disable these preprocessor
-// symbols.
+// _Py_HACL_CAN_COMPILE_VEC{128,256} because they *can* be compiled on x86_64.
+// If we're on macOS ARM64, we however disable these preprocessor symbols.
#if defined(__APPLE__) && defined(__arm64__)
-# undef HACL_CAN_COMPILE_SIMD128
-# undef HACL_CAN_COMPILE_SIMD256
+# undef _Py_HACL_CAN_COMPILE_VEC128
+# undef _Py_HACL_CAN_COMPILE_VEC256
#endif
-// Small mismatch between the variable names Python defines as part of configure
-// at the ones HACL* expects to be set in order to enable those headers.
-#define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128
-#define HACL_CAN_COMPILE_VEC256 HACL_CAN_COMPILE_SIMD256
+// HACL* expects HACL_CAN_COMPILE_VEC* macros to be set in order to enable
+// the corresponding SIMD instructions so we need to "forward" the values
+// we just deduced above.
+#define HACL_CAN_COMPILE_VEC128 _Py_HACL_CAN_COMPILE_VEC128
+#define HACL_CAN_COMPILE_VEC256 _Py_HACL_CAN_COMPILE_VEC256
#include "_hacl/Hacl_Hash_Blake2s.h"
#include "_hacl/Hacl_Hash_Blake2b.h"
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
#include "_hacl/Hacl_Hash_Blake2s_Simd128.h"
#endif
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
#include "_hacl/Hacl_Hash_Blake2b_Simd256.h"
#endif
@@ -88,7 +88,7 @@ blake2_get_state(PyObject *module)
return (Blake2State *)state;
}
-#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
+#if defined(_Py_HACL_CAN_COMPILE_VEC128) || defined(_Py_HACL_CAN_COMPILE_VEC256)
static inline Blake2State *
blake2_get_state_from_type(PyTypeObject *module)
{
@@ -181,7 +181,7 @@ blake2module_init_cpu_features(Blake2State *state)
#undef ECX_SSE3
#undef EBX_AVX2
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
// TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection
state->can_run_simd128 = sse && sse2 && sse3 && sse41 && sse42 && cmov;
#else
@@ -191,7 +191,7 @@ blake2module_init_cpu_features(Blake2State *state)
state->can_run_simd128 = false;
#endif
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
// TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection
state->can_run_simd256 = state->can_run_simd128 && avx && avx2;
#else
@@ -332,18 +332,18 @@ is_blake2s(blake2_impl impl)
static inline blake2_impl
type_to_impl(PyTypeObject *type)
{
-#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256)
+#if defined(_Py_HACL_CAN_COMPILE_VEC128) || defined(_Py_HACL_CAN_COMPILE_VEC256)
Blake2State *st = blake2_get_state_from_type(type);
#endif
if (!strcmp(type->tp_name, blake2b_type_spec.name)) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
return st->can_run_simd256 ? Blake2b_256 : Blake2b;
#else
return Blake2b;
#endif
}
else if (!strcmp(type->tp_name, blake2s_type_spec.name)) {
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
return st->can_run_simd128 ? Blake2s_128 : Blake2s;
#else
return Blake2s;
@@ -357,10 +357,10 @@ typedef struct {
union {
Hacl_Hash_Blake2s_state_t *blake2s_state;
Hacl_Hash_Blake2b_state_t *blake2b_state;
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
Hacl_Hash_Blake2s_Simd128_state_t *blake2s_128_state;
#endif
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
Hacl_Hash_Blake2b_Simd256_state_t *blake2b_256_state;
#endif
};
@@ -429,13 +429,13 @@ blake2_update_unlocked(Blake2Object *self, uint8_t *buf, Py_ssize_t len)
switch (self->impl) {
// blake2b_256_state and blake2s_128_state must be if'd since
// otherwise this results in an unresolved symbol at link-time.
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update,
self->blake2b_256_state, buf, len);
return;
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
HACL_UPDATE(Hacl_Hash_Blake2s_Simd128_update,
self->blake2s_128_state, buf, len);
@@ -555,12 +555,12 @@ py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size,
// Ensure that the states are NULL-initialized in case of an error.
// See: py_blake2_clear() for more details.
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
self->blake2b_256_state = NULL;
break;
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
self->blake2s_128_state = NULL;
break;
@@ -623,12 +623,12 @@ py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size,
} while (0)
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
BLAKE2_MALLOC(Blake2b_Simd256, self->blake2b_256_state);
break;
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
BLAKE2_MALLOC(Blake2s_Simd128, self->blake2s_128_state);
break;
@@ -756,12 +756,12 @@ blake2_blake2b_copy_unlocked(Blake2Object *self, Blake2Object *cpy)
} while (0)
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
BLAKE2_COPY(Blake2b_Simd256, blake2b_256_state);
break;
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
BLAKE2_COPY(Blake2s_Simd128, blake2s_128_state);
break;
@@ -787,17 +787,19 @@ error:
/*[clinic input]
_blake2.blake2b.copy
+ cls: defining_class
+
Return a copy of the hash object.
[clinic start generated code]*/
static PyObject *
-_blake2_blake2b_copy_impl(Blake2Object *self)
-/*[clinic end generated code: output=622d1c56b91c50d8 input=e383c2d199fd8a2e]*/
+_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls)
+/*[clinic end generated code: output=5f8ea31c56c52287 input=f38f3475e9aec98d]*/
{
int rc;
Blake2Object *cpy;
- if ((cpy = new_Blake2Object(Py_TYPE(self))) == NULL) {
+ if ((cpy = new_Blake2Object(cls)) == NULL) {
return NULL;
}
@@ -838,12 +840,12 @@ static uint8_t
blake2_blake2b_compute_digest(Blake2Object *self, uint8_t *digest)
{
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
return Hacl_Hash_Blake2b_Simd256_digest(
self->blake2b_256_state, digest);
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
return Hacl_Hash_Blake2s_Simd128_digest(
self->blake2s_128_state, digest);
@@ -921,11 +923,11 @@ static Hacl_Hash_Blake2b_index
hacl_get_blake2_info(Blake2Object *self)
{
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
return Hacl_Hash_Blake2b_Simd256_info(self->blake2b_256_state);
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
return Hacl_Hash_Blake2s_Simd128_info(self->blake2s_128_state);
#endif
@@ -973,12 +975,12 @@ py_blake2_clear(PyObject *op)
} while (0)
switch (self->impl) {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
case Blake2b_256:
BLAKE2_FREE(Blake2b_Simd256, self->blake2b_256_state);
break;
#endif
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
case Blake2s_128:
BLAKE2_FREE(Blake2s_Simd128, self->blake2s_128_state);
break;
diff --git a/Modules/clinic/_remote_debugging_module.c.h b/Modules/clinic/_remote_debugging_module.c.h
index 5c313a2d664..e80b24b54c0 100644
--- a/Modules/clinic/_remote_debugging_module.c.h
+++ b/Modules/clinic/_remote_debugging_module.c.h
@@ -10,7 +10,8 @@ preserve
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__,
-"RemoteUnwinder(pid, *, all_threads=False, debug=False)\n"
+"RemoteUnwinder(pid, *, all_threads=False, only_active_thread=False,\n"
+" debug=False)\n"
"--\n"
"\n"
"Initialize a new RemoteUnwinder object for debugging a remote Python process.\n"
@@ -19,6 +20,8 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__,
" pid: Process ID of the target Python process to debug\n"
" all_threads: If True, initialize state for all threads in the process.\n"
" If False, only initialize for the main thread.\n"
+" only_active_thread: If True, only sample the thread holding the GIL.\n"
+" Cannot be used together with all_threads=True.\n"
" debug: If True, chain exceptions to explain the sequence of events that\n"
" lead to the exception.\n"
"\n"
@@ -28,11 +31,13 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__,
"Raises:\n"
" PermissionError: If access to the target process is denied\n"
" OSError: If unable to attach to the target process or access its memory\n"
-" RuntimeError: If unable to read debug information from the target process");
+" RuntimeError: If unable to read debug information from the target process\n"
+" ValueError: If both all_threads and only_active_thread are True");
static int
_remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self,
int pid, int all_threads,
+ int only_active_thread,
int debug);
static int
@@ -41,7 +46,7 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje
int return_value = -1;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
- #define NUM_KEYWORDS 3
+ #define NUM_KEYWORDS 4
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
@@ -50,7 +55,7 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_hash = -1,
- .ob_item = { &_Py_ID(pid), &_Py_ID(all_threads), &_Py_ID(debug), },
+ .ob_item = { &_Py_ID(pid), &_Py_ID(all_threads), &_Py_ID(only_active_thread), &_Py_ID(debug), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
@@ -59,19 +64,20 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
- static const char * const _keywords[] = {"pid", "all_threads", "debug", NULL};
+ static const char * const _keywords[] = {"pid", "all_threads", "only_active_thread", "debug", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "RemoteUnwinder",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
- PyObject *argsbuf[3];
+ PyObject *argsbuf[4];
PyObject * const *fastargs;
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
int pid;
int all_threads = 0;
+ int only_active_thread = 0;
int debug = 0;
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
@@ -95,12 +101,21 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje
goto skip_optional_kwonly;
}
}
- debug = PyObject_IsTrue(fastargs[2]);
+ if (fastargs[2]) {
+ only_active_thread = PyObject_IsTrue(fastargs[2]);
+ if (only_active_thread < 0) {
+ goto exit;
+ }
+ if (!--noptargs) {
+ goto skip_optional_kwonly;
+ }
+ }
+ debug = PyObject_IsTrue(fastargs[3]);
if (debug < 0) {
goto exit;
}
skip_optional_kwonly:
- return_value = _remote_debugging_RemoteUnwinder___init___impl((RemoteUnwinderObject *)self, pid, all_threads, debug);
+ return_value = _remote_debugging_RemoteUnwinder___init___impl((RemoteUnwinderObject *)self, pid, all_threads, only_active_thread, debug);
exit:
return return_value;
@@ -110,13 +125,18 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stack_trace__doc__,
"get_stack_trace($self, /)\n"
"--\n"
"\n"
-"Returns a list of stack traces for all threads in the target process.\n"
+"Returns a list of stack traces for threads in the target process.\n"
"\n"
"Each element in the returned list is a tuple of (thread_id, frame_list), where:\n"
"- thread_id is the OS thread identifier\n"
"- frame_list is a list of tuples (function_name, filename, line_number) representing\n"
" the Python stack frames for that thread, ordered from most recent to oldest\n"
"\n"
+"The threads returned depend on the initialization parameters:\n"
+"- If only_active_thread was True: returns only the thread holding the GIL\n"
+"- If all_threads was True: returns all threads\n"
+"- Otherwise: returns only the main thread\n"
+"\n"
"Example:\n"
" [\n"
" (1234, [\n"
@@ -253,4 +273,4 @@ _remote_debugging_RemoteUnwinder_get_async_stack_trace(PyObject *self, PyObject
return return_value;
}
-/*[clinic end generated code: output=774ec34aa653402d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a37ab223d5081b16 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/blake2module.c.h b/Modules/clinic/blake2module.c.h
index 9e9cd56e569..97d010d03a4 100644
--- a/Modules/clinic/blake2module.c.h
+++ b/Modules/clinic/blake2module.c.h
@@ -434,15 +434,19 @@ PyDoc_STRVAR(_blake2_blake2b_copy__doc__,
"Return a copy of the hash object.");
#define _BLAKE2_BLAKE2B_COPY_METHODDEF \
- {"copy", (PyCFunction)_blake2_blake2b_copy, METH_NOARGS, _blake2_blake2b_copy__doc__},
+ {"copy", _PyCFunction_CAST(_blake2_blake2b_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _blake2_blake2b_copy__doc__},
static PyObject *
-_blake2_blake2b_copy_impl(Blake2Object *self);
+_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls);
static PyObject *
-_blake2_blake2b_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_blake2_blake2b_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
- return _blake2_blake2b_copy_impl((Blake2Object *)self);
+ if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+ PyErr_SetString(PyExc_TypeError, "copy() takes no arguments");
+ return NULL;
+ }
+ return _blake2_blake2b_copy_impl((Blake2Object *)self, cls);
}
PyDoc_STRVAR(_blake2_blake2b_update__doc__,
@@ -502,4 +506,4 @@ _blake2_blake2b_hexdigest(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return _blake2_blake2b_hexdigest_impl((Blake2Object *)self);
}
-/*[clinic end generated code: output=eed18dcfaf6f7731 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=60a4abbcb8950fe5 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h
index fbb012fb6dd..a443c48faaa 100644
--- a/Modules/clinic/mathmodule.c.h
+++ b/Modules/clinic/mathmodule.c.h
@@ -84,6 +84,40 @@ PyDoc_STRVAR(math_floor__doc__,
#define MATH_FLOOR_METHODDEF \
{"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
+PyDoc_STRVAR(math_signbit__doc__,
+"signbit($module, x, /)\n"
+"--\n"
+"\n"
+"Return True if the sign of x is negative and False otherwise.");
+
+#define MATH_SIGNBIT_METHODDEF \
+ {"signbit", (PyCFunction)math_signbit, METH_O, math_signbit__doc__},
+
+static PyObject *
+math_signbit_impl(PyObject *module, double x);
+
+static PyObject *
+math_signbit(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ double x;
+
+ if (PyFloat_CheckExact(arg)) {
+ x = PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ x = PyFloat_AsDouble(arg);
+ if (x == -1.0 && PyErr_Occurred()) {
+ goto exit;
+ }
+ }
+ return_value = math_signbit_impl(module, x);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(math_fsum__doc__,
"fsum($module, seq, /)\n"
"--\n"
@@ -1178,4 +1212,4 @@ math_ulp(PyObject *module, PyObject *arg)
exit:
return return_value;
}
-/*[clinic end generated code: output=44bba3a0a052a364 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4e3fa94d026f027b input=a9049054013a1b77]*/
diff --git a/Modules/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h
index d6d44bf4c51..1f631ff406e 100644
--- a/Modules/clinic/sha3module.c.h
+++ b/Modules/clinic/sha3module.c.h
@@ -100,15 +100,19 @@ PyDoc_STRVAR(_sha3_sha3_224_copy__doc__,
"Return a copy of the hash object.");
#define _SHA3_SHA3_224_COPY_METHODDEF \
- {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, _sha3_sha3_224_copy__doc__},
+ {"copy", _PyCFunction_CAST(_sha3_sha3_224_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sha3_sha3_224_copy__doc__},
static PyObject *
-_sha3_sha3_224_copy_impl(SHA3object *self);
+_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls);
static PyObject *
-_sha3_sha3_224_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_sha3_sha3_224_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
- return _sha3_sha3_224_copy_impl((SHA3object *)self);
+ if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+ PyErr_SetString(PyExc_TypeError, "copy() takes no arguments");
+ return NULL;
+ }
+ return _sha3_sha3_224_copy_impl((SHA3object *)self, cls);
}
PyDoc_STRVAR(_sha3_sha3_224_digest__doc__,
@@ -306,4 +310,4 @@ _sha3_shake_128_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t narg
exit:
return return_value;
}
-/*[clinic end generated code: output=c17e3ec670afe253 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=48be77f8a31e8a3e input=a9049054013a1b77]*/
diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c
index e7a5ccbb19b..95e400231bb 100644
--- a/Modules/hmacmodule.c
+++ b/Modules/hmacmodule.c
@@ -31,14 +31,15 @@
#endif
#if defined(__APPLE__) && defined(__arm64__)
-# undef HACL_CAN_COMPILE_SIMD128
-# undef HACL_CAN_COMPILE_SIMD256
+# undef _Py_HACL_CAN_COMPILE_VEC128
+# undef _Py_HACL_CAN_COMPILE_VEC256
#endif
-// Small mismatch between the variable names Python defines as part of configure
-// at the ones HACL* expects to be set in order to enable those headers.
-#define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128
-#define HACL_CAN_COMPILE_VEC256 HACL_CAN_COMPILE_SIMD256
+// HACL* expects HACL_CAN_COMPILE_VEC* macros to be set in order to enable
+// the corresponding SIMD instructions so we need to "forward" the values
+// we just deduced above.
+#define HACL_CAN_COMPILE_VEC128 _Py_HACL_CAN_COMPILE_VEC128
+#define HACL_CAN_COMPILE_VEC256 _Py_HACL_CAN_COMPILE_VEC256
#include "_hacl/Hacl_HMAC.h"
#include "_hacl/Hacl_Streaming_HMAC.h" // Hacl_Agile_Hash_* identifiers
@@ -361,7 +362,7 @@ narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind)
{
switch (kind) {
case Py_hmac_kind_hmac_blake2s_32: {
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
if (state->can_run_simd128) {
return Py_hmac_kind_hmac_vectorized_blake2s_32;
}
@@ -369,7 +370,7 @@ narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind)
return kind;
}
case Py_hmac_kind_hmac_blake2b_32: {
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
if (state->can_run_simd256) {
return Py_hmac_kind_hmac_vectorized_blake2b_32;
}
@@ -1601,7 +1602,7 @@ hmacmodule_init_cpu_features(hmacmodule_state *state)
#undef ECX_SSE3
#undef EBX_AVX2
-#if HACL_CAN_COMPILE_SIMD128
+#if _Py_HACL_CAN_COMPILE_VEC128
// TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection
state->can_run_simd128 = sse && sse2 && sse3 && sse41 && sse42 && cmov;
#else
@@ -1611,7 +1612,7 @@ hmacmodule_init_cpu_features(hmacmodule_state *state)
state->can_run_simd128 = false;
#endif
-#if HACL_CAN_COMPILE_SIMD256
+#if _Py_HACL_CAN_COMPILE_VEC256
// TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection
state->can_run_simd256 = state->can_run_simd128 && avx && avx2;
#else
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index bbbb4911568..033de0b2907 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1233,6 +1233,23 @@ FUNC2(remainder, m_remainder,
"Return x - n*y where n*y is the closest integer multiple of y.\n"
"In the case where x is exactly halfway between two multiples of\n"
"y, the nearest even value of n is used. The result is always exact.")
+
+/*[clinic input]
+math.signbit
+
+ x: double
+ /
+
+Return True if the sign of x is negative and False otherwise.
+[clinic start generated code]*/
+
+static PyObject *
+math_signbit_impl(PyObject *module, double x)
+/*[clinic end generated code: output=20c5f20156a9b871 input=3d3493fbcb5bdb3e]*/
+{
+ return PyBool_FromLong(signbit(x));
+}
+
FUNC1D(sin, sin, 0,
"sin($module, x, /)\n--\n\n"
"Return the sine of x (measured in radians).",
@@ -3148,7 +3165,7 @@ static PyObject *
math_issubnormal_impl(PyObject *module, double x)
/*[clinic end generated code: output=4e76ac98ddcae761 input=9a20aba7107d0d95]*/
{
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
return PyBool_FromLong(issubnormal(x));
#else
return PyBool_FromLong(isfinite(x) && x && !isnormal(x));
@@ -4199,6 +4216,7 @@ static PyMethodDef math_methods[] = {
MATH_POW_METHODDEF
MATH_RADIANS_METHODDEF
{"remainder", _PyCFunction_CAST(math_remainder), METH_FASTCALL, math_remainder_doc},
+ MATH_SIGNBIT_METHODDEF
{"sin", math_sin, METH_O, math_sin_doc},
{"sinh", math_sinh, METH_O, math_sinh_doc},
{"sqrt", math_sqrt, METH_O, math_sqrt_doc},
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 7dc5ef39a56..b570f81b7cf 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -685,7 +685,8 @@ static void
reset_remotedebug_data(PyThreadState *tstate)
{
tstate->remote_debugger_support.debugger_pending_call = 0;
- memset(tstate->remote_debugger_support.debugger_script_path, 0, MAX_SCRIPT_PATH_SIZE);
+ memset(tstate->remote_debugger_support.debugger_script_path, 0,
+ Py_MAX_SCRIPT_PATH_SIZE);
}
diff --git a/Modules/sha3module.c b/Modules/sha3module.c
index face90a6094..5764556bb68 100644
--- a/Modules/sha3module.c
+++ b/Modules/sha3module.c
@@ -239,16 +239,17 @@ SHA3_traverse(PyObject *self, visitproc visit, void *arg)
/*[clinic input]
_sha3.sha3_224.copy
+ cls: defining_class
+
Return a copy of the hash object.
[clinic start generated code]*/
static PyObject *
-_sha3_sha3_224_copy_impl(SHA3object *self)
-/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/
+_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls)
+/*[clinic end generated code: output=13958b44c244013e input=7134b4dc0a2fbcac]*/
{
SHA3object *newobj;
-
- if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) {
+ if ((newobj = newSHA3object(cls)) == NULL) {
return NULL;
}
HASHLIB_ACQUIRE_LOCK(self);