Re: Enable UTF-8 code page in driver and compiler on 64-bit mingw host [PR108865]

2023-03-07 Thread Jacek Caban via Gcc-patches

Hi Costas,

On 3/7/23 01:52, Costas Argyris via Gcc-patches wrote:

This is a proposal for addressing

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108865

by integrating the UTF-8 manifest file into gcc's build process for the
64-bit mingw host.



Is there a reason to make it specific to x86_64? It seems to me that all 
mingw hosts could use it.





+# The resource .rc file references the utf8 .manifest file.
+# Compile it into an object file using windres.
+# The resulting .o file gets added to host_extra_gcc_objs in
+# config.host for x86_64-*-mingw* host and gets linked into
+# the driver as a .o file, so it's lack of symbols is OK.
+utf8rc-mingw32.o : $(srcdir)/config/i386/utf8-mingw32.rc
+   $(WINDRES) $< $@



I think that .manifest file should also be a dependency here.


Thanks,

Jacek


Re: Enable UTF-8 code page in driver and compiler on 64-bit mingw host [PR108865]

2023-03-07 Thread Jacek Caban via Gcc-patches

Hi Costas,

On 3/7/23 15:00, Costas Argyris wrote:

Hi Jacek,

"Is there a reason to make it specific to x86_64? It seems to me that 
all mingw hosts could use it."


Are you referring to the 32-bit host?    My concern here is that this 
functionality (embedding the UTF-8
manifest file into the executable) is only truly supported in recent 
versions of Windows.    From:


https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page

It says that Windows Version 1903 (May 2019 Update) enables this, so 
we are looking at the 64-bit

version of Windows.

I suppose you are referring to the scenario where one has a 32-bit 
gcc + mingw running in a 64-bit
Windows that is recent enough to support this?    It is not clear to 
me based on the above doc what
would happen encoding-wise in that situation, and I haven't tried it 
either because I assumed that
most people would want the 64-bit version of gcc since they are 
probably running a 64-bit OS.


If you think it is useful, I could look into that as a separate task 
to try and keep this one simple, if

that makes sense.



Yes, realistically it's mostly about 32-bit gcc on 64-bit Windows 
(perhaps aarch64 as well at some point in the future). It's probably 
indeed not very popular configuration those days, but I think it should 
work just fine if you didn't explicitly limit the patch to x86_64.




"I think that .manifest file should also be a dependency here."

Why is that?    Windres takes only the .rc file as its input, as per 
its own doc, and it successfully
compiles it into an object file.    The .manifest file is only 
referenced by the .rc file, and it doesn't
get passed to windres, so I don't see why it has to be listed as a 
prerequisite in the make rule.



The point that when winnt-utf8.manifest is modified, utf8-mingw32.o 
should be rebuilt. Anyway, it's probably not a big deal (I should 
disclaim that I'm not very familiar with gcc build system; I'm mostly on 
this ML due to mingw-w64 contributions).



Thanks,

Jacek



Re: Adding a new thread model to GCC

2022-10-21 Thread Jacek Caban via Gcc-patches
The problem about this approach is that, semaphores are valuable kernel objects, and the maximum 
number of HANDLEs that a process can open concurrently has a limit (like FDs on Linux), while 'many 
critical sections are used only occasionally (or never at all), meaning the auto-reset event often 
isn’t even necessary' [1], the semaphores are actually allocated on demand. This means that locking 
can fail. There is a story in article [1] which also explains the origination of keyed events; it's 
worth reading.


This is not true for past 15 years, CRITICAL_SECTIONS use something like 
RtlWaitOnAddress (an equivalent of futexes) since Vista, see Wine 
implementation for details:
https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190

Jacek


Re: Adding a new thread model to GCC

2022-10-21 Thread Jacek Caban via Gcc-patches

On 2022-10-21 11:44, Eric Botcazou via Libstdc++ wrote:

/How does this compare with Eric B's proposal at />>>/https://gcc.gnu.org/legacy-ml/gcc-patches/2019-06/msg01840.html 
? />>//>>/My proposal was to reimplement (and extend) the native thread model />>/(win32) />>/instead 
of adding a new one, the advantage being that you don't need an />>/extra />/> threading layer between GCC and 
Windows. />

I agree!


I agree as well and I expressed that on mingw-w64 ML when the patch was 
introduced [1]. My main concern with the new threading model is that instead of 
solving root of the problem, it introduces more fragmentation with no clear 
benefit.

On top of that, mcfgthread library is way more invasive than it needs to be. It 
requires maintaining per-thread struct and reimplements a number of things 
instead of leveraging OS capabilities. Author also plans to make invasive 
changes to mingw-w64-crt, which go against it current approach of being 
agnostic to threading model.

Jacek

[1] https://sourceforge.net/p/mingw-w64/mailman/message/37719727/



Re: Adding a new thread model to GCC

2022-10-21 Thread Jacek Caban via Gcc-patches

On 10/21/22 14:29, LIU Hao wrote:

在 2022/10/21 20:13, Jacek Caban 写道:


This is not true for past 15 years, CRITICAL_SECTIONS use something 
like RtlWaitOnAddress (an equivalent of futexes) since Vista, see 
Wine implementation for details:

