Closed revelator closed 2 years ago
libobjc uses a different set of interfaces, which is shown in gthr-win32.h.
Having done a full grep
over GCC source, I failed to find any documentation of them.
These interfaces are neither declared nor defined in mcfgthread because I have little knowledge about ObjC. I hope somebody would fill this blank up.
The most preferred interfaces would be wrappers of current __gthread_*
ones. The reason why we need __gthread_objc_*
ones is currently unknown.
Well... why is __gthread_objc_data_tls
static
? Isn't it going to be shared across different translation units? Hmm...
Wrappers should do the trick :) might have to work a bit on the thread initializers but the rest should be pretty straight forward.
might have to work a bit on the thread initializers ...
Thread initializers? __gthread_t
needs no initialization. Upon failure of __gthread_create()
the TID is undefined and should not be used.
men't in regards to the objc gthread_objc_init_thread_system and gthread_objc_close_thread_system initers, or can they be removed safely ?.
also not sure what to do about gthread_objc_thread_set_priority gthread_objc_thread_get_priority, does mcf have any special case for thread priority ?.
That is exactly my question. I don't know what those *_thread_system()
functions are supposed to do.
The thread priority interfaces can be implemented via native Win32 APIs, although at the moment no __gthread_t
-to-HANDLE
translation function is provided, as it would require locking and unlocking a global mutex and the HANDLE
could get closed by another thread once the global mutex is unlocked. Well, a callback is an option.
Ill see if i can get some of the mingw.org devs onboard for this, should also be rather interesting for them since the old pthread library which they still use had to be patched again recently for use with gcc-5 (it was utterly broken). So my best guess would be that they will say hell yes to a thread library that uses native windows thread functions. Well besides that they want to keep compatibility with older windows like XP which might be a problem, but lets see.
Quoting from
/* Allocate a condition. */
int
__gthread_objc_condition_allocate (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
/* Deallocate a condition. */
int
__gthread_objc_condition_deallocate (objc_condition_t __UNUSED_PARAM(condition))
{
/* Unimplemented. */
return -1;
}
/* Wait on the condition */
int
__gthread_objc_condition_wait (objc_condition_t __UNUSED_PARAM(condition),
objc_mutex_t __UNUSED_PARAM(mutex))
{
/* Unimplemented. */
return -1;
}
This is good news for us, isn't it? XD
Would you please test whether mcfgthread.dll works on Windows XP?
I have been trying to minimize dependency on third-party libraries, including the infamous MSVCR*
and libgcc*
whatsoever. The keyed event is said to be inefficient on Windows XP because of linked list implementation which has been changed to BST since Vista, but nonetheless it should work. I have no XP at hand.
[edit] mcfgthread isn't said to work on XP, but isn't said not to work there either.
Dont have XP myself anymore but ill ask around, i do know quite a few devs who still work with it.
posted on mingw.org directing to this site, so help might be incomming ;)
@revelator link please? :>
NVM found it on their ML.
You are wrong about why XP isn't explicitly supported. It isn't lack of native TLS functions that is the reason; it is imperfectness of keyed events on XP that is the reason.
Corrected the mistake, and Eli Zaretski is willling to test it on XP but i have to provide the gcc build because it seems to be rather hard to do on XP.
P.s sorry about the delay i was at my friends birthday party.
It doesn't matter. :>
I have been bootstrapping GCC 6 for a couple of months now, but not the mingw (non=w64) one. I wonder how they are going to react to it. The two projects seem not getting on well with each other.
Dunno, but since its a library much like pthreads i dont see why it should be a problem for them :) might even spur some crosswork which would benefit both distros. Btw i tried building mcfgthread with the mingw.org compiler but it needs some rework to build with there api since its lacking things like winternl.h and has ntstatus.h in the ddk folder. But i think i can have the port done shortly.
Btw i tried building mcfgthread with the mingw.org compiler but it needs some rework to build with there api since its lacking things like winternl.h and has ntstatus.h in the ddk folder.
Try removing those headers and adding declarations/definitions manually such as typedef LONG NTSTATUS;
and #define NT_SUCCESS(x) ((LONG)(x) >= 0)
.
Got most of the things ironed out, but it fails to import the Nt functions.
mingw32-gcc -O3 -ffunction-sections -fdata-sections -shared -static -nostdlib -Wl,-e@MCFCRT_DllStartup,-subsystem,windows,--disable-runtime-pseudo-reloc,--disable-auto-import -Wl,--disable-stdcall-fixup,--enable-auto-image-base,--export-all-symbols,--out-implib,libmcfgthread.dll.a -Wl,-s,--gc-sections -o mcfgthread-6.dll src/env/avl_tree.o src/env/bail.o src/env/clocks.o src/env/condition_variable.o src/env/gthread.o src/env/c11thread.o src/env/heap.o src/env/mutex.o src/env/once_flag.o src/env/thread.o src/env/thread_env.o src/env/_seh_top.o src/ext/assert.o src/ext/itow.o src/ext/wcpcpy.o src/dll_startup.o -lkernel32 -lntdll
src/env/condition_variable.o:condition_variable.c:(.text$_MCFCRT_WaitForConditionVariable+0x87): undefined reference to _imp__NtWaitForKeyedEvent@16' src/env/condition_variable.o:condition_variable.c:(.text$_MCFCRT_WaitForConditionVariableForever+0x29): undefined reference to
_impNtWaitForKeyedEvent@16'
src/env/condition_variable.o:condition_variable.c:(.text$_MCFCRT_SignalConditionVariable+0x32): undefined reference to _imp__NtReleaseKeyedEvent@16' src/env/condition_variable.o:condition_variable.c:(.text$_MCFCRT_BroadcastConditionVariable+0x39): undefined reference to
_impNtReleaseKeyedEvent@16'
src/env/mutex.o:mutex.c:(.text$_MCFCRT_WaitForMutex+0x177): undefined reference to _imp__NtWaitForKeyedEvent@16' src/env/mutex.o:mutex.c:(.text$_MCFCRT_WaitForMutexForever+0x93): undefined reference to
_impNtWaitForKeyedEvent@16'
src/env/mutex.o:mutex.c:(.text$_MCFCRT_SignalMutex+0x36): undefined reference to _imp__NtReleaseKeyedEvent@16' src/env/once_flag.o:once_flag.c:(.text$_MCFCRT_WaitForOnceFlag+0xb3): undefined reference to
_impNtWaitForKeyedEvent@16'
src/env/once_flag.o:once_flag.c:(.text$_MCFCRT_WaitForOnceFlag+0x17e): undefined reference to _imp__NtWaitForKeyedEvent@16' src/env/once_flag.o:once_flag.c:(.text$_MCFCRT_WaitForOnceFlagForever+0x5b): undefined reference to
_impNtWaitForKeyedEvent@16'
src/env/once_flag.o:once_flag.c:(.text$_MCFCRT_SignalOnceFlagAsFinished+0x3d): undefined reference to _imp__NtReleaseKeyedEvent@16' src/env/once_flag.o:once_flag.c:(.text$_MCFCRT_SignalOnceFlagAsAborted+0x45): undefined reference to
_imp__NtReleaseKeyedEvent@16'
collect2.exe: fejl: ld returnerede afslutningskoden 1
make[1]: * [mcfgthread-6.dll] Error 1
make[1]: Leaving directory `/home/Ralph/mcfgthread/build_i386'
make: * [all] Error 2
I suspect the mingw.org compiler does not have these symbols at all as a grep showed me they dont exist. So in order to make this work i have to guess that the devs have to implement these before it will build. Not sure what to do next.
Try linking against NTDLL directly by adding ntdll.dll
to LDFLAGS
(this differs from what you typically do with a .a library where -lntdll
is added instead). Newer versions of binutils should work with this.
Try applying
this patch then compiling with gcc $(find src -name '*.c') -o mcfgthread-6.dll -shared -nostdlib -lkernel32 /c/Windows/System32/ntdll.dll -masm=intel -Wl,-e@__MCFCRT_DllStartup
.
This is only a quick fix. You are going to need to copy those command line options in Makefile.am too.
Closer but still no cigar.
gcc $(find src -name '*.c') -o mcfgthread-6.dll -shared -nostdlib -lkernel32 /c/Windows/System32/ntdll.dll -masm=intel -Wl,-e@__MCFCRT_DllStartup
X:\Temp\ccxzxBxs.o:c11thread.c:(.text+0x6e): undefined reference to _MCFCRT_InitializeConditionVariable' X:\Temp\ccxzxBxs.o:c11thread.c:(.text+0x2b4): undefined reference to
_MCFCRT_InitializeMutex'
X:\Temp\ccxzxBxs.o:c11thread.c:(.text+0x1187): undefined reference to _MCFCRT_InitializeConditionVariable' X:\Temp\ccAgFg96.o:gthread.c:(.text+0x18e): undefined reference to
_MCFCRT_InitializeMutex'
X:\Temp\ccAgFg96.o:gthread.c:(.text+0x401): undefined reference to _MCFCRT_InitializeConditionVariable' X:\Temp\ccAgFg96.o:gthread.c:(.text+0xf98): undefined reference to
_MCFCRT_InitializeConditionVariable'
Though now it seems to fail on some internals instead.
Sorry, that was a bug due to different semantics of inline
in C and C++. I fixed it today. Please pull and try again.
Yep builds now and i fixed the rest of the build chain to also work with the mingw.org compiler :all test passes ) shall i push my changes upstream ?
You can fork this project and make changes to your fork and push them.
Personally, I am not willing to create a branch for MinGW.org, simply because that I am unable to, and not going to, maintain it. It would eventually be found broken by someone, when I would not be able to fix it. It is not what people do to earn others' respect. Such a fork should be created and maintained by some MinGW.org enthusiasts, and I am not that person.
My changes don't affect mingw-w64 as far as i can see they still build and work, so the only maintainance would be if something radically changes, but sure i can make a fork for the mingw.org team which only needs to be kept in sync with future changes :)
How could we be off-topic so far. XD XD XD If you could fix the libobjc problem please submit a Pull Request. I am glad to review and merge it.
Still working on that part :) if i get anywhere with it i will.
Provided a build of gcc-5.4.0 built against the mingw.org api and the modified mcfgthread library to Eli Zaretski. I should ask from him if there are any particular tests on XP that you wanted him to try out ?. I suggested to him trying to build something that relies on C++11 to see if the thread library would be stable, but maybe you have a better idea of what we need to test.
I haven't had time to write my own testsuites. :joy: The libstdc++ ones are known to be broken #8. We had better find some more, for example, the libc++ one from llvm.org.
That might work :) i suspect if its stable when built then we can safely assume success.
Btw, loads of discussion about this library now on mingw.org having a hard time with all the questions though, so feel free to drop in :)
Out of curiosity, why didn'you just fork this project using the button that GitHub provides in the upper right corner... It would be much easier to synchronizewith the upstream.
Would have had to patch in my own changes then anyway :) i was a little afraid i might goof it up now that i finally got it working to take that approach.
But now that i have baseline i can just make a diff from git and the changes should be trackable.
Would you please take a look at #9? The description is cryptic but the code in the post should explain what happened.
But now that i have baseline i can just make a diff from git and the changes should be trackable.
Having a branch synchronized with the upstream, git merge foo-upstream/master
or git rebase foo-upstream/master
does that for you.
Still a lot i dont know about git :) but thanks for pointing that out.
Taking a look at the link now.
GitHub has some manuals about forking projects. I recommend you have a look.
A new implementation function named __MCFCRT_MopthreadCreateDetached()
has been added in src/env/thread_env.h
in 9f1dfa87615837ec8b39886b4ae97abad3edb597.
Strictly speaking, it is an error to detach a thread in a hosted environment, because no guaranteed destruction of objects would be made thereafter. The function is added as a counterpart of std::quick_exit()
, which is apparently a flimsy excuse.
What the f@#k is this thing??!
F@#K YOU GNU PEOPLE! F@#K YOU!!
strangely enough objc and objc++ are now building without any code changes ?, im not sure if it defaults to the win32 thread model but i suspect it does. So far it seems to work just fine with gcc-5.4.0 and gcc-6.2.0 allthough im cursing some changes in the latter gcc that breaks previously building sources like codelite, which seems to have a problem with using the restrict keyword and some that simply break due to incopatibilities with gnuc++14. Ive done some work updating the old TDM eh wrapper code for building stuff that only relies on windows libraries and still being able to throw exceptions across dll borders, so far with great success :) and its quite fast using your thread library.
Thanks for your feedback. :joy:
Np and happy new year :)
Ok newer got around to explain why it would sometimes fail to build libobjc, been on hiatus because i had a serious back injury which needed repair.
The problem i found out was that the main header for mcf in gcc builds needed a guard. Been a while so i cannot remember the exact name of the header in question, so i will have a look again shortly.
After introducing this guard it builds every time :) and all test pass.
Sorry if the thread got a little derailed, i was swamped with requests from around the scene so it turned into a feature request instead of getting to the real beef of fixing this bug.
But it would also seem you fixed it yourself so should i commence ?
Ok newer got around to explain why it would sometimes fail to build libobjc, been on hiatus because i had a serious back injury which needed repair.
May God bless you. :bouquet:
The problem i found out was that the main header for mcf in gcc builds needed a guard. Been a while so i cannot remember the exact name of the header in question, so i will have a look again shortly.
That would be strange, because if you had had a look at the link I posted above, you would see quite a few objc functions, which have not been implemented by anyone so far. It could be possible to build libobjc successfully, but I doubt whether it will be operational.
Indeed libobjc uses its own wrappers around win32 thread functions but one in particular got imported (or atleast it tried to import it) from mcf because of the lacking guard. After implementing this guard it builds and works :) but it does not use mcf sadly.
tbh i think a major rewrite of libobjc needs to be done to take advantage of mcf, the standard version built is lobotomized in several parts, but it works well enough to build gnustep which is objc. I cannot speak for other sources though.
在 2018/7/26 23:32, Ralph Engels 写道:
Indeed libobjc uses its own wrappers around win32 thread functions but one in particular got imported (or atleast it tried to import it) from mcf because of the lacking guard. After implementing this guard it builds and works :) but it does not use mcf sadly.
The rule of thumb is that I don't and am not willing to maintain stuff that I am unfamiliar with. I probably will add a guard if it is an easy matter (e.g. a macro consisting one or two lines or so). Otherwise it will not be accepted unless someone claims maintenance of it.
-- Best regards, LH_Mouse
tbh i think a major rewrite of libobjc needs to be done to take advantage of mcf, the standard version built is lobotomized in several parts, but it works well enough to build gnustep which is objc. I cannot speak for other sources though.
This would be, of course, the satisfactory solution. If you are interested in it, you may provide an implementation. There is some detailed documentation. All existent source code in gthread.h can be examined for reference.
Understandable, this should be the gcc devs job.
I can make an effort to get the code ready for libobjc, replacing the wrappers in libobjc's code (most of them are empty anyway, and are just dummies for unimplemented windows threading functions).
Would be funny to see what the end result would be with real working thread functions instead of the dummies :), might be positively beaming even hehe.
Gave it a go with a gcc-5.4.0 bootstrap and most of it builds but it keels over on objc it seems.
libtool: link: /f/projects/runtime/_gccbuild32/./gcc/xgcc -B/f/projects/runtime/_gccbuild32/./gcc/ -L/mingw32/i686-w64-mgw32/lib/ -isystem /mingw32/i686-w64-mingw32/include -isystem /mingw32/i686-w64-mingw32/sys-include -shared .libs/NX/init.o .libs/ivars.o .libs/memory.o .libs/methods.o .libs/nil_method.o .libs/objc-foreach.o .libs/objc-sync.o .libs/obj -shared-libgcc -o .libs/libobjc-4.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libobjc.dll. .libs/thr.o: I funktionen "objc_mutex_allocate": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:260: undefined reference to
__gthread_objc_mutex_allocate' .libs/thr.o: I funktionen "objc_mutex_lock": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:316: undefined reference to
gthread_objc_thread_id' f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:321: undefined reference to__gthread_objc_mutex_lock' .libs/thr.o: I funktionen "objc_mutex_deallocate": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:291: undefined reference to
gthread_objc_mutex_deallocate' .libs/thr.o: I funktionen "objc_mutex_trylock": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:346: undefined reference to__gthread_objc_thread_id' f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:351: undefined reference to
__gthread_objc_mutex_trylock' .libs/thr.o: I funktionen "objc_mutex_unlock": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:378: undefined reference to `__gthread_objc_thread_id' .libs/thr.o: I funktionen "objc_thread_detach"::/projects/runtime/gcc-5.4.0/libobjc/thr.c:169: undefined reference to
__gthread_objc_thread_detach' .libs/thr.o: I funktionen "objc_thread_set_data": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:235: undefined reference to
gthread_objc_thread_set_data' .libs/thr.o: I funktionen "objc_condition_allocate": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:415: undefined reference to `gthread_objc_condition_allocate' .libs/thr.o: I funktionen "objc_condition_broadcast": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:498: undefined reference to__gthread_objc_condition_broadcast' .libs/thr.o: I funktionen "objc_condition_deallocate": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:439: undefined reference to
gthread_objc_condition_deallocate' .libs/thr.o: I funktionen "objc_condition_wait": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:465: undefined reference to__gthread_objc_thread_id' f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:478: undefined reference to
gthread_objc_condition_wait' .libs/thr.o: I funktionen "_objc_init_thread_system": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:78: undefined reference to__gthread_objc_init_thread_system' .libs/thr.o: I funktionen "objc_thread_set_priority": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:189: undefined reference to
gthread_objc_thread_set_priority' .libs/thr.o: I funktionen "objc_thread_get_priority": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:196: undefined reference to__gthread_objc_thread_get_priority' .libs/thr.o: I funktionen "objc_thread_yield": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:205: undefined reference to
__gthread_objc_thread_yield' .libs/thr.o: I funktionen "objc_thread_id": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:227: undefined reference to`gthread_objc_thread_id' .libs/thr.o: I funktionen "objc_thread_set_data": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:235: undefined reference to__gthread_objc_thread_set_data' .libs/thr.o: I funktionen "objc_thread_get_data": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:243: undefined reference to
gthread_objc_thread_get_data' .libs/thr.o: I funktionen "objc_mutex_unlock": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:391: undefined reference to `gthread_objc_mutex_unlock' .libs/thr.o: I funktionen "objc_thread_exit": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:219: undefined reference to__gthread_objc_thread_exit' .libs/thr.o: I funktionen "objc_condition_broadcast": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:498: undefined reference to
__gthread_objc_condition_broadcast' .libs/thr.o: I funktionen "objc_condition_signal": f:/projects/runtime/gcc-5.4.0/libobjc/thr.c:512: undefined reference to__gthread_objc_condition_signal' collect2.exe: error: ld returned 1 exit status make[2]: **\* [libobjc.la] Error 1 make[2]: Leaving directory
/f/projects/runtime/_gccbuild32/i686-w64-mingw32/libobjc' make[1]: [all-target-libobjc] Error 2 make[1]: Leaving directory`/f/projects/runtime/_gccbuild32' make: \ [all] Error 2