Natanael Copa wrote:
> > So, you could try to install a different scheduler by default and repeat
> > the test.
>
> It passed with chrt --fifo (I had to do it from outside the LXC container):
>
> # time chrt --fifo 10 ./test-pthread-rwlock
> Starting test_rwlock ... OK
> real 0m 33.00s
> user 6m 50.63s
> sys 0m 16.23s
>
> I also verified that it still times out from outside the LXC container with
> the default:
>
> # time ./test-pthread-rwlock
> Starting test_rwlock ...Command terminated by signal 14
> real 10m 0.01s
> user 1h 46m 24s
> sys 2m 59.39s
>
>
> # time chrt --rr 10 ./test-pthread-rwlock
> Starting test_rwlock ... OK
> real 0m 30.00s
> user 6m 2.07s
> sys 0m 19.16s
>
> # time chrt --rr 99 ./test-pthread-rwlock
> Starting test_rwlock ... OK
> real 0m 30.00s
> user 6m 9.40s
> sys 0m 13.37s
>
> So even if the CPU cores are slow, they appear to finish in ~30 sec.
>
> chrt --other and chrt --idle appears to trigger the deadlock.
For comparison, some other data (below the details):
* On x86_64 (glibc), I see essentially no influence of the scheduling
policy on 'time ./test-pthread-rwlock'.
* On x86_64 (Alpine Linux), the test performs about 25% faster
under SCHED_FIFO and SCHED_RR.
* On three other riscv64 systems, the test needs less than 4 seconds
real time. Even on my QEMU-emulated riscv64 VM, it needs less
than 4 seconds.
So, it seems that
1) Your riscv64 system is generally slower that the cfarm* ones.
2) The performance penalty of SCHED_OTHER compared to SCHED_FIFO and
SCHED_RR exists also on x86_64, but not to such an extreme extent.
AFAICS, there are three differences in your setup compared to what I
see in stock Ubuntu:
- Linux is of a PREEMPTY_DYNAMIC flavour.
- musl libc.
- the LXR container.
Note: Most Gnulib applications don't use pthread_rwlock directly, but
the glthread_rwlock facility. On musl systems, it works around the
possible writer starvation by reimplementing read-write locks based
on condition variables. This may be slower for a single operation,
but it is guaranteed to avoid writer starvation and therefore is
preferrable globally. This is why you don't see a timeout in
'./test-lock', only in './test-pthread-rwlock'.
Bruno
========================= DETAILS =======================
Ubuntu x86_64 (glibc):
# time ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,161s
user 0m0,268s
sys 0m1,047s
# time chrt --other 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,166s
user 0m0,243s
sys 0m1,046s
# time chrt --fifo 10 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,161s
user 0m0,249s
sys 0m1,080s
# time chrt --rr 10 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,164s
user 0m0,307s
sys 0m1,019s
# time chrt --batch 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,151s
user 0m0,217s
sys 0m1,024s
# time chrt --idle 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m0,195s
user 0m0,264s
sys 0m1,115s
# time chrt --deadline 0 ./test-pthread-rwlock
chrt: failed to set pid 0's policy: Invalid argument
Alpine Linux 3.20 x86_64 in a VM:
# time ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.54 s
# time chrt --other 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.56 s
# time chrt --fifo 10 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.24 s
# time chrt --rr 10 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.25 s
# time chrt --batch 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.59 s
# time chrt --idle 0 ./test-pthread-rwlock
Starting test_rwlock ... OK
real 1.59 s
# time chrt --deadline 0 ./test-pthread-rwlock
chrt: failed to set pid 0's policy: Invalid argument
cfarm91 (glibc):
$ time ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m3,908s
user 0m0,909s
sys 0m6,863s
cfarm94 (Alpine Linux):
$ time ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m 0.84s
user 0m 0.60s
sys 0m 2.77s
cfarm95 (glibc):
$ time ./test-pthread-rwlock
Starting test_rwlock ... OK
real 0m2,166s
user 0m9,287s
sys 0m3,145s