From 18a16ad9563dce8cda802525c8937866c129082d Mon Sep 17 00:00:00 2001 From: Jarred Nicholls Date: Thu, 2 Dec 2021 20:18:21 -0500 Subject: [PATCH] Support building solana-program on 32-bit architectures that do not (#21577) have 64-bit atomics by using a Mutex on 32-bit architectures. Currently the usage of atomics are only in functions that support tests and benchmarks. --- Cargo.lock | 1 + programs/bpf/Cargo.lock | 1 + sdk/program/Cargo.toml | 5 ++++- sdk/program/src/atomic_u64.rs | 38 +++++++++++++++++++++++++++++++++++ sdk/program/src/blake3.rs | 4 ++-- sdk/program/src/hash.rs | 4 ++-- sdk/program/src/keccak.rs | 4 ++-- sdk/program/src/lib.rs | 1 + sdk/program/src/pubkey.rs | 4 ++-- 9 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 sdk/program/src/atomic_u64.rs diff --git a/Cargo.lock b/Cargo.lock index e8b18316bf..ceb63ee7f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5346,6 +5346,7 @@ dependencies = [ "log 0.4.14", "num-derive", "num-traits", + "parking_lot 0.11.2", "rand 0.7.3", "rustc_version 0.4.0", "rustversion", diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index efd67fb6e9..5ebba4f178 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -3188,6 +3188,7 @@ dependencies = [ "log", "num-derive", "num-traits", + "parking_lot", "rand 0.7.3", "rustc_version 0.4.0", "rustversion", diff --git a/sdk/program/Cargo.toml b/sdk/program/Cargo.toml index 3b9e984249..566162c9e3 100644 --- a/sdk/program/Cargo.toml +++ b/sdk/program/Cargo.toml @@ -19,7 +19,7 @@ bs58 = "0.4.0" bytemuck = { version = "1.7.2", features = ["derive"] } bv = { version = "0.11.1", features = ["serde"] } hex = "0.4.2" -itertools = "0.10.1" +itertools = "0.10.1" lazy_static = "1.4.0" log = "0.4.14" num-derive = "0.3" @@ -44,6 +44,9 @@ rand = "0.7.0" solana-logger = { path = "../../logger", version = "=1.9.0" } itertools = "0.10.1" +[target.'cfg(not(target_pointer_width = "64"))'.dependencies] +parking_lot = "0.11" + [dev-dependencies] static_assertions = "1.1.0" assert_matches = "1.3.0" diff --git a/sdk/program/src/atomic_u64.rs b/sdk/program/src/atomic_u64.rs new file mode 100644 index 0000000000..ea8695d0b5 --- /dev/null +++ b/sdk/program/src/atomic_u64.rs @@ -0,0 +1,38 @@ +pub(crate) use implementation::AtomicU64; + +#[cfg(target_pointer_width = "64")] +mod implementation { + use std::sync::atomic; + + pub(crate) struct AtomicU64(atomic::AtomicU64); + + impl AtomicU64 { + pub(crate) const fn new(initial: u64) -> Self { + Self(atomic::AtomicU64::new(initial)) + } + + pub(crate) fn fetch_add(&self, v: u64) -> u64 { + self.0.fetch_add(v, atomic::Ordering::Relaxed) + } + } +} + +#[cfg(not(target_pointer_width = "64"))] +mod implementation { + use parking_lot::{const_mutex, Mutex}; + + pub(crate) struct AtomicU64(Mutex); + + impl AtomicU64 { + pub(crate) const fn new(initial: u64) -> Self { + Self(const_mutex(initial)) + } + + pub(crate) fn fetch_add(&self, v: u64) -> u64 { + let mut lock = self.0.lock(); + let i = *lock; + *lock = i + v; + i + } + } +} diff --git a/sdk/program/src/blake3.rs b/sdk/program/src/blake3.rs index d09da7d4af..de219953cb 100644 --- a/sdk/program/src/blake3.rs +++ b/sdk/program/src/blake3.rs @@ -103,11 +103,11 @@ impl Hash { /// unique Hash for tests and benchmarks. pub fn new_unique() -> Self { - use std::sync::atomic::{AtomicU64, Ordering}; + use crate::atomic_u64::AtomicU64; static I: AtomicU64 = AtomicU64::new(1); let mut b = [0u8; HASH_BYTES]; - let i = I.fetch_add(1, Ordering::Relaxed); + let i = I.fetch_add(1); b[0..8].copy_from_slice(&i.to_le_bytes()); Self::new(&b) } diff --git a/sdk/program/src/hash.rs b/sdk/program/src/hash.rs index f79bf004cc..b4f707ef89 100644 --- a/sdk/program/src/hash.rs +++ b/sdk/program/src/hash.rs @@ -106,11 +106,11 @@ impl Hash { /// unique Hash for tests and benchmarks. pub fn new_unique() -> Self { - use std::sync::atomic::{AtomicU64, Ordering}; + use crate::atomic_u64::AtomicU64; static I: AtomicU64 = AtomicU64::new(1); let mut b = [0u8; HASH_BYTES]; - let i = I.fetch_add(1, Ordering::Relaxed); + let i = I.fetch_add(1); b[0..8].copy_from_slice(&i.to_le_bytes()); Self::new(&b) } diff --git a/sdk/program/src/keccak.rs b/sdk/program/src/keccak.rs index b3df920f15..99db669b43 100644 --- a/sdk/program/src/keccak.rs +++ b/sdk/program/src/keccak.rs @@ -104,11 +104,11 @@ impl Hash { /// unique Hash for tests and benchmarks. pub fn new_unique() -> Self { - use std::sync::atomic::{AtomicU64, Ordering}; + use crate::atomic_u64::AtomicU64; static I: AtomicU64 = AtomicU64::new(1); let mut b = [0u8; HASH_BYTES]; - let i = I.fetch_add(1, Ordering::Relaxed); + let i = I.fetch_add(1); b[0..8].copy_from_slice(&i.to_le_bytes()); Self::new(&b) } diff --git a/sdk/program/src/lib.rs b/sdk/program/src/lib.rs index d5a174c8a0..5914aa842b 100644 --- a/sdk/program/src/lib.rs +++ b/sdk/program/src/lib.rs @@ -6,6 +6,7 @@ extern crate self as solana_program; pub mod account_info; +pub(crate) mod atomic_u64; pub mod blake3; pub mod borsh; pub mod bpf_loader; diff --git a/sdk/program/src/pubkey.rs b/sdk/program/src/pubkey.rs index fc1c90ec84..764a1aabbe 100644 --- a/sdk/program/src/pubkey.rs +++ b/sdk/program/src/pubkey.rs @@ -148,11 +148,11 @@ impl Pubkey { /// unique Pubkey for tests and benchmarks. pub fn new_unique() -> Self { - use std::sync::atomic::{AtomicU64, Ordering}; + use crate::atomic_u64::AtomicU64; static I: AtomicU64 = AtomicU64::new(1); let mut b = [0u8; 32]; - let i = I.fetch_add(1, Ordering::Relaxed); + let i = I.fetch_add(1); b[0..8].copy_from_slice(&i.to_le_bytes()); Self::new(&b) }