lhmouse / mcfgthread

Cornerstone of the MOST efficient std::thread on Windows for mingw-w64
https://gcc-mcf.lhmouse.com/
Other
277 stars 28 forks source link

libobjc not building #6

Closed revelator closed 2 years ago

revelator commented 8 years ago

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 togthread_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 togthread_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 togthread_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 togthread_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 togthread_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 togthread_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 togthread_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

lhmouse commented 8 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.

lhmouse commented 8 years ago

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...

revelator commented 8 years ago

Wrappers should do the trick :) might have to work a bit on the thread initializers but the rest should be pretty straight forward.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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 ?.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

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

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

Dont have XP myself anymore but ill ask around, i do know quite a few devs who still work with it.

revelator commented 8 years ago

posted on mingw.org directing to this site, so help might be incomming ;)

lhmouse commented 8 years ago

@revelator link please? :>

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

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).

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

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.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

Sorry, that was a bug due to different semantics of inline in C and C++. I fixed it today. Please pull and try again.

revelator commented 8 years ago

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 ?

lhmouse commented 8 years ago

You can fork this project and make changes to your fork and push them.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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 :)

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

Still working on that part :) if i get anywhere with it i will.

revelator commented 8 years ago

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.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

That might work :) i suspect if its stable when built then we can safely assume success.

revelator commented 8 years ago

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 :)

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

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.

revelator commented 8 years ago

But now that i have baseline i can just make a diff from git and the changes should be trackable.

lhmouse commented 8 years ago

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.

revelator commented 8 years ago

Still a lot i dont know about git :) but thanks for pointing that out.

Taking a look at the link now.

lhmouse commented 8 years ago

GitHub has some manuals about forking projects. I recommend you have a look.

lhmouse commented 8 years ago

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.

lhmouse commented 8 years ago

What the f@#k is this thing??!

F@#K YOU GNU PEOPLE! F@#K YOU!!

revelator commented 7 years ago

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.

lhmouse commented 7 years ago

Thanks for your feedback. :joy:

revelator commented 7 years ago

Np and happy new year :)

revelator commented 6 years ago

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 ?

lhmouse commented 6 years ago

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.

revelator commented 6 years ago

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.

revelator commented 6 years ago

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.

lhmouse commented 6 years ago

在 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

lhmouse commented 6 years ago

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.

revelator commented 6 years ago

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.