Nothing to see here, move along
at main 620 lines 24 kB view raw
1use crate::cap::cnode; 2use crate::cap::object::{ 3 EndpointData, NotificationData, ObjectData, ObjectTag, ProcessObjectData, SchedContextData, 4}; 5use crate::cap::ops; 6use crate::cap::pool::POOL; 7use crate::cap::table::{CapRef, Rights}; 8use crate::error::KernelError; 9use crate::ipc::endpoint; 10use crate::proc::{BlockedReason, PROCESSES, ProcessState}; 11use crate::types::{Pid, Priority}; 12 13fn bootstrap_test_cnode(pid: Pid, ptable: &mut crate::proc::ProcessManager) { 14 let size_bits = crate::proc::ROOT_CNODE_SIZE_BITS; 15 let allocator = &crate::mem::phys::BitmapFrameAllocator; 16 let cnode_data = crate::cap::cnode::create_cnode(size_bits, allocator).expect("create cnode"); 17 let frame_count = cnode_data.frame_count; 18 let (cnode_id, cnode_gen) = crate::cap::pool::POOL 19 .lock() 20 .allocate(crate::cap::object::ObjectData::CNode(cnode_data)) 21 .expect("alloc cnode"); 22 let proc = ptable.get_mut(pid).expect("get proc"); 23 proc.root_cnode = Some((cnode_id, cnode_gen)); 24 proc.cnode_depth = size_bits; 25 proc.charge_frames(frame_count as u16).expect("charge frames"); 26} 27 28crate::kernel_test!( 29 fn create_endpoint_inserts_cap() { 30 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 31 let mut ptable = PROCESSES.lock(); 32 let created = ptable.allocate(&mut allocator).expect("alloc"); 33 ptable.start(created).expect("start"); 34 let pid = created.pid(); 35 bootstrap_test_cnode(pid, &mut ptable); 36 37 let address = 10u64; 38 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 39 let oid = { 40 let mut pool = POOL.lock_after(&ptable); 41 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Endpoint) 42 .expect("create endpoint") 43 }; 44 45 { 46 let pool = POOL.lock_after(&ptable); 47 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, address, depth) 48 .expect("read slot"); 49 assert!(cap.tag() == ObjectTag::Endpoint); 50 assert!(cap.rights().contains(Rights::ALL)); 51 assert!(cap.object_id() == oid); 52 } 53 54 ptable.destroy(pid, &mut allocator); 55 } 56); 57 58crate::kernel_test!( 59 fn create_notification_inserts_cap() { 60 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 61 let mut ptable = PROCESSES.lock(); 62 let created = ptable.allocate(&mut allocator).expect("alloc"); 63 ptable.start(created).expect("start"); 64 let pid = created.pid(); 65 bootstrap_test_cnode(pid, &mut ptable); 66 67 let address = 11u64; 68 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 69 let oid = { 70 let mut pool = POOL.lock_after(&ptable); 71 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Notification) 72 .expect("create notification") 73 }; 74 75 { 76 let pool = POOL.lock_after(&ptable); 77 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, address, depth) 78 .expect("read slot"); 79 assert!(cap.tag() == ObjectTag::Notification); 80 assert!(cap.object_id() == oid); 81 } 82 83 ptable.destroy(pid, &mut allocator); 84 } 85); 86 87crate::kernel_test!( 88 fn create_memory_region_rejected() { 89 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 90 let mut ptable = PROCESSES.lock(); 91 let created = ptable.allocate(&mut allocator).expect("alloc"); 92 ptable.start(created).expect("start"); 93 let pid = created.pid(); 94 bootstrap_test_cnode(pid, &mut ptable); 95 96 let address = 12u64; 97 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 98 let result = { 99 let mut pool = POOL.lock_after(&ptable); 100 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::MemoryRegion) 101 }; 102 assert!( 103 matches!(result, Err(KernelError::InvalidType)), 104 "creating a MemoryRegion cap via create_via_cnode must fail" 105 ); 106 107 ptable.destroy(pid, &mut allocator); 108 } 109); 110 111crate::kernel_test!( 112 fn create_invalid_tag_rejected() { 113 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 114 let mut ptable = PROCESSES.lock(); 115 let created = ptable.allocate(&mut allocator).expect("alloc"); 116 ptable.start(created).expect("start"); 117 let pid = created.pid(); 118 bootstrap_test_cnode(pid, &mut ptable); 119 120 let address = 13u64; 121 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 122 let result = { 123 let mut pool = POOL.lock_after(&ptable); 124 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Process) 125 }; 126 assert!( 127 matches!(result, Err(KernelError::InvalidType)), 128 "creating a Process cap via ops::create must fail" 129 ); 130 131 ptable.destroy(pid, &mut allocator); 132 } 133); 134 135crate::kernel_test!( 136 fn create_occupied_slot_rolls_back() { 137 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 138 let mut ptable = PROCESSES.lock(); 139 let created = ptable.allocate(&mut allocator).expect("alloc"); 140 ptable.start(created).expect("start"); 141 let pid = created.pid(); 142 bootstrap_test_cnode(pid, &mut ptable); 143 144 let address = 14u64; 145 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 146 { 147 let mut pool = POOL.lock_after(&ptable); 148 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Endpoint) 149 .expect("first create"); 150 } 151 152 let result = { 153 let mut pool = POOL.lock_after(&ptable); 154 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Notification) 155 }; 156 assert!( 157 matches!(result, Err(KernelError::SlotOccupied)), 158 "second create into occupied slot must fail" 159 ); 160 161 { 162 let pool = POOL.lock_after(&ptable); 163 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, address, depth) 164 .expect("read slot"); 165 assert!( 166 cap.tag() == ObjectTag::Endpoint, 167 "original cap should still be in the slot" 168 ); 169 } 170 171 ptable.destroy(pid, &mut allocator); 172 } 173); 174 175crate::kernel_test!( 176 fn derive_attenuates_rights() { 177 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 178 let mut ptable = PROCESSES.lock(); 179 let created = ptable.allocate(&mut allocator).expect("alloc"); 180 ptable.start(created).expect("start"); 181 let pid = created.pid(); 182 bootstrap_test_cnode(pid, &mut ptable); 183 184 let src_addr = 20u64; 185 let dest_addr = 21u64; 186 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 187 188 { 189 let mut pool = POOL.lock_after(&ptable); 190 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, src_addr, depth, ObjectTag::Endpoint) 191 .expect("create source"); 192 } 193 194 { 195 let mut pool = POOL.lock_after(&ptable); 196 ops::derive_via_cnode(&mut pool, cnode_id, cnode_gen, src_addr, dest_addr, depth, Rights::READ) 197 .expect("derive"); 198 } 199 200 { 201 let pool = POOL.lock_after(&ptable); 202 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, dest_addr, depth) 203 .expect("read derived slot"); 204 assert!(cap.rights().contains(Rights::READ)); 205 assert!(!cap.rights().contains(Rights::WRITE)); 206 assert!(!cap.rights().contains(Rights::REVOKE)); 207 } 208 209 ptable.destroy(pid, &mut allocator); 210 } 211); 212 213crate::kernel_test!( 214 fn derive_without_grant_fails() { 215 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 216 let mut ptable = PROCESSES.lock(); 217 let created = ptable.allocate(&mut allocator).expect("alloc"); 218 ptable.start(created).expect("start"); 219 let pid = created.pid(); 220 bootstrap_test_cnode(pid, &mut ptable); 221 222 let src_addr = 30u64; 223 let dest_addr = 31u64; 224 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 225 226 { 227 let mut pool = POOL.lock_after(&ptable); 228 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, src_addr, depth, ObjectTag::Endpoint) 229 .expect("create source"); 230 } 231 232 { 233 let pool = POOL.lock_after(&ptable); 234 let old_cap = cnode::resolve_and_clear(&pool, cnode_id, cnode_gen, src_addr, depth) 235 .expect("clear slot"); 236 let new_cap = old_cap.with_rights(Rights::READ | Rights::WRITE); 237 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, src_addr, depth, new_cap) 238 .expect("reinsert cap"); 239 } 240 241 let result = { 242 let mut pool = POOL.lock_after(&ptable); 243 ops::derive_via_cnode(&mut pool, cnode_id, cnode_gen, src_addr, dest_addr, depth, Rights::READ) 244 }; 245 assert!( 246 matches!(result, Err(KernelError::InsufficientRights)), 247 "derive without GRANT right must fail" 248 ); 249 250 ptable.destroy(pid, &mut allocator); 251 } 252); 253 254crate::kernel_test!( 255 fn identify_returns_tag_and_rights() { 256 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 257 let mut ptable = PROCESSES.lock(); 258 let created = ptable.allocate(&mut allocator).expect("alloc"); 259 ptable.start(created).expect("start"); 260 let pid = created.pid(); 261 bootstrap_test_cnode(pid, &mut ptable); 262 263 let address = 40u64; 264 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(pid, &ptable).expect("coords"); 265 266 { 267 let mut pool = POOL.lock_after(&ptable); 268 ops::create_via_cnode(&mut pool, cnode_id, cnode_gen, address, depth, ObjectTag::Notification) 269 .expect("create notification"); 270 } 271 272 let (tag, rights) = { 273 let pool = POOL.lock_after(&ptable); 274 ops::identify_via_cnode(&pool, cnode_id, cnode_gen, address, depth) 275 .expect("identify") 276 }; 277 278 assert!(tag == ObjectTag::Notification); 279 assert!(rights.contains(Rights::ALL)); 280 281 ptable.destroy(pid, &mut allocator); 282 } 283); 284 285crate::kernel_test!( 286 fn endpoint_revoke_unblocks_senders() { 287 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 288 let mut ptable = PROCESSES.lock(); 289 290 let owner_created = ptable.allocate(&mut allocator).expect("alloc owner"); 291 let sender_created = ptable.allocate(&mut allocator).expect("alloc sender"); 292 ptable.start(owner_created).expect("start owner"); 293 ptable.start(sender_created).expect("start sender"); 294 let owner_pid = owner_created.pid(); 295 let sender_pid = sender_created.pid(); 296 bootstrap_test_cnode(owner_pid, &mut ptable); 297 298 let (ep_id, ep_gen) = POOL 299 .lock_after(&ptable) 300 .allocate(ObjectData::Endpoint(EndpointData::new())) 301 .expect("alloc ep"); 302 303 let cap = CapRef::new(ObjectTag::Endpoint, ep_id, Rights::ALL, ep_gen); 304 let address = 0u64; 305 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(owner_pid, &ptable).expect("coords"); 306 { 307 let pool = POOL.lock_after(&ptable); 308 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 309 .expect("insert cap"); 310 } 311 312 ptable[sender_pid] 313 .transition_to(ProcessState::Running) 314 .expect("sender -> Running"); 315 let blocked = ptable[sender_pid] 316 .block_on(BlockedReason::Sending(ep_id, ep_gen)) 317 .expect("block sender"); 318 319 { 320 let mut pool = POOL.lock_after(&ptable); 321 let ep = pool 322 .get_mut(ep_id, ep_gen) 323 .and_then(|d| d.as_endpoint_mut()) 324 .expect("get ep"); 325 endpoint::enqueue(&mut ep.senders, blocked, &mut ptable).expect("enqueue"); 326 } 327 328 ops::revoke_via_cnode(owner_pid, address, &mut ptable).expect("revoke"); 329 330 assert!( 331 ptable[sender_pid].state() == ProcessState::Ready, 332 "sender should be unblocked after endpoint revoke" 333 ); 334 assert!( 335 ptable[sender_pid].saved_context.rax == KernelError::InvalidObject.to_errno() as u64, 336 "sender's rax should contain InvalidObject errno after endpoint revoke" 337 ); 338 339 ptable.destroy(owner_pid, &mut allocator); 340 ptable.destroy(sender_pid, &mut allocator); 341 } 342); 343 344crate::kernel_test!( 345 fn notification_revoke_unblocks_waiters() { 346 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 347 let mut ptable = PROCESSES.lock(); 348 349 let owner_created = ptable.allocate(&mut allocator).expect("alloc owner"); 350 let waiter_created = ptable.allocate(&mut allocator).expect("alloc waiter"); 351 ptable.start(owner_created).expect("start owner"); 352 ptable.start(waiter_created).expect("start waiter"); 353 let owner_pid = owner_created.pid(); 354 let waiter_pid = waiter_created.pid(); 355 bootstrap_test_cnode(owner_pid, &mut ptable); 356 357 let (notif_id, notif_gen) = POOL 358 .lock_after(&ptable) 359 .allocate(ObjectData::Notification(NotificationData::new())) 360 .expect("alloc notif"); 361 362 let cap = CapRef::new(ObjectTag::Notification, notif_id, Rights::ALL, notif_gen); 363 let address = 0u64; 364 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(owner_pid, &ptable).expect("coords"); 365 { 366 let pool = POOL.lock_after(&ptable); 367 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 368 .expect("insert cap"); 369 } 370 371 ptable[waiter_pid] 372 .transition_to(ProcessState::Running) 373 .expect("waiter -> Running"); 374 let _ = ptable[waiter_pid] 375 .block_on(BlockedReason::WaitingNotification(notif_id, notif_gen)) 376 .expect("block waiter"); 377 378 { 379 let mut pool = POOL.lock_after(&ptable); 380 let notif = pool 381 .get_mut(notif_id, notif_gen) 382 .and_then(|d| d.as_notification_mut()) 383 .expect("get notif"); 384 let _ = notif.waiters.push(waiter_pid); 385 } 386 387 ops::revoke_via_cnode(owner_pid, address, &mut ptable).expect("revoke"); 388 389 assert!( 390 ptable[waiter_pid].state() == ProcessState::Ready, 391 "waiter should be unblocked after notification revoke" 392 ); 393 assert!( 394 ptable[waiter_pid].saved_context.rax == KernelError::InvalidObject.to_errno() as u64, 395 "waiter's rax should contain InvalidObject errno after notification revoke" 396 ); 397 398 ptable.destroy(owner_pid, &mut allocator); 399 ptable.destroy(waiter_pid, &mut allocator); 400 } 401); 402 403crate::kernel_test!( 404 fn proc_destroy_decrements_pool_refcount() { 405 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 406 let mut ptable = PROCESSES.lock(); 407 408 let parent_created = ptable.allocate(&mut allocator).expect("alloc parent"); 409 let child_created = ptable.allocate(&mut allocator).expect("alloc child"); 410 ptable.start(parent_created).expect("start parent"); 411 ptable.start(child_created).expect("start child"); 412 let parent_pid = parent_created.pid(); 413 let child_pid = child_created.pid(); 414 bootstrap_test_cnode(parent_pid, &mut ptable); 415 416 let data = ObjectData::Process(ProcessObjectData { pid: child_pid }); 417 let tag = ObjectTag::Process; 418 let (obj_id, generation) = POOL.lock_after(&ptable).allocate(data).expect("alloc process object"); 419 let cap = CapRef::new(tag, obj_id, Rights::ALL, generation); 420 let address = 0u64; 421 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(parent_pid, &ptable).expect("coords"); 422 { 423 let pool = POOL.lock_after(&ptable); 424 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 425 .expect("insert cap"); 426 } 427 428 POOL.lock_after(&ptable).inc_ref(obj_id, generation).expect("inc_ref"); 429 let refcount_before = POOL.lock_after(&ptable).get(obj_id, generation).is_ok(); 430 assert!(refcount_before, "object should be alive before destroy"); 431 432 ptable.destroy(child_pid, &mut allocator); 433 434 POOL.lock_after(&ptable).dec_ref(obj_id, generation); 435 { 436 let pool = POOL.lock_after(&ptable); 437 let _ = cnode::resolve_and_clear(&pool, cnode_id, cnode_gen, address, depth); 438 } 439 440 ptable.destroy(parent_pid, &mut allocator); 441 } 442); 443 444crate::kernel_test!( 445 fn sched_context_revoke_detaches_process() { 446 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 447 let mut ptable = PROCESSES.lock(); 448 449 let owner_created = ptable.allocate(&mut allocator).expect("alloc owner"); 450 ptable.start(owner_created).expect("start owner"); 451 let owner_pid = owner_created.pid(); 452 bootstrap_test_cnode(owner_pid, &mut ptable); 453 454 let sc_data = 455 ObjectData::SchedContext(SchedContextData::new(1000, 10000, Priority::new(100))); 456 let (sc_id, sc_gen) = POOL.lock_after(&ptable).allocate(sc_data).expect("alloc sched context"); 457 458 { 459 let mut pool = POOL.lock_after(&ptable); 460 let sc = pool 461 .get_mut(sc_id, sc_gen) 462 .and_then(|d| d.as_sched_context_mut()) 463 .expect("get sc"); 464 sc.attached_pid = Some(owner_pid); 465 } 466 467 let cap = CapRef::new(ObjectTag::SchedContext, sc_id, Rights::ALL, sc_gen); 468 let address = 0u64; 469 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(owner_pid, &ptable).expect("coords"); 470 { 471 let pool = POOL.lock_after(&ptable); 472 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 473 .expect("insert cap"); 474 } 475 476 ptable[owner_pid].attach_sched_context(sc_id, sc_gen, Priority::new(100)); 477 assert!( 478 ptable[owner_pid].sched_context().is_some(), 479 "sched_context should be attached before revoke" 480 ); 481 482 ops::revoke_via_cnode(owner_pid, address, &mut ptable).expect("revoke sched context"); 483 484 assert!( 485 ptable[owner_pid].sched_context().is_none(), 486 "sched_context must be detached after SchedContext revoke" 487 ); 488 489 ptable.destroy(owner_pid, &mut allocator); 490 } 491); 492 493crate::kernel_test!( 494 fn sched_context_revoke_prevents_scheduling() { 495 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 496 let mut ptable = PROCESSES.lock(); 497 498 let owner_created = ptable.allocate(&mut allocator).expect("alloc owner"); 499 ptable.start(owner_created).expect("start owner"); 500 let owner_pid = owner_created.pid(); 501 bootstrap_test_cnode(owner_pid, &mut ptable); 502 503 let sc_data = 504 ObjectData::SchedContext(SchedContextData::new(1000, 10000, Priority::new(200))); 505 let address = 0u64; 506 let (sc_id, sc_gen) = POOL.lock_after(&ptable).allocate(sc_data).expect("alloc sc"); 507 508 { 509 let mut pool = POOL.lock_after(&ptable); 510 let sc = pool 511 .get_mut(sc_id, sc_gen) 512 .and_then(|d| d.as_sched_context_mut()) 513 .expect("get sc"); 514 sc.attached_pid = Some(owner_pid); 515 } 516 517 let cap = CapRef::new(ObjectTag::SchedContext, sc_id, Rights::ALL, sc_gen); 518 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(owner_pid, &ptable).expect("coords"); 519 { 520 let pool = POOL.lock_after(&ptable); 521 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 522 .expect("insert cap"); 523 } 524 ptable[owner_pid].attach_sched_context(sc_id, sc_gen, Priority::new(200)); 525 526 assert!( 527 ptable[owner_pid].is_runnable(), 528 "process should be runnable before revoke" 529 ); 530 531 ops::revoke_via_cnode(owner_pid, address, &mut ptable).expect("revoke"); 532 533 assert!( 534 ptable[owner_pid].sched_context().is_none(), 535 "sched_context detached after revoke" 536 ); 537 538 ptable.destroy(owner_pid, &mut allocator); 539 } 540); 541 542crate::kernel_test!( 543 fn cleanup_sched_context_with_no_attached_process() { 544 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 545 let mut ptable = PROCESSES.lock(); 546 547 let owner_created = ptable.allocate(&mut allocator).expect("alloc owner"); 548 ptable.start(owner_created).expect("start owner"); 549 let owner_pid = owner_created.pid(); 550 bootstrap_test_cnode(owner_pid, &mut ptable); 551 552 let sc_data = ObjectData::SchedContext(SchedContextData::new(500, 5000, Priority::new(50))); 553 let address = 0u64; 554 let (sc_id, sc_gen) = POOL.lock_after(&ptable).allocate(sc_data).expect("alloc sc"); 555 let cap = CapRef::new(ObjectTag::SchedContext, sc_id, Rights::ALL, sc_gen); 556 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(owner_pid, &ptable).expect("coords"); 557 { 558 let pool = POOL.lock_after(&ptable); 559 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 560 .expect("insert cap"); 561 } 562 563 ops::revoke_via_cnode(owner_pid, address, &mut ptable).expect("revoke unattached sc"); 564 565 ptable.destroy(owner_pid, &mut allocator); 566 } 567); 568 569crate::kernel_test!( 570 fn sched_context_cleanup_different_holder_and_attached() { 571 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 572 let mut ptable = PROCESSES.lock(); 573 574 let holder_created = ptable.allocate(&mut allocator).expect("alloc holder"); 575 let target_created = ptable.allocate(&mut allocator).expect("alloc target"); 576 ptable.start(holder_created).expect("start holder"); 577 ptable.start(target_created).expect("start target"); 578 let holder_pid = holder_created.pid(); 579 let target_pid = target_created.pid(); 580 bootstrap_test_cnode(holder_pid, &mut ptable); 581 582 let sc_data = 583 ObjectData::SchedContext(SchedContextData::new(1000, 10000, Priority::new(100))); 584 let (sc_id, sc_gen) = POOL.lock_after(&ptable).allocate(sc_data).expect("alloc sc"); 585 586 { 587 let mut pool = POOL.lock_after(&ptable); 588 let sc = pool 589 .get_mut(sc_id, sc_gen) 590 .and_then(|d| d.as_sched_context_mut()) 591 .expect("get sc"); 592 sc.attached_pid = Some(target_pid); 593 } 594 595 ptable[target_pid].attach_sched_context(sc_id, sc_gen, Priority::new(100)); 596 assert!( 597 ptable[target_pid].sched_context().is_some(), 598 "target should have sched context" 599 ); 600 601 let cap = CapRef::new(ObjectTag::SchedContext, sc_id, Rights::ALL, sc_gen); 602 let address = 0u64; 603 let (cnode_id, cnode_gen, depth) = cnode::cnode_coords(holder_pid, &ptable).expect("coords"); 604 { 605 let pool = POOL.lock_after(&ptable); 606 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, address, depth, cap) 607 .expect("insert cap"); 608 } 609 610 ops::revoke_via_cnode(holder_pid, address, &mut ptable).expect("revoke"); 611 612 assert!( 613 ptable[target_pid].sched_context().is_none(), 614 "target's sched_context must be cleared when holder revokes the SchedContext" 615 ); 616 617 ptable.destroy(holder_pid, &mut allocator); 618 ptable.destroy(target_pid, &mut allocator); 619 } 620);