(context_ptr: *mut Context, handle: u64)
| 327 | |
| 328 | |
| 329 | fn sys_receive(context_ptr: *mut Context, handle: u64) { |
| 330 | // Extract the current thread |
| 331 | if let Some(mut thread) = process::take_current_thread() { |
| 332 | let current_tid = thread.tid(); |
| 333 | thread.set_context(context_ptr); |
| 334 | |
| 335 | // Get the Rendezvous and call |
| 336 | if let Some(rdv) = thread.rendezvous(handle) { |
| 337 | let (thread1, thread2) = rdv.write().receive(thread); |
| 338 | // thread1 should be started asap |
| 339 | // thread2 should be scheduled |
| 340 | |
| 341 | let mut returning = false; |
| 342 | for maybe_thread in [thread2, thread1] { |
| 343 | if let Some(t) = maybe_thread { |
| 344 | if t.tid() == current_tid { |
| 345 | // Same thread -> return |
| 346 | process::set_current_thread(t); |
| 347 | returning = true; |
| 348 | } else { |
| 349 | process::schedule_thread(t); |
| 350 | } |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | if !returning { |
| 355 | // Original thread is waiting. |
| 356 | // Switch to a different thread |
| 357 | drop(rdv); // Not returning from launch_thread |
| 358 | let new_context_addr = process::schedule_next(context_ptr as usize); |
| 359 | interrupts::launch_thread(new_context_addr); |
| 360 | } |
| 361 | } else { |
| 362 | // Missing handle |
| 363 | thread.return_error(SYSCALL_ERROR_INVALID_HANDLE); |
| 364 | process::set_current_thread(thread); |
| 365 | } |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | /// This handles both syscall_send and syscall_sendreceive |
| 370 | fn sys_send( |
no test coverage detected