sba1 / adtools

Experimental GNU toolchain for AmigaOS
33 stars 18 forks source link

std::call_once failing test #82

Open ksdhans opened 4 years ago

ksdhans commented 4 years ago

From here: https://amigaworld.net/modules/newbb/viewtopic.php?mode=viewtopic&topic_id=43666&forum=17&start=60&viewmode=flat&order=0

Running the example code from https://en.cppreference.com/w/cpp/thread/call_once does not produce the correct result.

The output is: Simple example: called once throw: call_once will retry

And then nothing happens anymore. CPU load ends up at 100%, like it's waiting for some input from somewhere and nothing else.

NOTE: Kas1e says he gets the same output on Cygwin when compile it natively for x86, except it exits instead of waiting in loop with CPU usage at 100%.

capehill commented 3 years ago

Is this the implementation: https://github.com/sba1/adtools/blob/master/gcc/8/patches/0025-Add-amigaos-thread-model.patch#L477 ?

If func() throws, then "done" flag will not be set on 483 and other threads are waiting for the flag in the else branch.

kas1e commented 3 years ago

@capehill As you know I ready for any tests if need it, can build everything quite fast :)

sba1 commented 3 years ago

I cannot test myself, but @salass00 did a fix elsewhere, maybe it will fix this problem as well. For people that have running machines it is easy to test, just link the test together with the gthr-amigaos-native.c file and look if it helps. There is no need to produce the entire compiler toolchain.

The gthr implementation itself is not C++ aware (it is a plain C implementation) so I could imagine that this throw case must be solved somewhere else, i.e., not directly in the gthr implementation. I haven't looked at the actual std::call_once implementation of libstc++ but I guess this could further help.

Note that I never had a chance to test the functions myself as I haven't had access to real hardware since a long time (they were indeed developed blindly). I'm happy to merge any pull requests.

kas1e commented 3 years ago

@sba1 Frederik's fixes were for some other problems, I tested them with this bug: nope, didn't help

kas1e commented 3 years ago

@sba1 Sorry forgot to ask, but will you in interest if I will gift you real hardware? You are the one who deserve it, so if you need it for continued work on adtools, I will happily deal with all the stuff so you will have an x5000 motherboard

capehill commented 3 years ago

@sba1 Classic OS4 on WinUAE would be another extreme option.

I did a little bit research and it seems that there has been issues with GNU's std::call_once implementation and they have actually fixed it recently for Linux: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=93e79ed391b9c636f087e6eb7e70f14963cd10ad

Searching for "gnu std::call_once" should find a lot of bug reports.

I will try to update my own compiler and see if something could be done. At this point I have zero clue about std::call_once implementation ;)

kas1e commented 3 years ago

@capehill I build gcc10.0.1 on the cross compiler (from Sodero link, if all will be well that probably can be merged to adtools repo), and the example still didn't work as well. The same stuck on 100% CPU loading.

sba1 commented 3 years ago

@sba1 Sorry forgot to ask, but will you in interest if I will gift you real hardware? You are the one who deserve it, so if you need it for continued work on adtools, I will happily deal with all the stuff so you will have an x5000 motherboard

Thank for the offer, it is appreciated, but indeed I have a plenty of PPC hardware and all of my development happend via QEMU since serveral years, but this does not scale when developing for gcc. Due to a movement I have now some space again for the hardware but as my job is more demanding nowadays especially since the Corona pandemic it is not set up yet.

sba1 commented 3 years ago

I did a little bit research and it seems that there has been issues with GNU's std::call_once implementation and they have actually fixed it recently for Linux: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=93e79ed391b9c636f087e6eb7e70f14963cd10ad

Yes, this is interesting. Especially this one:

As a consequence of the new implementation that doesn't use pthread_once, we can also make std::call_once work for targets with no gthreads support. The code for the single-threaded implementation follows the same methods as on Linux, but with no need for atomics or futexes.

If this is true then the std::call_once should work in more recent versions of gcc directly without gthreads, but I guess it is still a matter setting of some options such that the new code path is taken.

kas1e commented 3 years ago

@all

