Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARM Unittest Failures #14

Closed
ghost opened this issue Dec 15, 2011 · 13 comments
Closed

ARM Unittest Failures #14

ghost opened this issue Dec 15, 2011 · 13 comments
Labels

Comments

@ghost
Copy link

ghost commented Dec 15, 2011

$ ./unit_tests 
run test__pattern ...
0 error(s) detected

run test__yield_interface ...
ERROR in file test__yield_interface.cpp on line 67 => ((yielded_state()) == (yield_state::done))
1 error(s) detected

run test__ripemd_160 ...
0 error(s) detected

run test__primitive_variant ...
0 error(s) detected

run test__uniform_type ...
0 error(s) detected

run test__intrusive_ptr ...
0 error(s) detected

run test__type_list ...
0 error(s) detected

run test__tuple ...
0 error(s) detected

run test__serialization ...
0 error(s) detected

run test__spawn ...
^C

The last test hangs indefinitely. I'm not sure how to proceed with testing this, any thoughts?

@Neverlord
Copy link
Member

First of all: thank you for your work try porting libcppa to ARM! What system are you using? What compiler version?

Yielding is an essential component of the cooperative actor scheduling. If this doesn't work, the scheduler doesn't work. That's why test spawn is stuck in a deadlock. Either the ucontext API doesn't work as expected or the yield interface doesn't work. The yield interface uses "__thread" variables of GCC, see src/yield_interface.cpp. Is this feature available on ARM?
If the yield interface does work correctly, then you might try to fix the cppa::fiber implementation for ARM. It uses "ucontext.h" on Unix machines.

Good luck!

@ghost
Copy link
Author

ghost commented Dec 15, 2011

System is a Tegra 2 (in a Trim Slice - http://trimslice.com/) running Arch Linux ARM with GCC 4.6.2. Kernel is 2.6.38.3 (I can't upgrade to 3.1 due to some hardware support issues).

I recall reading at some point that the ucontext API is deprecated? I'll look into it.
It seems safe to assume that GCC intrinsics would either be available or cause an error; anything else would be a broken design.

I'll take a closer look.

@ghost
Copy link
Author

ghost commented Dec 15, 2011

It looks like the ucontext API has been removed from the POSIX standard, but I don't know whether that's considered deprecation or not.
As for this specific issue, setcontext seems to be a noop on my system. I'll see if I can figure out why.

@ghost
Copy link
Author

ghost commented Dec 15, 2011

As far as I can tell, because ucontext has been removed from the POSIX standard, it will remain on platforms where it's already implemented but will not be ported to new platforms. Apparently ARM falls into the latter category. There are supposed to be linker warnings that getcontext/setcontext will always fail, but I don't see them for some reason (even when building 5 line ucontext demo applications).
I'll see if there's any effort inside glibc to get this API implemented on ARM, but it seems the general recommendation is to fall back to setjmp/longjmp and friends and avoid ucontext.

@Neverlord
Copy link
Member

Well, the default actor implementation needs an own stack. Thus, setjmp/longjmp doesn't help much. What about GNU pth? It should be relatively easy to port libcppa from ucontext to GNU pth if it does work on ARM.

@ghost
Copy link
Author

ghost commented Dec 17, 2011

I just wrote a sample program, and pth does seem to be working. Given that the current attitude in glibc is that ucontext is deprecated and should be avoided, pth does look like a good alternative.
On the other hand, pth doesn't look like it runs on Windows (but ucontext probably doesn't either).

@Neverlord
Copy link
Member

I just read the GNU pth documentation for porting libcppa to it, but it's not possible since GNU pth implements its own single-threaded scheduling. Sorry! I thought pth provides primitives for context switching but its a different approach to ucontext. I will search for an alternative. I'm really sorry for wasting your time. :/

Btw, Microsoft implemented its own user-space threading library called fibers: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682661(v=vs.85).aspx
It's not an issue and there is already a port included in libcppa. However, the problem with Windows right now is the lack of a lot C++11 features in the Visual Studio compiler.

@ghost
Copy link
Author

ghost commented Dec 19, 2011

Alright, well, I don't know of any alternatives, but I'll poke around and see if I can find anything. I see what you mean about scheduling, though.
As for my time, don't worry about it. This library looks to be worth some of my time :)

@ghost
Copy link
Author

ghost commented Dec 19, 2011

I have yet to try it out, but this looks like it implements the abstraction you're looking for: http://www.xmailserver.org/libpcl.html
I don't know how well supported it is.

EDIT: Just tried it, and fortified glibc doesn't like it on ARM. I'll see what I can do...
EDIT AGAIN: Gah, my bad, forgot to disable source fortification when building the library (which seems to be standard practice). Looks good.

@Neverlord
Copy link
Member

Things like libpcl, libtask, etc. are too high level. All libcppa needs is swapcontext() functionality. In particular, libcppa needs a library without internal state. Thus, everything providing init() or something similar is out.
However, I browsed the GNU pth sources and it does implement its own context switching:

extern int pth_uctx_create(pth_uctx_t *);
extern int pth_uctx_make(pth_uctx_t, char *, size_t, const sigset_t *, void (*)(void *), void *, pth_uctx_t);
extern int pth_uctx_switch(pth_uctx_t, pth_uctx_t);
extern int pth_uctx_destroy(pth_uctx_t);

I will try to port libcppa to pth using only the context switching functionality of it. I guess it should be straight forward and should run on ARM since you already tested it successfully. :)

@Neverlord
Copy link
Member

I've ported libcppa to pth and poked a bit around with it. In short: it doesn't work. The unit test of the yield interface is successful, but as soon as you try to spawn an actor, your application is dead.
Pth uses signal handlers for context switching. It's a very tricky algorithm by the way (see www.gnu.org/s/pth/rse-pmt.ps). However, it fails as soon as you have more than one kernel thread. Even if one synchronizes calls to the context switching function, since it needs access to some static data.
And a single-threaded libcppa implementation is pretty useless. I would love to see libcppa running on ARM, but I don't have the time (or hardware) yet to look for an alternative ucontext implementation, resp., implement one of my own.

However, libcppa is LGPL software. Feel free to fork it and try porting it yourself (if you have the time to do so). fiber.cpp is the only file you'll need to modify.

@ghost
Copy link
Author

ghost commented Jan 8, 2012

Thanks for looking into this, and sorry it didn't wind up working.
pcl and pth both use setjmp and longjmp, along with some custom code, to duplicate swapcontext on platforms where it's not available. When I've got some time (which I probably will in the next week or so), I'll see if I can duplicate what they're doing well enough to get things working.

@Neverlord
Copy link
Member

You can disable context switching now by using ./configure CXXFLAGS="-DCPPA_DISABLE_CONTEXT_SWITCHING".

Be aware that this will cause each actor to run in its own thread unless you're using event-based actors. Btw, you always should use event-based actors anyways, since they run faster and scale better. However, a subset of libcppa is better than nothing, isn't it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant