@@ -35,7 +35,7 @@ static inline bool pipe_empty(struct k_pipe *pipe)
3535}
3636
3737static int wait_for (_wait_q_t * waitq , struct k_pipe * pipe , k_spinlock_key_t * key ,
38- k_timepoint_t time_limit )
38+ k_timepoint_t time_limit , bool * need_resched )
3939{
4040 k_timeout_t timeout = sys_timepoint_timeout (time_limit );
4141 int rc ;
@@ -45,6 +45,7 @@ static int wait_for(_wait_q_t *waitq, struct k_pipe *pipe, k_spinlock_key_t *key
4545 }
4646
4747 pipe -> waiting ++ ;
48+ * need_resched = false;
4849 SYS_PORT_TRACING_OBJ_FUNC_BLOCKING (k_pipe , read , pipe , timeout );
4950 rc = z_pend_curr (& pipe -> lock , * key , waitq , timeout );
5051 * key = k_spin_lock (& pipe -> lock );
@@ -85,7 +86,7 @@ struct pipe_buf_spec {
8586 size_t used ;
8687};
8788
88- static size_t copy_to_pending_readers (struct k_pipe * pipe ,
89+ static size_t copy_to_pending_readers (struct k_pipe * pipe , bool * need_resched ,
8990 const uint8_t * data , size_t len )
9091{
9192 struct k_thread * reader ;
@@ -132,6 +133,7 @@ static size_t copy_to_pending_readers(struct k_pipe *pipe,
132133 /* rest of thread wake-up outside the scheduler lock */
133134 z_thread_return_value_set_with_data (reader , 0 , NULL );
134135 z_ready_thread (reader );
136+ * need_resched = true;
135137 }
136138 } while (reader != NULL && written < len );
137139
@@ -144,6 +146,7 @@ int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_
144146 size_t written = 0 ;
145147 k_timepoint_t end = sys_timepoint_calc (timeout );
146148 k_spinlock_key_t key = k_spin_lock (& pipe -> lock );
149+ bool need_resched = false;
147150
148151 SYS_PORT_TRACING_OBJ_FUNC_ENTER (k_pipe , write , pipe , data , len , timeout );
149152
@@ -160,7 +163,8 @@ int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_
160163
161164 if (pipe_empty (pipe )) {
162165 if (pipe -> waiting != 0 ) {
163- written += copy_to_pending_readers (pipe , & data [written ],
166+ written += copy_to_pending_readers (pipe , & need_resched ,
167+ & data [written ],
164168 len - written );
165169 if (written >= len ) {
166170 rc = written ;
@@ -179,7 +183,7 @@ int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_
179183 break ;
180184 }
181185
182- rc = wait_for (& pipe -> space , pipe , & key , end );
186+ rc = wait_for (& pipe -> space , pipe , & key , end , & need_resched );
183187 if (rc != 0 ) {
184188 if (rc == - EAGAIN ) {
185189 rc = written ? written : - EAGAIN ;
@@ -189,7 +193,11 @@ int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_
189193 }
190194exit :
191195 SYS_PORT_TRACING_OBJ_FUNC_EXIT (k_pipe , write , pipe , rc );
192- k_spin_unlock (& pipe -> lock , key );
196+ if (need_resched ) {
197+ z_reschedule (& pipe -> lock , key );
198+ } else {
199+ k_spin_unlock (& pipe -> lock , key );
200+ }
193201 return rc ;
194202}
195203
@@ -199,6 +207,7 @@ int z_impl_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout
199207 int rc ;
200208 k_timepoint_t end = sys_timepoint_calc (timeout );
201209 k_spinlock_key_t key = k_spin_lock (& pipe -> lock );
210+ bool need_resched = false;
202211
203212 SYS_PORT_TRACING_OBJ_FUNC_ENTER (k_pipe , read , pipe , data , len , timeout );
204213
@@ -209,7 +218,8 @@ int z_impl_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout
209218
210219 for (;;) {
211220 if (pipe_full (pipe )) {
212- z_sched_wake (& pipe -> space , 0 , NULL );
221+ /* One or more pending writers may exist. */
222+ need_resched = z_sched_wake_all (& pipe -> space , 0 , NULL );
213223 }
214224
215225 buf .used += ring_buf_get (& pipe -> buf , & data [buf .used ], len - buf .used );
@@ -226,7 +236,7 @@ int z_impl_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout
226236 /* provide our "direct copy" info to potential writers */
227237 _current -> base .swap_data = & buf ;
228238
229- rc = wait_for (& pipe -> data , pipe , & key , end );
239+ rc = wait_for (& pipe -> data , pipe , & key , end , & need_resched );
230240 if (rc != 0 ) {
231241 if (rc == - EAGAIN ) {
232242 rc = buf .used ? buf .used : - EAGAIN ;
@@ -236,7 +246,11 @@ int z_impl_k_pipe_read(struct k_pipe *pipe, uint8_t *data, size_t len, k_timeout
236246 }
237247exit :
238248 SYS_PORT_TRACING_OBJ_FUNC_EXIT (k_pipe , read , pipe , rc );
239- k_spin_unlock (& pipe -> lock , key );
249+ if (need_resched ) {
250+ z_reschedule (& pipe -> lock , key );
251+ } else {
252+ k_spin_unlock (& pipe -> lock , key );
253+ }
240254 return rc ;
241255}
242256
0 commit comments