Interestingly, if I manually compile gthr-amigaos-posix.c, name it gthr-amigaos-pthread.o and put where it should be so -athread=pthread works, then that test case not just simple halt when should exit, but crashes instead. And crash log looks like this:

Crash log for task "pthread id 5"
Generated by GrimReaper 53.19
Crash occured in module kernel at address 0x01806304
Type of crash: unknown exception
Alert number: 0x81000009

Register dump:
GPR (General Purpose Registers):
   0: 0183872C 637C5E50 00000002 0180631C 639E1230 0239BDDC 0239BDCC 0239BE3C
   8: 639E10B0 00000000 0000000A 00000012 33953599 0000000D FFFFFFFF 63BE6DFC
  16: 6475E6E0 EFCFD3C0 00010000 01950000 63BE6DF8 639E127A 18E536E9 7F7D24E4
  24: 639E1230 00000000 637C5E50 00000001 639E1230 0239ECC2 639E1230 0223A968

FPR (Floating Point Registers, NaN = Not a Number):
   0:              nan        0.0820312          0.99999         0.181836
   4:         0.222222       4.5036e+15               20               20
   8:                0       4.5036e+15              167       4.5036e+15
  12:                1      2.14748e+09             1000                1
  16:               60              100                0     -1.25593e-63
  20:     5.64694e-115    -1.96426e-298     3.65371e-220     2.48115e-265
  24:     -9.5969e-266    -3.46801e-210     3.08327e-153     2.41351e-226
  28:    -1.37561e-260    -3.81213e-262     8.60255e-294     -3.85448e+88

FPSCR (Floating Point Status and Control Register): 0x82004000

SPRs (Special Purpose Registers):
           Machine State (msr) : 0x0002B030
                Condition (cr) : 0x63830000
      Instruction Pointer (ip) : 0x01806304
       Xtended Exception (xer) : 0x63751134
                   Count (ctr) : 0x00570001
                     Link (lr) : 0x00000000
            DSI Status (dsisr) : 0x85027002
            Data Address (dar) : 0x63835A44

680x0 emulated registers:
DATA: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ADDR: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
FPU0:                0                0                0                0
FPU4:                0                0                0                0

Symbol info:
Instruction pointer 0x01806304 belongs to module "kernel" (HUNK/Kickstart)

Stack trace:
    native kernel module kernel+0x00006304
    native kernel module kernel+0x00038734
    native kernel module newlib.library.kmod+0x00014250
    native kernel module newlib.library.kmod+0x00006d2c
    LIBS:pthreads.library:_impl_DoDestructors()+0x94 (section 1 @ 0x232C)
    LIBS:pthreads.library:run()+0x114 (section 1 @ 0x5324)
    LIBS:pthreads.library:ThreadCode()+0x344 (section 1 @ 0x5824)
    native kernel module dos.library.kmod+0x0002a458
    native kernel module kernel+0x0005c18c
    native kernel module kernel+0x0005c204

PPC disassembly:
 018062fc: 6063631c   ori               r3,r3,25372
 01806300: 44000002   sc
*01806304: 4e800020   blr
 01806308: 7c641b78   mr                r4,r3
 0180630c: 3c600180   lis               r3,384

System information:

CPU
 Model: Freescale P5020 (E5500 core) V1.2
 CPU speed: 1995 MHz
 FSB speed: 798 MHz
 Extensions:

Machine
 Machine name: AmigaOne X5000/20
 Memory: 2097152 KB
 Extensions: bus.pci bus.pcie

It's, of course, point out an issue in the pthreads, but from another side maybe it will bring also something new to us in terms of why it fails on native implementation too (through, without a crash, but..)

sba1 commented 3 years ago

If the libstdc++ implementation of call_once really plainly uses the gthread without propagating exceptions properly through the c function then it cannot work as well as it is not exception-safe either. I haven't checked if this has been changed in recent versions of libstdc++. If pushes come to shove, we could always come with a custom std::call_once implementation.

3246251196 commented 2 years ago

This ticket can potentially be closed. The call_once test now passes, but no extensive testing has been performed. See HEAD revision.