9
9
//! [`object`]: crate::object
10
10
11
11
use core:: fmt;
12
+ use core:: mem;
12
13
use crate :: {
13
14
error:: { Result , to_result_void} ,
14
15
raw:: {
@@ -25,6 +26,7 @@ use crate::{
25
26
time:: Timeout ,
26
27
} ;
27
28
use crate :: object:: {
29
+ Fixed ,
28
30
StaticKernelObject ,
29
31
Wrapped ,
30
32
} ;
@@ -54,10 +56,22 @@ use crate::sys::K_FOREVER;
54
56
/// [`sync::Mutex`]: http://example.com/TODO
55
57
pub struct Mutex {
56
58
/// The raw Zephyr mutex.
57
- item : * mut k_mutex ,
59
+ item : Fixed < k_mutex > ,
58
60
}
59
61
60
62
impl Mutex {
63
+ /// Create a new Mutex in an unlocked state.
64
+ ///
65
+ /// Create a new dynamically allocated Mutex. The Mutex can only be used from system threads.
66
+ #[ cfg( CONFIG_RUST_ALLOC ) ]
67
+ pub fn new ( ) -> Result < Mutex > {
68
+ let item: Fixed < k_mutex > = Fixed :: new ( unsafe { mem:: zeroed ( ) } ) ;
69
+ unsafe {
70
+ to_result_void ( k_mutex_init ( item. get ( ) ) ) ?;
71
+ }
72
+ Ok ( Mutex { item } )
73
+ }
74
+
61
75
/// Lock a Zephyr Mutex.
62
76
///
63
77
/// Will wait for the lock, returning status, with `Ok(())` indicating the lock has been
@@ -67,15 +81,15 @@ impl Mutex {
67
81
where T : Into < Timeout > ,
68
82
{
69
83
let timeout: Timeout = timeout. into ( ) ;
70
- to_result_void ( unsafe { k_mutex_lock ( self . item , timeout. 0 ) } )
84
+ to_result_void ( unsafe { k_mutex_lock ( self . item . get ( ) , timeout. 0 ) } )
71
85
}
72
86
73
87
/// Unlock a Zephyr Mutex.
74
88
///
75
89
/// The mutex must already be locked by the calling thread. Mutexes may not be unlocked in
76
90
/// ISRs.
77
91
pub fn unlock ( & self ) -> Result < ( ) > {
78
- to_result_void ( unsafe { k_mutex_unlock ( self . item ) } )
92
+ to_result_void ( unsafe { k_mutex_unlock ( self . item . get ( ) ) } )
79
93
}
80
94
}
81
95
@@ -109,24 +123,23 @@ impl Wrapped for StaticKernelObject<k_mutex> {
109
123
k_mutex_init ( ptr) ;
110
124
}
111
125
Mutex {
112
- item : ptr,
126
+ item : Fixed :: Static ( ptr) ,
113
127
}
114
128
}
115
129
}
116
130
117
131
impl fmt:: Debug for Mutex {
118
132
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
119
- write ! ( f, "sys::Mutex {:?}" , self . item)
133
+ write ! ( f, "sys::Mutex {:?}" , self . item. get ( ) )
120
134
}
121
135
}
122
136
123
137
/// A Condition Variable
124
138
///
125
139
/// Lightweight wrappers for Zephyr's `k_condvar`.
126
- #[ derive( Clone ) ]
127
140
pub struct Condvar {
128
141
/// The underlying `k_condvar`.
129
- item : * mut k_condvar ,
142
+ item : Fixed < k_condvar > ,
130
143
}
131
144
132
145
#[ doc( hidden) ]
@@ -138,6 +151,18 @@ unsafe impl Sync for Condvar {}
138
151
unsafe impl Send for Condvar { }
139
152
140
153
impl Condvar {
154
+ /// Create a new Condvar.
155
+ ///
156
+ /// Create a new dynamically allocated Condvar. The Condvar can only be used from system threads.
157
+ #[ cfg( CONFIG_RUST_ALLOC ) ]
158
+ pub fn new ( ) -> Result < Condvar > {
159
+ let item: Fixed < k_condvar > = Fixed :: new ( unsafe { mem:: zeroed ( ) } ) ;
160
+ unsafe {
161
+ to_result_void ( k_condvar_init ( item. get ( ) ) ) ?;
162
+ }
163
+ Ok ( Condvar { item } )
164
+ }
165
+
141
166
/// Wait for someone else using this mutex/condvar pair to notify.
142
167
///
143
168
/// Note that this requires the lock to be held by use, but as this is a low-level binding to
@@ -147,25 +172,25 @@ impl Condvar {
147
172
/// [`sync::Condvar`]: http://www.example.com/TODO
148
173
// /// [`sync::Condvar`]: crate::sync::Condvar
149
174
pub fn wait ( & self , lock : & Mutex ) {
150
- unsafe { k_condvar_wait ( self . item , lock. item , K_FOREVER ) ; }
175
+ unsafe { k_condvar_wait ( self . item . get ( ) , lock. item . get ( ) , K_FOREVER ) ; }
151
176
}
152
177
153
178
// TODO: timeout.
154
179
155
180
/// Wake a single thread waiting on this condition variable.
156
181
pub fn notify_one ( & self ) {
157
- unsafe { k_condvar_signal ( self . item ) ; }
182
+ unsafe { k_condvar_signal ( self . item . get ( ) ) ; }
158
183
}
159
184
160
185
/// Wake all threads waiting on this condition variable.
161
186
pub fn notify_all ( & self ) {
162
- unsafe { k_condvar_broadcast ( self . item ) ; }
187
+ unsafe { k_condvar_broadcast ( self . item . get ( ) ) ; }
163
188
}
164
189
}
165
190
166
191
impl fmt:: Debug for Condvar {
167
192
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
168
- write ! ( f, "sys::Condvar {:?}" , self . item)
193
+ write ! ( f, "sys::Condvar {:?}" , self . item. get ( ) )
169
194
}
170
195
}
171
196
@@ -181,7 +206,7 @@ impl Wrapped for StaticCondvar {
181
206
k_condvar_init ( ptr) ;
182
207
}
183
208
Condvar {
184
- item : ptr,
209
+ item : Fixed :: Static ( ptr) ,
185
210
}
186
211
}
187
212
}
0 commit comments