From dee45d36440988c7131c8cd22f27cac61afec28c Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Mon, 22 May 2023 11:31:20 +0900 Subject: [PATCH 1/2] Use a const initializer for `GIL_COUNT` if possible. --- pyo3-build-config/src/lib.rs | 5 +++++ src/gil.rs | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs index 9bcaf34e..f870daa7 100644 --- a/pyo3-build-config/src/lib.rs +++ b/pyo3-build-config/src/lib.rs @@ -156,6 +156,11 @@ pub fn print_feature_cfgs() { if rustc_minor_version >= 53 { println!("cargo:rustc-cfg=option_insert"); } + + // Enable use of const initializer for thread_local! on Rust 1.59 and greater + if rustc_minor_version >= 59 { + println!("cargo:rustc-cfg=thread_local_const_init"); + } } /// Private exports used in PyO3's build.rs diff --git a/src/gil.rs b/src/gil.rs index aa4ed2e7..c2316524 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -10,15 +10,29 @@ use std::{mem, ptr::NonNull, sync::atomic}; static START: Once = Once::new(); -thread_local! { +cfg_if::cfg_if! { + if #[cfg(thread_local_const_init)] { + use std::thread_local as thread_local_const_init; + } else { + macro_rules! thread_local_const_init { + ($(#[$attr:meta])* static $name:ident: $ty:ty = const { $init:expr };) => ( + thread_local! { $(#[$attr])* static $name: $ty = $init; } + ) + } + } +} + +thread_local_const_init! { /// This is an internal counter in pyo3 monitoring whether this thread has the GIL. /// /// It will be incremented whenever a GILGuard or GILPool is created, and decremented whenever /// they are dropped. /// /// As a result, if this thread has the GIL, GIL_COUNT is greater than zero. - static GIL_COUNT: Cell = Cell::new(0); + static GIL_COUNT: Cell = const { Cell::new(0) }; +} +thread_local! { /// Temporarily hold objects that will be released when the GILPool drops. static OWNED_OBJECTS: RefCell>> = RefCell::new(Vec::with_capacity(256)); } From 291fc36d0c6a62acfceb58255b3d5da11e1dfb55 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Wed, 24 May 2023 10:42:07 +0900 Subject: [PATCH 2/2] Use a const initializer for `OWNED_OBJECTS` if possible. Since `Vec::with_capacity` is not a const function, it now does not allocate any initial memory. --- src/gil.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gil.rs b/src/gil.rs index c2316524..7f7c1f4e 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -15,8 +15,8 @@ cfg_if::cfg_if! { use std::thread_local as thread_local_const_init; } else { macro_rules! thread_local_const_init { - ($(#[$attr:meta])* static $name:ident: $ty:ty = const { $init:expr };) => ( - thread_local! { $(#[$attr])* static $name: $ty = $init; } + ($($(#[$attr:meta])* static $name:ident: $ty:ty = const { $init:expr };)*) => ( + thread_local! { $($(#[$attr])* static $name: $ty = $init;)* } ) } } @@ -30,11 +30,9 @@ thread_local_const_init! { /// /// As a result, if this thread has the GIL, GIL_COUNT is greater than zero. static GIL_COUNT: Cell = const { Cell::new(0) }; -} -thread_local! { /// Temporarily hold objects that will be released when the GILPool drops. - static OWNED_OBJECTS: RefCell>> = RefCell::new(Vec::with_capacity(256)); + static OWNED_OBJECTS: RefCell>> = const { RefCell::new(Vec::new()) }; } /// Checks whether the GIL is acquired.