Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
> 0) complexifies comparison of thread IDs without obvious benefits, and The reverse argument is also true: using IDs would complexify everything else with the only benefit of simplifying the equal primitive. > 1) does not work reliably because handles can be duplicated, and That's pure FUD. > 2) makes `__gthread_self()` return invalid handles in detached threads. Admittedly, but this can be fixed if this is deemed necessary by clearing the thread descriptor when detaching the thread. -- Eric Botcazou ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
在 2019/7/29 22:43, JonY 写道: > > Any updates? > No. I am still under the impression that using thread handles as `std::thread::id`s: 0) complexifies comparison of thread IDs without obvious benefits, and 1) does not work reliably because handles can be duplicated, and 2) makes `__gthread_self()` return invalid handles in detached threads. -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 7/3/19 12:55 PM, Liu Hao wrote: > 在 2019/7/2 下午8:27, Jonathan Wakely 写道: >> >> What do you mean by "unclosed thread"? If I read it correctly, the MSDN >> page >> refers to closing a handle (which makes sense), not closing a thread. >> > > Yes, it meant a thread which has terminated but not deleted due to some > handles left open. > > >>> This could also mean that there is no effect way to denote a thread >>> uniquely. As a consequence libstdc++ may have to its own bookkeeping >>> mechanism. >> >> As I said in my last mail, libstdc++ does not need a way to denote a >> thread uniquely. >> > > At my last glance at the `__gthread_` interfaces, libstdc++ requires > thread IDs to be LessThanComparable, which would require retrieval of > thread IDs by handle, as in `__gthread_equal()`. > > More than that, if my previous vision was correct (a terminated thread > has no ID associated) then `GetThreadId()` on a thread that has > terminated would not return a valid thread ID. Fortunately, this seems > not the case: > > ```c > #include > #include > > DWORD __stdcall ThreadProc(void* pParam) > { > printf("thread %lu running\n", GetCurrentThreadId()); > return 0; > } > > int main(void) > { > HANDLE hThread = CreateThread(0, 0, ThreadProc, 0, CREATE_SUSPENDED, 0); > printf("thread %lu created\n", GetThreadId(hThread)); > > ResumeThread(hThread); > WaitForSingleObject(hThread, INFINITE); > printf("thread %lu terminated\n", GetThreadId(hThread)); > > CloseHandle(hThread); > // `hThread` is now invalid; DO NOT PLAY WITH THIS AT HOME! > printf("thread %lu closed\n", GetThreadId(hThread)); > } > ``` > > This program outputs > > ```text > E:\Desktop>gcc test.c -Wall -Wextra -Wpedantic && a.exe > test.c: In function 'ThreadProc': > test.c:4:34: warning: unused parameter 'pParam' [-Wunused-parameter] > 4 | DWORD __stdcall ThreadProc(void* pParam) > |~~^~ > thread 9172 created > thread 9172 running > thread 9172 terminated > thread 0 closed > > E:\Desktop> > ``` > > Despite Microsoft's documentation, the identifier of a thread seems > uncollected as long as there are still handles to the thread. So it > might be safe to assume that the identifier of an `std::thread` *cannot* > be reused before it is `join()`'d or `detach()`'d which closes the > handle stored in the `std::thread` object. > > Any updates? signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/19 12:15 +0200, Jacek Caban wrote: On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. I meant unique, not identical. The C++ standard says: "The library may reuse the value of a thread::id of a terminated thread that can no longer be joined." So that's not a reason to use a handle. ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
> It seems inappropriate to use handles as thread identifiers (as handles > imply resource ownership and are not unique identifiers); thread IDs (as > `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. -- Eric Botcazou ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/19 20:14 +0800, Liu Hao wrote: 在 2019/7/2 下午8:00, Jonathan Wakely 写道: The C++ standard says: "The library may reuse the value of a thread::id of a terminated thread that can no longer be joined." So that's not a reason to use a handle. According to MSDN [1] a thread ID is valid 'until the thread has been terminated' so I presume a terminated but unclosed thread does not have a thread ID. What do you mean by "unclosed thread"? If I read it correctly, the MSDN page refers to closing a handle (which makes sense), not closing a thread. This could also mean that there is no effect way to denote a thread uniquely. As a consequence libstdc++ may have to its own bookkeeping mechanism. As I said in my last mail, libstdc++ does not need a way to denote a thread uniquely. I'm not objecting to Eric's use of a HANDLE for a thread::id, as his justification makes sense. I'm just saying we don't need a unique ID that outlives the thread, because that's not a requirement. [1] https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-handles-and-identifiers -- Best regards, LH_Mouse ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
在 2019/7/2 下午8:27, Jonathan Wakely 写道: > > What do you mean by "unclosed thread"? If I read it correctly, the MSDN > page > refers to closing a handle (which makes sense), not closing a thread. > Yes, it meant a thread which has terminated but not deleted due to some handles left open. >> This could also mean that there is no effect way to denote a thread >> uniquely. As a consequence libstdc++ may have to its own bookkeeping >> mechanism. > > As I said in my last mail, libstdc++ does not need a way to denote a > thread uniquely. > At my last glance at the `__gthread_` interfaces, libstdc++ requires thread IDs to be LessThanComparable, which would require retrieval of thread IDs by handle, as in `__gthread_equal()`. More than that, if my previous vision was correct (a terminated thread has no ID associated) then `GetThreadId()` on a thread that has terminated would not return a valid thread ID. Fortunately, this seems not the case: ```c #include #include DWORD __stdcall ThreadProc(void* pParam) { printf("thread %lu running\n", GetCurrentThreadId()); return 0; } int main(void) { HANDLE hThread = CreateThread(0, 0, ThreadProc, 0, CREATE_SUSPENDED, 0); printf("thread %lu created\n", GetThreadId(hThread)); ResumeThread(hThread); WaitForSingleObject(hThread, INFINITE); printf("thread %lu terminated\n", GetThreadId(hThread)); CloseHandle(hThread); // `hThread` is now invalid; DO NOT PLAY WITH THIS AT HOME! printf("thread %lu closed\n", GetThreadId(hThread)); } ``` This program outputs ```text E:\Desktop>gcc test.c -Wall -Wextra -Wpedantic && a.exe test.c: In function 'ThreadProc': test.c:4:34: warning: unused parameter 'pParam' [-Wunused-parameter] 4 | DWORD __stdcall ThreadProc(void* pParam) |~~^~ thread 9172 created thread 9172 running thread 9172 terminated thread 0 closed E:\Desktop> ``` Despite Microsoft's documentation, the identifier of a thread seems uncollected as long as there are still handles to the thread. So it might be safe to assume that the identifier of an `std::thread` *cannot* be reused before it is `join()`'d or `detach()`'d which closes the handle stored in the `std::thread` object. -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02.07.2019 14:58, Jacek Caban wrote: > On 7/2/19 1:35 PM, LRN wrote: >> On 02.07.2019 13:42, Jacek Caban wrote: >>> On 02/07/2019 12:38, LRN wrote: On 02.07.2019 13:15, Jacek Caban wrote: > On 02/07/2019 12:12, Jacek Caban wrote: >> On 02/07/2019 11:57, Liu Hao wrote: >> >>> 在 2019/7/2 下午5:19, Eric Botcazou 写道: > It seems inappropriate to use handles as thread identifiers (as > handles > imply resource ownership and are not unique identifiers); thread > IDs (as > `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. >>> The `OpenThread()` function can obtain a handle by thread ID. It returns >>> a real handle that has to be closed when it is out of use. Using the >>> pseudo handle returned by `GetCurrentThread()` may be more efficient if >>> the target thread ID is equal to `GetCurrentThreadId()`. >> The problem with thread id is that it's not valid nor guaranteed to be >> identical after the thread is terminated. A handle needs to be used >> for that. > I meant unique, not identical. > According to linux.die.net[0], Linux kernel re-uses thread IDs. This stackoverflow answer[1] claims that this applies to all POSIX threads implementations, citing opengroup spec[2]. >>> >>> It will not reuse them until you detach or join the thread. Joining may >>> happen after the thread is terminated. >>> >> It just means that you may not be able to use Windows thread IDs for that, >> but >> using your own, homegrown thread IDs would be OK (just make sure an ID is >> valid >> until a thread is joined or detached - that would usually imply keeping >> metadata of a thread around after it's terminated). > > > That would be additional complication with additional problems. Without > a handle, there is no reliable way to detect if thread is terminated and > if it's not, you need to wait in join. Also, you'd replace handle leak > to internal data leak. > > So what you want is for the thread library to keep thread metadata around while the thread exists, then destroy that metadata when the thread terminates (preventing leaks), and still be able to respond to thread-API calls (such as join()) made from other threads toward this (now terminated) thread? I don't know W32 and POSIX thread APIs to judge whether this is actually doable that way, regardless of whether thread IDs are handles or not. signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02.07.2019 15:14, Liu Hao wrote: > 在 2019/7/2 下午8:00, Jonathan Wakely 写道: >> The C++ standard says: >> >> "The library may reuse the value of a thread::id of a terminated >> thread that can no longer be joined." >> >> So that's not a reason to use a handle. > > According to MSDN [1] a thread ID is valid 'until the thread has been > terminated' so I presume a terminated but unclosed thread does not have > a thread ID. > Good point. In NT world, as long as a handle for a resource exists, the resource itself also exists, even if it's in a state that makes it unusable. Until a handle is explicitly closed, it remains valid. Until all handles to a resource are closed, the resource exists. signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
在 2019/7/2 下午8:00, Jonathan Wakely 写道: > The C++ standard says: > > "The library may reuse the value of a thread::id of a terminated > thread that can no longer be joined." > > So that's not a reason to use a handle. According to MSDN [1] a thread ID is valid 'until the thread has been terminated' so I presume a terminated but unclosed thread does not have a thread ID. This could also mean that there is no effect way to denote a thread uniquely. As a consequence libstdc++ may have to its own bookkeeping mechanism. [1] https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-handles-and-identifiers -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 7/2/19 1:35 PM, LRN wrote: On 02.07.2019 13:42, Jacek Caban wrote: On 02/07/2019 12:38, LRN wrote: On 02.07.2019 13:15, Jacek Caban wrote: On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. I meant unique, not identical. According to linux.die.net[0], Linux kernel re-uses thread IDs. This stackoverflow answer[1] claims that this applies to all POSIX threads implementations, citing opengroup spec[2]. It will not reuse them until you detach or join the thread. Joining may happen after the thread is terminated. It just means that you may not be able to use Windows thread IDs for that, but using your own, homegrown thread IDs would be OK (just make sure an ID is valid until a thread is joined or detached - that would usually imply keeping metadata of a thread around after it's terminated). That would be additional complication with additional problems. Without a handle, there is no reliable way to detect if thread is terminated and if it's not, you need to wait in join. Also, you'd replace handle leak to internal data leak. Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02.07.2019 13:42, Jacek Caban wrote: > > On 02/07/2019 12:38, LRN wrote: >> On 02.07.2019 13:15, Jacek Caban wrote: >>> On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: > 在 2019/7/2 下午5:19, Eric Botcazou 写道: >>> It seems inappropriate to use handles as thread identifiers (as >>> handles >>> imply resource ownership and are not unique identifiers); thread >>> IDs (as >>> `DWORD` or `unsigned long`) would be a better alternative. >> This was considered but ultimately rejected, as you can do nothing >> with a >> thread Id, i.e. you need a handle for everything. But the >> __gthread_equal >> routine does compare the Ids and not the handles. >> > The `OpenThread()` function can obtain a handle by thread ID. It returns > a real handle that has to be closed when it is out of use. Using the > pseudo handle returned by `GetCurrentThread()` may be more efficient if > the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. >>> >>> I meant unique, not identical. >>> >> According to linux.die.net[0], Linux kernel re-uses thread IDs. This >> stackoverflow answer[1] claims that this applies to all POSIX threads >> implementations, citing opengroup spec[2]. > > > It will not reuse them until you detach or join the thread. Joining may > happen after the thread is terminated. > It just means that you may not be able to use Windows thread IDs for that, but using your own, homegrown thread IDs would be OK (just make sure an ID is valid until a thread is joined or detached - that would usually imply keeping metadata of a thread around after it's terminated). signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/2019 12:38, LRN wrote: On 02.07.2019 13:15, Jacek Caban wrote: On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. I meant unique, not identical. According to linux.die.net[0], Linux kernel re-uses thread IDs. This stackoverflow answer[1] claims that this applies to all POSIX threads implementations, citing opengroup spec[2]. It will not reuse them until you detach or join the thread. Joining may happen after the thread is terminated. Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02.07.2019 13:15, Jacek Caban wrote: > > On 02/07/2019 12:12, Jacek Caban wrote: >> On 02/07/2019 11:57, Liu Hao wrote: >> >>> 在 2019/7/2 下午5:19, Eric Botcazou 写道: > It seems inappropriate to use handles as thread identifiers (as > handles > imply resource ownership and are not unique identifiers); thread > IDs (as > `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. >>> The `OpenThread()` function can obtain a handle by thread ID. It returns >>> a real handle that has to be closed when it is out of use. Using the >>> pseudo handle returned by `GetCurrentThread()` may be more efficient if >>> the target thread ID is equal to `GetCurrentThreadId()`. >> >> >> The problem with thread id is that it's not valid nor guaranteed to be >> identical after the thread is terminated. A handle needs to be used >> for that. > > > I meant unique, not identical. > According to linux.die.net[0], Linux kernel re-uses thread IDs. This stackoverflow answer[1] claims that this applies to all POSIX threads implementations, citing opengroup spec[2]. [0]: https://linux.die.net/man/7/pthreads [1]: https://stackoverflow.com/questions/1693180/how-do-i-determine-if-a-detached-pthread-is-alive [2]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_02 signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/2019 12:12, Jacek Caban wrote: On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. I meant unique, not identical. Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On 02/07/2019 11:57, Liu Hao wrote: 在 2019/7/2 下午5:19, Eric Botcazou 写道: It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. This was considered but ultimately rejected, as you can do nothing with a thread Id, i.e. you need a handle for everything. But the __gthread_equal routine does compare the Ids and not the handles. The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. The problem with thread id is that it's not valid nor guaranteed to be identical after the thread is terminated. A handle needs to be used for that. Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
在 2019/7/2 下午5:19, Eric Botcazou 写道: >> It seems inappropriate to use handles as thread identifiers (as handles >> imply resource ownership and are not unique identifiers); thread IDs (as >> `DWORD` or `unsigned long`) would be a better alternative. > > This was considered but ultimately rejected, as you can do nothing with a > thread Id, i.e. you need a handle for everything. But the __gthread_equal > routine does compare the Ids and not the handles. > The `OpenThread()` function can obtain a handle by thread ID. It returns a real handle that has to be closed when it is out of use. Using the pseudo handle returned by `GetCurrentThread()` may be more efficient if the target thread ID is equal to `GetCurrentThreadId()`. -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
On Fri, Jun 28, 2019 at 7:17 PM Ruben Van Boxem wrote: > > > I'm interested in seeing real-world benchmarks when using this code! that is something i would really like too Vincent Torri ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
在 2019/6/29 上午12:10, Jacek Caban 写道: > > You don't really need to store the whole __gthr_win32_thr_desc in TLS. > If you stored just the handle, this wouldn't need a destructor. > > The handle to be stored in the TLS ('the Handle' for short hereinafter) should be a real handle, so there are a few scenarios that we should consider: 0) the Handle should be closed upon the spawned thread's exit; in this case a destructor is still necessary to prevent handle leaks. 1) the Handle is closed by the creator via either `*_join()` or `*_detach()`; in the latter case the Handle becomes invalid while the thread is running, so `*_self()` would return an invalid handle. It seems inappropriate to use handles as thread identifiers (as handles imply resource ownership and are not unique identifiers); thread IDs (as `DWORD` or `unsigned long`) would be a better alternative. -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
This is awesome! Although winpthreads was a nice in-between solution for this (and it still is a good solution for those who want a pthreads library on Windows), this is what everyone (using C++ and/or OpenMP, heck, even C11 thread support) needs of course. I'm interested in seeing real-world benchmarks when using this code! If only my build scripts still worked reliably (they never really did to be honest) I could prepare myself (and others) a nice preview of this functionality. Ruben Op vr 28 jun. 2019 om 15:43 schreef NightStrike : > FYI, Eric posted this today to the GCC patches list. This may be of > great interest to many who would prefer native threads instead of the > winpthreads posix style interface. > > Great work, Eric! I look forward to trying this out! > > -- Forwarded message - > From: Eric Botcazou > Date: Fri, Jun 28, 2019 at 6:51 AM > Subject: [patch] Reimplement GNU threads library on native Windows > To: > Cc: > > > Hi, > > this reimplements the GNU threads library on native Windows (except for the > Objective-C specific subset) using direct Win32 API calls, in lieu of the > implementation based on semaphores. This base implementations requires > Windows XP/Server 2003, which is the default minimal setting of MinGW-W64. > This also adds the support required for the C++11 threads, using again > direct > Win32 API calls; this additional layer requires Windows Vista/Server 2008 > and > is enabled only if _GTHREADS_USE_COND is defined to 1. > > This also changes libstdc++ to setting _GTHREADS_USE_COND to 1 when the > switch > --enable-libstdcxx-threads is passed, which means that C++11 threads are > still > disabled by default on native Windows and that you need to explicitly pass > the > switch to enable them. The 30_threads chapter of the testsuite is clean. > > Tested on i686-pc-mingw32 and x86_64-pc-mingw32, OK for the mainline? > > > 2019-06-28 Eric Botcazou > > libgcc/ > * config.host (i[34567]86-*-mingw*): Add thread fragment after EH > one > as well as new i386/t-slibgcc-mingw fragment. > (x86_64-*-mingw*): Likewise. > * config/i386/gthr-win32.h: If _GTHREADS_USE_COND is 1, define both > __GTHREAD_HAS_COND & __GTHREADS_CXX0X to 1 and _WIN32_WINNT to > 0x0600. > Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1. > Include stdlib.h instead of errno.h and do not include _mingw.h. > (CONST_CAST2): Add specific definition for C++. > (ATTRIBUTE_UNUSED): New macro. > (__UNUSED_PARAM): Delete. > Define WIN32_LEAN_AND_MEAN before including windows.h. > (__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of > (DWORD)-1. > (__gthread_objc_init_thread_system): Likewise. > (__gthread_objc_thread_get_data): Minor tweak. > (__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED. > (__gthread_objc_condition_deallocate): Likewise. > (__gthread_objc_condition_wait): Likewise. > (__gthread_objc_condition_broadcast): Likewise. > (__gthread_objc_condition_signal): Likewise. > Include sys/time.h. > (__gthr_win32_DWORD): New typedef. > (__gthr_win32_HANDLE): Likewise. > (__gthr_win32_CRITICAL_SECTION): Likewise. > (__gthr_win32_CONDITION_VARIABLE): Likewise. > (__gthread_t): Adjust. > (__gthread_key_t): Likewise. > (__gthread_mutex_t): Likewise. > (__gthread_recursive_mutex_t): Likewise. > (__gthread_cond_t): New typedef. > (__gthread_time_t): Likewise. > (__GTHREAD_MUTEX_INIT_DEFAULT): Delete. > (__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise. > (__GTHREAD_COND_INIT_FUNCTION): Define. > (__GTHREAD_TIME_INIT): Likewise. > (__gthr_i486_lock_cmp_xchg): Delete. > (__gthr_win32_create): Declare. > (__gthr_win32_join): Likewise. > (__gthr_win32_self): Likewise. > (__gthr_win32_detach): Likewise. > (__gthr_win32_equal): Likewise. > (__gthr_win32_yield): Likewise. > (__gthr_win32_mutex_destroy): Likewise. > (__gthr_win32_cond_init_function): Likewise if _GTHREADS_USE_COND > is 1. > (__gthr_win32_cond_broadcast): Likewise. > (__gthr_win32_cond_signal): Likewise. > (__gthr_win32_cond_wait): Likewise. > (__gthr_win32_cond_timedwait): Likewise. > (__gthr_win32_recursive_mutex_init_function): Delete. > (__gthr_win32_recursive_mutex_lock): Likewise. > (__gthr_win32_recursive_mutex_unlock): Likewise. > (__gthr_win32_recursive_mutex_destroy): Likewise. > (__gthread_create): New inline function. > (__gthread_join): Likewise. > (__gthread_self): Likewise. > (__gthread_detach): Likewise. > (__gthread_equal): Likewise. > (__gthread_yield): Likewise. > (__gthread_cond_init_function): Likewise if _GTHREADS_USE_COND is > 1. >
Re: [Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
Hi Eric, On 6/28/19 3:42 PM, NightStrike wrote: FYI, Eric posted this today to the GCC patches list. This may be of great interest to many who would prefer native threads instead of the winpthreads posix style interface. Great work, Eric! I look forward to trying this out! -- Forwarded message - From: Eric Botcazou Date: Fri, Jun 28, 2019 at 6:51 AM Subject: [patch] Reimplement GNU threads library on native Windows To: Cc: Hi, this reimplements the GNU threads library on native Windows (except for the Objective-C specific subset) using direct Win32 API calls, in lieu of the implementation based on semaphores. This base implementations requires Windows XP/Server 2003, which is the default minimal setting of MinGW-W64. This also adds the support required for the C++11 threads, using again direct Win32 API calls; this additional layer requires Windows Vista/Server 2008 and is enabled only if _GTHREADS_USE_COND is defined to 1. This also changes libstdc++ to setting _GTHREADS_USE_COND to 1 when the switch --enable-libstdcxx-threads is passed, which means that C++11 threads are still disabled by default on native Windows and that you need to explicitly pass the switch to enable them. The 30_threads chapter of the testsuite is clean. Tested on i686-pc-mingw32 and x86_64-pc-mingw32, OK for the mainline? It's indeed great to see this. Thank you! +/* The implementation strategy for the c++0x thread support is as follows. + + A GNU thread is represented by a Win32 HANDLE that is obtained when the + Win32 thread is created, except of course for the initial thread. This + Win32 HANDLE is stored in a descriptor keyed from TLS memory for every + thread, so the self routine can return it instead of having to duplicate + the pseudo-handle returned by GetCurrentThread each time it is invoked. + For the initial thread, this Win32 HANDLE is created during the first + call to the self routine using the aforementioned technique. + + Note that the equal routine compares the identifier of threads instead + of their Win32 HANDLE, which will give the correct positive answer even + in the case where distinct Win32 HANDLEs have been created for the same + thread by multiple instances of libgcc included in the link. */ Note that this will cause handle leaks if used across multiple libgcc instances, through. +#include "gthr-win32.h" + +/* The thread descriptor keyed from TLS memory. */ +struct __gthr_win32_thr_desc +{ + void *(*func) (void*); + void *args; + HANDLE h; +}; + +/* The TLS key used by one instance of the library. */ +static __gthread_key_t __gthr_win32_tls = TLS_OUT_OF_INDEXES; + +/* The initialization device for the TLS key. */ +static __gthread_once_t __gthr_win32_tls_once = __GTHREAD_ONCE_INIT; + +/* Initialize the TLS key. */ + +static void +__gthr_win32_tls_init (void) +{ + if (__gthread_key_create (&__gthr_win32_tls, free)) +abort (); +} You don't really need to store the whole __gthr_win32_thr_desc in TLS. If you stored just the handle, this wouldn't need a destructor. Thanks, Jacek ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
[Mingw-w64-public] Fwd: [patch] Reimplement GNU threads library on native Windows
FYI, Eric posted this today to the GCC patches list. This may be of great interest to many who would prefer native threads instead of the winpthreads posix style interface. Great work, Eric! I look forward to trying this out! -- Forwarded message - From: Eric Botcazou Date: Fri, Jun 28, 2019 at 6:51 AM Subject: [patch] Reimplement GNU threads library on native Windows To: Cc: Hi, this reimplements the GNU threads library on native Windows (except for the Objective-C specific subset) using direct Win32 API calls, in lieu of the implementation based on semaphores. This base implementations requires Windows XP/Server 2003, which is the default minimal setting of MinGW-W64. This also adds the support required for the C++11 threads, using again direct Win32 API calls; this additional layer requires Windows Vista/Server 2008 and is enabled only if _GTHREADS_USE_COND is defined to 1. This also changes libstdc++ to setting _GTHREADS_USE_COND to 1 when the switch --enable-libstdcxx-threads is passed, which means that C++11 threads are still disabled by default on native Windows and that you need to explicitly pass the switch to enable them. The 30_threads chapter of the testsuite is clean. Tested on i686-pc-mingw32 and x86_64-pc-mingw32, OK for the mainline? 2019-06-28 Eric Botcazou libgcc/ * config.host (i[34567]86-*-mingw*): Add thread fragment after EH one as well as new i386/t-slibgcc-mingw fragment. (x86_64-*-mingw*): Likewise. * config/i386/gthr-win32.h: If _GTHREADS_USE_COND is 1, define both __GTHREAD_HAS_COND & __GTHREADS_CXX0X to 1 and _WIN32_WINNT to 0x0600. Error out if _GTHREAD_USE_MUTEX_TIMEDLOCK is 1. Include stdlib.h instead of errno.h and do not include _mingw.h. (CONST_CAST2): Add specific definition for C++. (ATTRIBUTE_UNUSED): New macro. (__UNUSED_PARAM): Delete. Define WIN32_LEAN_AND_MEAN before including windows.h. (__gthread_objc_data_tls): Use TLS_OUT_OF_INDEXES instead of (DWORD)-1. (__gthread_objc_init_thread_system): Likewise. (__gthread_objc_thread_get_data): Minor tweak. (__gthread_objc_condition_allocate): Use ATTRIBUTE_UNUSED. (__gthread_objc_condition_deallocate): Likewise. (__gthread_objc_condition_wait): Likewise. (__gthread_objc_condition_broadcast): Likewise. (__gthread_objc_condition_signal): Likewise. Include sys/time.h. (__gthr_win32_DWORD): New typedef. (__gthr_win32_HANDLE): Likewise. (__gthr_win32_CRITICAL_SECTION): Likewise. (__gthr_win32_CONDITION_VARIABLE): Likewise. (__gthread_t): Adjust. (__gthread_key_t): Likewise. (__gthread_mutex_t): Likewise. (__gthread_recursive_mutex_t): Likewise. (__gthread_cond_t): New typedef. (__gthread_time_t): Likewise. (__GTHREAD_MUTEX_INIT_DEFAULT): Delete. (__GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT): Likewise. (__GTHREAD_COND_INIT_FUNCTION): Define. (__GTHREAD_TIME_INIT): Likewise. (__gthr_i486_lock_cmp_xchg): Delete. (__gthr_win32_create): Declare. (__gthr_win32_join): Likewise. (__gthr_win32_self): Likewise. (__gthr_win32_detach): Likewise. (__gthr_win32_equal): Likewise. (__gthr_win32_yield): Likewise. (__gthr_win32_mutex_destroy): Likewise. (__gthr_win32_cond_init_function): Likewise if _GTHREADS_USE_COND is 1. (__gthr_win32_cond_broadcast): Likewise. (__gthr_win32_cond_signal): Likewise. (__gthr_win32_cond_wait): Likewise. (__gthr_win32_cond_timedwait): Likewise. (__gthr_win32_recursive_mutex_init_function): Delete. (__gthr_win32_recursive_mutex_lock): Likewise. (__gthr_win32_recursive_mutex_unlock): Likewise. (__gthr_win32_recursive_mutex_destroy): Likewise. (__gthread_create): New inline function. (__gthread_join): Likewise. (__gthread_self): Likewise. (__gthread_detach): Likewise. (__gthread_equal): Likewise. (__gthread_yield): Likewise. (__gthread_cond_init_function): Likewise if _GTHREADS_USE_COND is 1. (__gthread_cond_broadcast): Likewise. (__gthread_cond_signal): Likewise. (__gthread_cond_wait): Likewise. (__gthread_cond_timedwait): Likewise. (__GTHREAD_WIN32_INLINE): New macro. (__GTHREAD_WIN32_COND_INLINE): Likewise. (__GTHREAD_WIN32_ACTIVE_P): Likewise. Define WIN32_LEAN_AND_MEAN before including windows.h. (__gthread_once): Minor tweaks. (__gthread_key_create): Use ATTRIBUTE_UNUSED and TLS_OUT_OF_INDEXES. (__gthread_key_delete): Minor tweak. (__gthread_getspecific): Likewise. (__gthread_setspecific): Likewise. (__gthread_mutex_init_function): Reimplement. (__gthread_mutex_destroy): Likewise. (__gthread_mutex_