https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/sync.c#L190




Ah Jacek, nice to see you here.

I haven't dug into this too much, though. From my limited knowledge 
(mostly from reading disassembly) now CRITICAL_SECTION uses 
`NtWaitForAlertByThreadId` (and no longer keyed events or semaphores). 
As with `WaitOnAddress()`, there seems to be some global data 
structure, protected by a spin lock. It's just another undocumented 
syscall. Keyed events are still functional.



NtWaitForAlertByThreadId() is an underlying syscall that's used by 
WaitOnAddress(). Anyway, you don't need to worry about that if you just 
use public CRITICAL_SECTION APIs.



Jacek



Re: Adding a new thread model to GCC

2022-10-24 Thread Jacek Caban via Gcc-patches

On 10/24/22 05:40, LIU Hao via Gcc-patches wrote:

在 2022/10/21 20:34, i.nix...@autistici.org 写道:


got it...
anyway it seems logical to me the way I proposed :)




Below is a message forwarded from mingw-w64-public, elaborating the 
necessity of a new thread model.


As there are objections from other mingw-w64 developers, I am putting 
those patches against mingw-w64-crt on hold for now. Despite that, all 
threading facilities - mutexes, condition variables, once flags, etc. 
- are still fully functional within the mcf thread model.


In addition, I will keep maintaining my personal builds (from GCC 12 
release branch) with these patches at https://gcc-mcf.lhmouse.com/.



 Forwarded Message 
在 2022/10/23 18:06, Jacek Caban 写道:
>
> Please, let's not do that. It's possible to fix existing 
implementations, we don't need to make

> things more complicated than they are.
>

Okay okay, I think I have to compose a thorough list of problems that 
we are facing at the moment, and had better have a permalink to the 
mailing list archive that I can reference elsewhere. I have been tired 
of repeating the same grounds of arguments again and again:



1. In a DLL, destructors of static objects and callbacks that are 
registered
    with `atexit()`, are executed by `LdrShutdownProcess()`, after all 
the other
    thread have been terminated `ZwTerminateProcessO(NULL, status)`. 
This means
    that, if another thread has been terminated while holding a mutex, 
the mutex
    can never get unlocked. If a destructor attempts to lock the same 
mutex,
    deadlocks will occur. Destructors of executables do not suffer 
from this

    issue, because they are executed before `RtlExitUserProcess()`.

    Standard behavior: Static destructors and exit callbacks should be 
executed
    while other threads are running. If another thread attempts to 
access a
    destroyed object, the behavior is undefined; the user is 
responsible to

    prevent this from happening, by joining or suspending it.


2. Following 1, in a DLL, static destructors and exit callbacks are still
    invoked when `_Exit()` or `quick_exit()` is called.

    Standard behavior: `_Exit()` should not perform any cleanup; not 
even open
    files are flushed. `quick_exit()` shall invoke all quick-exit 
callbacks in

    reverse order, then call `_Exit()`.


3. There is a use-after-free bug [1] about thread-local destructors. I 
suspect

    this is caused by emutls, because GCC uses `__cxa_thread_atexit()` to
    register thread-local destructors, which could interleave with
    `emutls_destroy()`.

    Standard behavior: This is not allowed to happen. mcfgthread 
solves this

    issue by running thread-local destructors and thread-specific key
    destructors as two separate passes [3].

    [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80816
    [2] 
https://github.com/gcc-mirror/gcc/blob/f84e4fb44aa26b71fbc64e0532fd24d96e5caa3f/libgcc/emutls.c#L96
    [3] 
https://github.com/lhmouse/mcfgthread/blob/63e034d375caf585e2921cd3455f1048feb2172d/src/xglobals.c#L249



4. In the win32 thread model, thread-specific key destructors are 
called at

    process exit [4], after static destructors.

    Standard behavior: They shall be called only when a thread exits, 
and the
    associated thread-specific values are not a null pointer. They 
shall not be

    called when a program terminates; instead, users are responsible for
    deallocating such resources before calling `exit()`. This 
requirement is
    missing in POSIX, but formally specified by ISO/IEC 9899:2017, as 
the 4th

    paragraph in '7.26.6.1 The tss_create function'.

    [4] 
https://github.com/mingw-w64/mingw-w64/blob/d0a034a04d312434b842c4869a8a900568d8db98/mingw-w64-crt/crt/tlsthrd.c#L134



Those 4 points describes problems that you solve in the new threading 
model, but there is no reason they can't be fixed for existing threading 
models. In fact, ideally they would be fixed for all threading models. 
Except now we need to worry about one more threading model, meaning that 
future bugs will be even harder to fix.





5. Wait operations, of timed mutexes and condition variables, should take
    absolute time points as `struct timespec`.

    Standard behavior: Both POSIX and ISO C specifies them as such, 
while all
    Windows APIs take relative durations as a 32-bit integer of 
milliseconds,

    which can also easily get overflown.



This also may be supported in existing threading models. Overflow is 
trivial to fix by waiting in a loop. (There are other reasons why OS 
support for absolute timeout is slightly better, but the price of this 
design decision makes it questionable. I plan to elaborate more on that 
on mingw ML, but I need to find time to do a bit of research first).



Jacek