You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mutexes are mostly used for static variables, and also a lot of times the variable needs to be initialized later.
The current Mutex implementation doesn't feel very ergonomic:
to allow mutable access + late initialization to a variable, we need to use Mutex<RefCell<Option<T>>> with var.borrow(cs).borrow_mut().replace(value) for initialization and var.borrow(cs).borrow_mut().as_mut().unwrap() for mutable access. These are very long expressions for simple purposes.
RefCell comes with an extra isize 32bit space with Option adding another u8 4bit overhead. Each time accessing a mutable reference to a variable basically involves two unwraps, once for checking uniqueness and once for checking initialization, which is unnecessary.
I am thinking of an easier to use + more efficient implementation:
We can use a single enum to keep track of the state of the mutex cell. So the value can be
uninitialized (None),
locked (borrowed),
unlock (free to borrow).
enumMutexInnerState{Locked,Uinit,Unlock,}
The mutex can be either initialized with a value or not.
impl<T>Mutex<T>{/// Creates a new mutex.pubconstfnnew(value:T) -> Self{Self(UnsafeCell::new(MutexInner{state:MutexInnerState::Unlock,value:MaybeUninit::new(value),}))}/// Creates a new unit mutex.pubconstfnnew_uinit() -> Self{Self(UnsafeCell::new(MutexInner{state:MutexInnerState::Uinit,value:MaybeUninit::uninit(),}))}}
Value can be initialized once if it was not initialized (otherwise panic).
impl<T>Mutex<T>{/// Value initialization.////// panic if already initialized.pubfninit<'cs>(&'csself,_cs:&'csCriticalSection,value:T){let inner = unsafe{&mut*self.0.get()};ifletMutexInnerState::Uinit = inner.state{
inner.state = MutexInnerState::Unlock;
inner.value = MaybeUninit::new(value);}else{panic!()}}}
Locking the mutex returns None if try_lock fails or if the value is uninitialized.
Of course we should not use the name Mutex directly since we need to have backward compatibility. I am thinking of naming it MutexCell or perhaps MutexOption. If anyone finds it useful maybe we can PR it into the library.
The text was updated successfully, but these errors were encountered:
Mutexes are mostly used for static variables, and also a lot of times the variable needs to be initialized later.
The current Mutex implementation doesn't feel very ergonomic:
Mutex<RefCell<Option<T>>>
withvar.borrow(cs).borrow_mut().replace(value)
for initialization andvar.borrow(cs).borrow_mut().as_mut().unwrap()
for mutable access. These are very long expressions for simple purposes.RefCell
comes with an extraisize
32bit space withOption
adding anotheru8
4bit overhead. Each time accessing a mutable reference to a variable basically involves twounwraps
, once for checking uniqueness and once for checking initialization, which is unnecessary.I am thinking of an easier to use + more efficient implementation:
We can use a single enum to keep track of the state of the mutex cell. So the value can be
None
),The mutex can be either initialized with a value or not.
Value can be initialized once if it was not initialized (otherwise panic).
Locking the mutex returns None if
try_lock
fails or if the value is uninitialized.The LockGuard restore lock state back to
Unlock
on drop.Miscellaneous.
Usage
Now we can write like
Of course we should not use the name
Mutex
directly since we need to have backward compatibility. I am thinking of naming itMutexCell
or perhapsMutexOption
. If anyone finds it useful maybe we can PR it into the library.The text was updated successfully, but these errors were encountered: