@@ -49,6 +49,20 @@ impl<T> Lock<T> {
4949 self . 0 . try_borrow_mut ( ) . ok ( )
5050 }
5151
52+ #[ inline( always) ]
53+ #[ track_caller]
54+ // This is unsafe to match the API for the `parallel_compiler` case.
55+ pub unsafe fn lock_assume_no_sync ( & self ) -> LockGuard < ' _ , T > {
56+ self . 0 . borrow_mut ( )
57+ }
58+
59+ #[ inline( always) ]
60+ #[ track_caller]
61+ // This is unsafe to match the API for the `parallel_compiler` case.
62+ pub unsafe fn lock_assume_sync ( & self ) -> LockGuard < ' _ , T > {
63+ self . 0 . borrow_mut ( )
64+ }
65+
5266 #[ inline( always) ]
5367 #[ track_caller]
5468 pub fn lock ( & self ) -> LockGuard < ' _ , T > {
@@ -150,24 +164,45 @@ impl LockRaw {
150164
151165 #[ inline( always) ]
152166 fn lock ( & self ) {
153- if super :: ERROR_CHECKING {
154- // We're in the debugging mode, so assert that the lock is not held so we
155- // get a panic instead of waiting for the lock.
156- assert_eq ! ( self . try_lock( ) , true , "lock must not be hold" ) ;
157- } else {
158- // SAFETY: This is safe since the union fields are used in accordance with `self.sync`.
159- unsafe {
160- if likely ( !self . sync ) {
161- if unlikely ( self . opt . cell . replace ( true ) ) {
162- cold_path ( || panic ! ( "lock was already held" ) )
163- }
164- } else {
165- self . opt . lock . lock ( ) ;
166- }
167+ // SAFETY: This is safe since `self.sync` is used in accordance with the preconditions of
168+ // `lock_assume_no_sync` and `lock_assume_sync`.
169+ unsafe {
170+ if likely ( !self . sync ) {
171+ self . lock_assume_no_sync ( )
172+ } else {
173+ self . lock_assume_sync ( ) ;
174+ }
175+ }
176+ }
177+
178+ /// This acquires the lock assuming no syncronization is required.
179+ ///
180+ /// Safety
181+ /// This method must only be called if `might_be_dyn_thread_safe` was false on lock creation.
182+ #[ inline( always) ]
183+ unsafe fn lock_assume_no_sync ( & self ) {
184+ // SAFETY: This is safe since `self.opt.cell` is the union field used due to the
185+ // precondition on this function.
186+ unsafe {
187+ if unlikely ( self . opt . cell . replace ( true ) ) {
188+ cold_path ( || panic ! ( "lock was already held" ) )
167189 }
168190 }
169191 }
170192
193+ /// This acquires the lock assuming syncronization is required.
194+ ///
195+ /// Safety
196+ /// This method must only be called if `might_be_dyn_thread_safe` was true on lock creation.
197+ #[ inline( always) ]
198+ unsafe fn lock_assume_sync ( & self ) {
199+ // SAFETY: This is safe since `self.opt.lock` is the union field used due to the
200+ // precondition on this function.
201+ unsafe {
202+ self . opt . lock . lock ( ) ;
203+ }
204+ }
205+
171206 /// This unlocks the lock.
172207 ///
173208 /// Safety
@@ -217,6 +252,30 @@ impl<T> Lock<T> {
217252 if self . raw . try_lock ( ) { Some ( LockGuard { lock : self , marker : PhantomData } ) } else { None }
218253 }
219254
255+ /// This acquires the lock assuming no syncronization is required.
256+ ///
257+ /// Safety
258+ /// This method must only be called if `might_be_dyn_thread_safe` was false on lock creation.
259+ #[ inline( always) ]
260+ pub ( crate ) unsafe fn lock_assume_no_sync ( & self ) -> LockGuard < ' _ , T > {
261+ unsafe {
262+ self . raw . lock_assume_no_sync ( ) ;
263+ }
264+ LockGuard { lock : self , marker : PhantomData }
265+ }
266+
267+ /// This acquires the lock assuming syncronization is required.
268+ ///
269+ /// Safety
270+ /// This method must only be called if `might_be_dyn_thread_safe` was true on lock creation.
271+ #[ inline( always) ]
272+ pub ( crate ) unsafe fn lock_assume_sync ( & self ) -> LockGuard < ' _ , T > {
273+ unsafe {
274+ self . raw . lock_assume_sync ( ) ;
275+ }
276+ LockGuard { lock : self , marker : PhantomData }
277+ }
278+
220279 #[ inline( always) ]
221280 pub fn lock ( & self ) -> LockGuard < ' _ , T > {
222281 self . raw . lock ( ) ;
0 commit comments