Skip to content

Commit 13bb4c8

Browse files
authored
Merge pull request #737 from wedsonaf/factory
rust: split `CreatableLock` into `LockFactory` and `LockIniter`
2 parents d05946b + a486f47 commit 13bb4c8

File tree

7 files changed

+63
-49
lines changed

7 files changed

+63
-49
lines changed

rust/kernel/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ mod spinlock;
3636

3737
pub use arc::{Ref, RefBorrow, UniqueRef};
3838
pub use condvar::CondVar;
39-
pub use guard::{CreatableLock, Guard, Lock, LockInfo, ReadLock, WriteLock};
39+
pub use guard::{Guard, Lock, LockFactory, LockInfo, LockIniter, ReadLock, WriteLock};
4040
pub use locked_by::LockedBy;
4141
pub use mutex::Mutex;
4242
pub use revocable_mutex::{RevocableMutex, RevocableMutexGuard};

rust/kernel/sync/guard.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,22 @@ pub unsafe trait Lock<I: LockInfo = WriteLock> {
128128
fn locked_data(&self) -> &core::cell::UnsafeCell<Self::Inner>;
129129
}
130130

131-
/// A generic mutual exclusion primitive that can be instantiated generically.
132-
pub trait CreatableLock {
133-
/// The type of the argument passed to [`CreatableLock::new_lock`].
134-
type CreateArgType: ?Sized;
131+
/// A creator of instances of a mutual exclusion (lock) primitive.
132+
pub trait LockFactory {
133+
/// The parametrised type of the mutual exclusion primitive that can be created by this factory.
134+
type LockedType<T>;
135135

136-
/// Constructs a new instance of the lock.
136+
/// Constructs a new instance of the mutual exclusion primitive.
137137
///
138138
/// # Safety
139139
///
140-
/// The caller must call [`CreatableLock::init_lock`] before using the lock.
141-
unsafe fn new_lock(data: Self::CreateArgType) -> Self;
140+
/// The caller must call [`LockIniter::init_lock`] before using the lock.
141+
unsafe fn new_lock<T>(data: T) -> Self::LockedType<T>;
142+
}
142143

143-
/// Initialises the lock type instance so that it can be safely used.
144+
/// A lock that can be initialised with a single lock class key.
145+
pub trait LockIniter {
146+
/// Initialises the lock instance so that it can be safely used.
144147
///
145148
/// # Safety
146149
///
@@ -153,7 +156,7 @@ pub trait CreatableLock {
153156
);
154157
}
155158

156-
impl<L: CreatableLock> NeedsLockClass for L {
159+
impl<L: LockIniter> NeedsLockClass for L {
157160
unsafe fn init(
158161
self: Pin<&mut Self>,
159162
name: &'static CStr,

rust/kernel/sync/mutex.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! This module allows Rust code to use the kernel's [`struct mutex`].
66
7-
use super::{CreatableLock, Guard, Lock};
7+
use super::{Guard, Lock, LockFactory, LockIniter};
88
use crate::{bindings, str::CStr, Opaque};
99
use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
1010

@@ -72,14 +72,16 @@ impl<T: ?Sized> Mutex<T> {
7272
}
7373
}
7474

75-
impl<T> CreatableLock for Mutex<T> {
76-
type CreateArgType = T;
75+
impl<T> LockFactory for Mutex<T> {
76+
type LockedType<U> = Mutex<U>;
7777

78-
unsafe fn new_lock(data: Self::CreateArgType) -> Self {
78+
unsafe fn new_lock<U>(data: U) -> Mutex<U> {
7979
// SAFETY: The safety requirements of `new_lock` also require that `init_lock` be called.
80-
unsafe { Self::new(data) }
80+
unsafe { Mutex::new(data) }
8181
}
82+
}
8283

84+
impl<T> LockIniter for Mutex<T> {
8385
unsafe fn init_lock(
8486
self: Pin<&mut Self>,
8587
name: &'static CStr,

rust/kernel/sync/rwsem.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! C header: [`include/linux/rwsem.h`](../../../../include/linux/rwsem.h)
88
9-
use super::{mutex::EmptyGuardContext, CreatableLock, Guard, Lock, ReadLock};
9+
use super::{mutex::EmptyGuardContext, Guard, Lock, LockFactory, LockIniter, ReadLock};
1010
use crate::{bindings, str::CStr, Opaque};
1111
use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
1212

@@ -85,14 +85,16 @@ impl<T: ?Sized> RwSemaphore<T> {
8585
}
8686
}
8787

88-
impl<T> CreatableLock for RwSemaphore<T> {
89-
type CreateArgType = T;
88+
impl<T> LockFactory for RwSemaphore<T> {
89+
type LockedType<U> = RwSemaphore<U>;
9090

91-
unsafe fn new_lock(data: Self::CreateArgType) -> Self {
91+
unsafe fn new_lock<U>(data: U) -> RwSemaphore<U> {
9292
// SAFETY: The safety requirements of `new_lock` also require that `init_lock` be called.
93-
unsafe { Self::new(data) }
93+
unsafe { RwSemaphore::new(data) }
9494
}
95+
}
9596

97+
impl<T> LockIniter for RwSemaphore<T> {
9698
unsafe fn init_lock(
9799
self: Pin<&mut Self>,
98100
name: &'static CStr,

rust/kernel/sync/seqlock.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
//! A kernel sequential lock (seqlock).
44
//!
55
//! This module allows Rust code to use the sequential locks based on the kernel's `seqcount_t` and
6-
//! any locks implementing the [`CreatableLock`] trait.
6+
//! any locks implementing the [`LockFactory`] trait.
77
//!
88
//! See <https://www.kernel.org/doc/Documentation/locking/seqlock.rst>.
99
10-
use super::{CreatableLock, Guard, Lock, NeedsLockClass, ReadLock};
10+
use super::{Guard, Lock, LockFactory, LockIniter, NeedsLockClass, ReadLock};
1111
use crate::{bindings, str::CStr, Opaque};
1212
use core::{cell::UnsafeCell, marker::PhantomPinned, ops::Deref, pin::Pin};
1313

1414
/// Exposes sequential locks backed by the kernel's `seqcount_t`.
1515
///
16-
/// The write-side critical section is protected by a lock implementing the `CreatableLock` trait.
16+
/// The write-side critical section is protected by a lock implementing the [`LockFactory`] trait.
1717
///
1818
/// # Examples
1919
///
@@ -52,7 +52,7 @@ use core::{cell::UnsafeCell, marker::PhantomPinned, ops::Deref, pin::Pin};
5252
/// guard.b.store(b + 1, Ordering::Relaxed);
5353
/// }
5454
/// ```
55-
pub struct SeqLock<L: CreatableLock + Lock + ?Sized> {
55+
pub struct SeqLock<L: Lock + ?Sized> {
5656
_p: PhantomPinned,
5757
count: Opaque<bindings::seqcount>,
5858
write_lock: L,
@@ -61,21 +61,22 @@ pub struct SeqLock<L: CreatableLock + Lock + ?Sized> {
6161
// SAFETY: `SeqLock` can be transferred across thread boundaries iff the data it protects and the
6262
// underlying lock can.
6363
#[allow(clippy::non_send_fields_in_send_ty)]
64-
unsafe impl<L: CreatableLock + Lock + Send> Send for SeqLock<L> where L::Inner: Send {}
64+
unsafe impl<L: Lock + Send> Send for SeqLock<L> where L::Inner: Send {}
6565

6666
// SAFETY: `SeqLock` allows concurrent access to the data it protects by both readers and writers,
6767
// so it requires that the data it protects be `Sync`, as well as the underlying lock.
68-
unsafe impl<L: CreatableLock + Lock + Sync> Sync for SeqLock<L> where L::Inner: Sync {}
68+
unsafe impl<L: Lock + Sync> Sync for SeqLock<L> where L::Inner: Sync {}
6969

70-
impl<L: CreatableLock + Lock> SeqLock<L> {
70+
impl<L: Lock> SeqLock<L> {
7171
/// Constructs a new instance of [`SeqLock`].
7272
///
7373
/// # Safety
7474
///
7575
/// The caller must call [`SeqLock::init`] before using the seqlock.
76-
pub unsafe fn new(data: L::CreateArgType) -> Self
76+
pub unsafe fn new(data: L::Inner) -> Self
7777
where
78-
L::CreateArgType: Sized,
78+
L: LockFactory<LockedType<L::Inner> = L>,
79+
L::Inner: Sized,
7980
{
8081
Self {
8182
_p: PhantomPinned,
@@ -87,7 +88,7 @@ impl<L: CreatableLock + Lock> SeqLock<L> {
8788
}
8889
}
8990

90-
impl<L: CreatableLock + Lock + ?Sized> SeqLock<L> {
91+
impl<L: Lock + ?Sized> SeqLock<L> {
9192
/// Accesses the protected data in read mode.
9293
///
9394
/// Readers and writers are allowed to run concurrently, so callers must check if they need to
@@ -129,7 +130,7 @@ impl<L: CreatableLock + Lock + ?Sized> SeqLock<L> {
129130
}
130131
}
131132

132-
impl<L: CreatableLock + Lock + ?Sized> NeedsLockClass for SeqLock<L> {
133+
impl<L: LockIniter + Lock + ?Sized> NeedsLockClass for SeqLock<L> {
133134
unsafe fn init(
134135
mut self: Pin<&mut Self>,
135136
name: &'static CStr,
@@ -146,7 +147,7 @@ impl<L: CreatableLock + Lock + ?Sized> NeedsLockClass for SeqLock<L> {
146147
}
147148

148149
// SAFETY: The underlying lock ensures mutual exclusion.
149-
unsafe impl<L: CreatableLock + Lock + ?Sized> Lock<ReadLock> for SeqLock<L> {
150+
unsafe impl<L: Lock + ?Sized> Lock<ReadLock> for SeqLock<L> {
150151
type Inner = L::Inner;
151152
type GuardContext = L::GuardContext;
152153

@@ -176,12 +177,12 @@ unsafe impl<L: CreatableLock + Lock + ?Sized> Lock<ReadLock> for SeqLock<L> {
176177
}
177178

178179
/// Allows read-side access to data protected by a sequential lock.
179-
pub struct SeqLockReadGuard<'a, L: CreatableLock + Lock + ?Sized> {
180+
pub struct SeqLockReadGuard<'a, L: Lock + ?Sized> {
180181
lock: &'a SeqLock<L>,
181182
start_count: u32,
182183
}
183184

184-
impl<L: CreatableLock + Lock + ?Sized> SeqLockReadGuard<'_, L> {
185+
impl<L: Lock + ?Sized> SeqLockReadGuard<'_, L> {
185186
/// Determine if the callers needs to retry reading values.
186187
///
187188
/// It returns `true` when a concurrent writer ran between the guard being created and
@@ -192,7 +193,7 @@ impl<L: CreatableLock + Lock + ?Sized> SeqLockReadGuard<'_, L> {
192193
}
193194
}
194195

195-
impl<L: CreatableLock + Lock + ?Sized> Deref for SeqLockReadGuard<'_, L> {
196+
impl<L: Lock + ?Sized> Deref for SeqLockReadGuard<'_, L> {
196197
type Target = L::Inner;
197198

198199
fn deref(&self) -> &Self::Target {

rust/kernel/sync/smutex.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
//! When the waiter queue is non-empty, unlocking the mutex always results in the first waiter being
4747
//! popped form the queue and awakened.
4848
49-
use super::{mutex::EmptyGuardContext, CreatableLock, Guard, Lock};
49+
use super::{mutex::EmptyGuardContext, Guard, Lock, LockFactory, LockIniter};
5050
use crate::{bindings, str::CStr, Opaque};
5151
use core::sync::atomic::{AtomicUsize, Ordering};
5252
use core::{cell::UnsafeCell, pin::Pin};
@@ -134,13 +134,15 @@ impl<T: ?Sized> Mutex<T> {
134134
}
135135
}
136136

137-
impl<T> CreatableLock for Mutex<T> {
138-
type CreateArgType = T;
137+
impl<T> LockFactory for Mutex<T> {
138+
type LockedType<U> = Mutex<U>;
139139

140-
unsafe fn new_lock(data: Self::CreateArgType) -> Self {
141-
Self::new(data)
140+
unsafe fn new_lock<U>(data: U) -> Mutex<U> {
141+
Mutex::new(data)
142142
}
143+
}
143144

145+
impl<T> LockIniter for Mutex<T> {
144146
unsafe fn init_lock(
145147
self: Pin<&mut Self>,
146148
_name: &'static CStr,

rust/kernel/sync/spinlock.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! See <https://www.kernel.org/doc/Documentation/locking/spinlocks.txt>.
88
9-
use super::{mutex::EmptyGuardContext, CreatableLock, Guard, Lock, LockInfo, WriteLock};
9+
use super::{mutex::EmptyGuardContext, Guard, Lock, LockFactory, LockInfo, LockIniter, WriteLock};
1010
use crate::{bindings, c_types, str::CStr, Opaque, True};
1111
use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin};
1212

@@ -125,14 +125,16 @@ impl<T: ?Sized> SpinLock<T> {
125125
}
126126
}
127127

128-
impl<T> CreatableLock for SpinLock<T> {
129-
type CreateArgType = T;
128+
impl<T> LockFactory for SpinLock<T> {
129+
type LockedType<U> = SpinLock<U>;
130130

131-
unsafe fn new_lock(data: Self::CreateArgType) -> Self {
131+
unsafe fn new_lock<U>(data: U) -> SpinLock<U> {
132132
// SAFETY: The safety requirements of `new_lock` also require that `init_lock` be called.
133-
unsafe { Self::new(data) }
133+
unsafe { SpinLock::new(data) }
134134
}
135+
}
135136

137+
impl<T> LockIniter for SpinLock<T> {
136138
unsafe fn init_lock(
137139
self: Pin<&mut Self>,
138140
name: &'static CStr,
@@ -294,14 +296,16 @@ impl<T: ?Sized> RawSpinLock<T> {
294296
}
295297
}
296298

297-
impl<T> CreatableLock for RawSpinLock<T> {
298-
type CreateArgType = T;
299+
impl<T> LockFactory for RawSpinLock<T> {
300+
type LockedType<U> = RawSpinLock<U>;
299301

300-
unsafe fn new_lock(data: Self::CreateArgType) -> Self {
302+
unsafe fn new_lock<U>(data: U) -> RawSpinLock<U> {
301303
// SAFETY: The safety requirements of `new_lock` also require that `init_lock` be called.
302-
unsafe { Self::new(data) }
304+
unsafe { RawSpinLock::new(data) }
303305
}
306+
}
304307

308+
impl<T> LockIniter for RawSpinLock<T> {
305309
unsafe fn init_lock(
306310
self: Pin<&mut Self>,
307311
name: &'static CStr,

0 commit comments

Comments
 (0)