Subject: Re: [boost] [context] review
From: Oliver Kowalke (oliver.kowalke_at_[hidden])
Date: 2011-03-28 04:03:34


Hello Gordon,

Am 28.03.2011 07:28, schrieb Gordon Woodhull:
> Hi Oliver,
>
> On Mar 27, 2011, at 9:22 AM, Oliver Kowalke wrote:
>> Gordon wrote:
>>> I would probably be just as happy with a slower safe cross-platform library built on OS support, as with the fast (dangerous?) assembly version.
>> On UNIX ucontext_t is deprecated by the new POSIX standard (and might not be available in the next releases of C-libs). This has its reason in the fact that the interface of makecontext() function was
>> designed before C99. It expects a function-pointer of void(*)() and accepts ellipses/var args for the arguments accepted by the function to be called by ucontext_t.
> Do you mean that the functionality might go away, or will be replaced by a new API?

yes - it is dprecated by the new POSIX standard. For instance glibc on
ARM doesn't provide ucontext anymore. that was the reason for
implementing the functionality in assembler => fcontext (without the
limitations of ucontext).

>> I'm not the big C expert but I believe following cast is not legal (even if some compilers accept it):
>>
>> void my_fn( int, char *);
>> (void(*)())my_fn; // not legal
>>
>> But the signature of ucontext-function makecontext( ucontext_t *, void(*)(), int, ...) requires this cast.
>>
>> Even worse - on x86_64/Linux the glibc the usage of non integer values as argument for the var-args is undefined. example:
>>
>> void my_fn( X * x); // to be called by ucontext
>>
>> X * x = new X("abc");
>> ucontext_t ctx;
>> makecontext(& ctx, (void(*)())(my_fn), 1, x); // not reliable; undefined behaviour
>>
>> In the example above it might work (if the high bits of the address of x are zero) but in some cases makecontext() truncates the high bit of x pointer :/
>> => segfault
>>
>> Therefore I prefer the fcontext version over ucontext because it hasn't this problem.
> Hmm. Not really following you here. My understanding was that the proposed Boost.Context only accepts void f(void*) at this time - are you describing functionality that is not exposed because you have to stay compatible with ucontext? I hope you aren't saying that the ucontext version is unreliable!

ucontext is wrapped by boost::context - and in the new version of
boost.context ucontext will be used only as fallback for platforms where
fcontext implementation isn't available.
And yes - ucontext is buggy - from its usage (invalid function pointer
cast) and behaviour (the 64bit-pointer truncation of arguments with
glibc/x86_64).

>> On Windows I suggest using the Windows Fiber version because as Holger mentioned I've to correct the exception handling.
> My preference, for all platforms, as someone who considers all this assembly stack manipulation to be (not my kind of) black magic, would be to have both a 100% safe OS implementation and a fast hand-rolled implementation available via a #define
>
> BTW, I'm still not clear how to choose which implementation I'm using. I have the review version.

The documentation contains a chapter 'Configuration', it describes the
required bjam command-line arguments for the different platforms:

x86/32bit: bjam toolset0gcc architecture=x86 instruction-set=i686
address-model=64 context-impl=asm

I know that's a lot of args but it is triggered by some limitations of
the current version of boost.build (Vladimir addresses this issue already).

so long,
Oliver