kernel: futex 64-shard hash table (Phase 0c, plan order #1)
Re-apply P6-futex-sharding.patch from local/patches/kernel/ to the local fork. Replaces the single global Mutex<L1, FutexList> with a 64-shard hash table to eliminate contention between futex operations on different addresses (different cores no longer serialize on one lock). src/syscall/futex.rs: static FUTEXES changes from a single Mutex<L1, FutexList> to a [Mutex<L1, Shard>; 64] array indexed by hash of the physical address. This is the foundation patch for Phase 1 (Futex Completeness). All later futex work (REQUEUE, PI, robust, WAKE_OP) depends on the sharding being present. The Cargo.lock diff is the expected dep resolution update. Multi-threading plan Phase 0c, plan order #1 (P6-futex-sharding).
This commit is contained in:
Generated
+4
-1
@@ -202,7 +202,6 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.8.1"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#79cb6d9057642be31623677458a93aa88145864f"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
]
|
||||
@@ -418,3 +417,7 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[patch.unused]]
|
||||
name = "libredox"
|
||||
version = "0.1.17"
|
||||
|
||||
+10
-4
@@ -49,8 +49,13 @@ pub struct FutexEntry {
|
||||
// implement that fully in userspace. Although futex is probably the best API for process-shared
|
||||
// POSIX synchronization primitives, a local hash table and wait-for-thread kernel APIs (e.g.
|
||||
// lwp_park/lwp_unpark from NetBSD) could be a simpler replacement.
|
||||
static FUTEXES: Mutex<L1, FutexList> =
|
||||
Mutex::new(FutexList::with_hasher(DefaultHashBuilder::new()));
|
||||
const FUTEX_SHARDS: usize = 64;
|
||||
|
||||
fn futex_shard(phys: PhysicalAddress) -> usize {
|
||||
(phys.data() as usize >> 12) % FUTEX_SHARDS
|
||||
}
|
||||
|
||||
static FUTEXES: [Mutex<L1, FutexList>; FUTEX_SHARDS] = [const { Mutex::new(FutexList::with_hasher(DefaultHashBuilder::new())) }; FUTEX_SHARDS];
|
||||
|
||||
fn validate_and_translate_virt(space: &AddrSpace, addr: VirtualAddress) -> Option<PhysicalAddress> {
|
||||
// TODO: Move this elsewhere!
|
||||
@@ -97,7 +102,7 @@ pub fn futex(
|
||||
{
|
||||
// TODO: Lock ordering violation
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
let mut futexes = FUTEXES.lock(token.token());
|
||||
let mut futexes = FUTEXES[futex_shard(target_physaddr)].lock(token.token());
|
||||
let (futexes, mut token) = futexes.token_split();
|
||||
|
||||
let (fetched, expected) = if op == FUTEX_WAIT {
|
||||
@@ -181,10 +186,11 @@ pub fn futex(
|
||||
}
|
||||
FUTEX_WAKE => {
|
||||
let mut woken = 0;
|
||||
let shard = futex_shard(target_physaddr);
|
||||
|
||||
{
|
||||
drop(addr_space_guard);
|
||||
let mut futexes_map = FUTEXES.lock(token.token());
|
||||
let mut futexes_map = FUTEXES[shard].lock(token.token());
|
||||
let (futexes_map, mut token) = futexes_map.token_split();
|
||||
|
||||
let is_empty = if let Some(futexes) = futexes_map.get_mut(&target_physaddr) {
|
||||
|
||||
Reference in New Issue
Block a user