Author Topic: Netlabs EPMD Startup Freeze  (Read 11497 times)

Dave Yeo

  • Hero Member
  • *****
  • Posts: 4805
  • Karma: +99/-1
    • View Profile
Re: Netlabs EPMD Startup Freeze
« Reply #15 on: December 07, 2022, 09:33:49 pm »
It seems to be a bug in the convenience packages (and WSeB according to the thread). FFmpeg worked perfectly on Warp V4 here, passing all the tests, run on eCS, it crashed with a sigfpu exception.
Bitwise added a fix/work around in libc066 IIRC so GCC programs no longer suffer from the fpu exceptions, so I was thinking that Firefox or any recent libc program would reset the FCW control word preventing the exception. As many programs are built with  GCC and some are in various startup folders, the problem usually doesn't happen. Apparently christech isn't running any GCC programs when starting up EPMD.
Results from Michal's test case, libc vs emx.
Code: [Select]
H:\tmp>test_emx.exe
cw = 0x7F
cw = 0x7F
cw = 0x37F
cw = 0x37F
5.56268e-309

H:\tmp>test_libc.exe
cw = 0X7F
cw = 0X7F
cw = 0X7F
cw = 0X7F
5.56268e-309

Couldn't tell from the thread if the correct answer should be zero or 5.5628e-309, which is very small.
Doodle added this to Cairo,
Code: [Select]
static inline void
DisableFPUException (void)
{
    unsigned short usCW;

    /* Some OS/2 PM API calls modify the FPU Control Word,
     * but forget to restore it.
     *
     * This can result in XCPT_FLOAT_INVALID_OPCODE exceptions,
     * so to be sure, we disable Invalid Opcode FPU exception
     * before using FPU stuffs.
     */
    usCW = _control87 (0, 0);
    usCW = usCW | EM_INVALID | 0x80;
    _control87 (usCW, MCW_EM | 0x80);
}

Edit, I get the same result using SSE for floating point math,
Code: [Select]
cc -Zomf -march=native -mfpmath=sse test.c -o test_libc.exe

H:\tmp>test_libc.exe
cw = 0X7F
cw = 0X7F
cw = 0X7F
cw = 0X7F
5.56268e-309
« Last Edit: December 07, 2022, 09:38:20 pm by Dave Yeo »

Lars

  • Hero Member
  • *****
  • Posts: 1272
  • Karma: +65/-0
    • View Profile
Re: Netlabs EPMD Startup Freeze
« Reply #16 on: December 08, 2022, 11:44:03 am »
This can all be expected.

1) the difference in 0x7F and 0x37F being returned is the precision. 0x7F tells the FPU to internally only use 24 mantissa bits (that is: 32-bit single precision) and 0x37F tell it to use 64 mantissa bits (that is: 80-bit double extended precision). I cannot understand why libc limits the internal FPU computation precision to only 24 mantissa bits. That really makes no sense.

2) it is a known fact that MMX/SSE/AVX/AVX512 do not support double extended precision and never will. They only support single precision (32-bit: 24 mantissa bits) and double precision (64-bit: 53 mantissa bits) and they are not influenced by the FCW setting, there are dedicated machine instructions to load/store either one or the other data type (from/to memory).

But in both cases, 0x7F are the lowest 6 bits of the FCW (strange enough that is even 7 bits, the top bit (0x40) is not defined ...) and these bits control the exception masking and therefore are set to the very same value which is: "mask all FPU exceptions" (there are 6 different FPU exception types).

And these lowest 6 bits seem to be consistently set, at least in your tests and there is no difference between an "emx" and a "libc" program.
Again, if the OS does its job properly, one application should not be able to influence the FCW setting of another application. It can only screw up itself.
« Last Edit: December 08, 2022, 11:59:51 am by Lars »