[context] How to set stack pointer in a platform-independent way?

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

[context] How to set stack pointer in a platform-independent way?

TONGARI J
Hi,

The problem had been discussed here:
https://groups.google.com/forum/#!topic/boost-devel-archive/cl8B1oUPrVM

But it's still not clear how to set the stack pointer portably, even after examining the code of Boost.Coroutine. For now, Boost.Context only supports downward stack, and Boost.Coroutine, which happened to be written by the same author, just assumes that the stack always grows downward, which is not really a portable implementation, if future Boost.Context supports upward stack, Boost.Coroutine has to be changed as well.

Even than that, what does "beginning of the stack" really means?
Suppose we have a stack of size 3, starting at [s]:

[s-1][s][s+1][s+2][s+3]

Why the beginning of a downward stack is [s+3], not [s+2]?
If it's a upward stack, is beginning [s] or [s-1]?


Thanks.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

Oliver Kowalke-3
But it's still not clear how to set the stack pointer portably, even after examining the code of Boost.Coroutine. For now, Boost.Context only supports downward stack, and Boost.Coroutine, which happened to be written by the same author, just assumes that the stack always grows downward, which is not really a portable implementation, if future Boost.Context

boost.context is implemented for specific architectures/platforms, e.g. it does not contain generic code which will work in general.
that said -  you can not have a 'portable' implementation.
an architecture/platform determines in which direction the stack grows - at the moment all architectures/platforms supported by boost.context have
downward growing stack.
 
supports upward stack, Boost.Coroutine has to be changed as well.

yes, if in the future an architecture/platform with upward growing stack will be supported, the stack allocator classes have to be modified


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

TONGARI J
2014-09-19 14:10 GMT+08:00 Oliver Kowalke <[hidden email]>:
But it's still not clear how to set the stack pointer portably, even after examining the code of Boost.Coroutine. For now, Boost.Context only supports downward stack, and Boost.Coroutine, which happened to be written by the same author, just assumes that the stack always grows downward, which is not really a portable implementation, if future Boost.Context

boost.context is implemented for specific architectures/platforms, e.g. it does not contain generic code which will work in general.
that said -  you can not have a 'portable' implementation.
an architecture/platform determines in which direction the stack grows - at the moment all architectures/platforms supported by boost.context have
downward growing stack.

I'm not familiar with the asm enough, but can't you adjust the sp in the asm so that in user code it always has to be the lowest position?

supports upward stack, Boost.Coroutine has to be changed as well.

yes, if in the future an architecture/platform with upward growing stack will be supported, the stack allocator classes have to be modified

So how would you modify them to support both upward and downward stack? preprocessor branch? runtime check?

My prevoius question stays unanswered, so let me repeat here:
what does "beginning of the stack" really means?
Suppose we have a stack of size 3, starting at [s]:

[s-1][s][s+1][s+2][s+3]

Why the beginning of a downward stack is [s+3], not [s+2]?
If it's a upward stack, is beginning [s] or [s-1]?


Thanks.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

Oliver Kowalke-3
2014-09-19 8:53 GMT+02:00 TONGARI J <[hidden email]>:
I'm not familiar with the asm enough, but can't you adjust the sp in the asm so that in user code it always has to be the lowest position?

no idea what you want - fcontext_t is a pointer containing the address of the lowest address of the stack - but it is not the stack point position
if the context is resumed
 
So how would you modify them to support both upward and downward stack? preprocessor branch? runtime check?

preprocessor - because it is determined at compile time
 
My prevoius question stays unanswered, so let me repeat here:
what does "beginning of the stack" really means?
Suppose we have a stack of size 3, starting at [s]:

[s-1][s][s+1][s+2][s+3]

Why the beginning of a downward stack is [s+3], not [s+2]?
If it's a upward stack, is beginning [s] or [s-1]?


stackallocator using malloc():
        void * limit = std::malloc( size);
        if ( ! limit) throw std::bad_alloc();
        ctx.size = size;
        ctx.sp = static_cast< char * >( limit) + ctx.size;

if limit is at x and you allocated 64byte of memory for the stack you have to adjust your stack base
for downward growing stacks to address y=x+64, e.g. starting at y your stack has 64bytes to grow.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

TONGARI J
2014-09-19 15:21 GMT+08:00 Oliver Kowalke <[hidden email]>:
2014-09-19 8:53 GMT+02:00 TONGARI J <[hidden email]>:
I'm not familiar with the asm enough, but can't you adjust the sp in the asm so that in user code it always has to be the lowest position?

no idea what you want - fcontext_t is a pointer containing the address of the lowest address of the stack - but it is not the stack point position
if the context is resumed

To be clear, I was talking about `make_fcontext(void* sp,std::size_t size,void(*fn)(intptr_t))`.

Currently `sp` requires the user to know the whether stack grows downwards or upwards, but for a specific architecture/platform, you have to write an asm for it, and you know how the stack grows on this architecture/platform, don't you? Or are those asms independent of how the stack grows?

If the asm knows how the stack grows, you can offset the `sp` internally, leave it transparent to the user.
 
So how would you modify them to support both upward and downward stack? preprocessor branch? runtime check?

preprocessor - because it is determined at compile time
 
My prevoius question stays unanswered, so let me repeat here:
what does "beginning of the stack" really means?
Suppose we have a stack of size 3, starting at [s]:

[s-1][s][s+1][s+2][s+3]

Why the beginning of a downward stack is [s+3], not [s+2]?
If it's a upward stack, is beginning [s] or [s-1]?


stackallocator using malloc():
        void * limit = std::malloc( size);
        if ( ! limit) throw std::bad_alloc();
        ctx.size = size;
        ctx.sp = static_cast< char * >( limit) + ctx.size;

if limit is at x and you allocated 64byte of memory for the stack you have to adjust your stack base
for downward growing stacks to address y=x+64, e.g. starting at y your stack has 64bytes to grow.

So how about upward stack, is it x or (x-1)?


Thanks.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

Oliver Kowalke-3
2014-09-19 10:12 GMT+02:00 TONGARI J <[hidden email]>:
Currently `sp` requires the user to know the whether stack grows downwards or upwards, but for a specific architecture/platform, you have to write an asm for it, and you know how the stack grows on this architecture/platform, don't you?

yes, but at the moment for all supported platforms the stack grows downward
 
Or are those asms independent of how the stack grows?

no
 
If the asm knows how the stack grows, you can offset the `sp` internally, leave it transparent to the user.

boost.context is low level and the design decision was that higher level libraries using boost.context have to take care about the stack, e.g.
boost.context is not responsible for allocating/deallocating the stack.
 
stackallocator using malloc():
        void * limit = std::malloc( size);
        if ( ! limit) throw std::bad_alloc();
        ctx.size = size;
        ctx.sp = static_cast< char * >( limit) + ctx.size;

if limit is at x and you allocated 64byte of memory for the stack you have to adjust your stack base
for downward growing stacks to address y=x+64, e.g. starting at y your stack has 64bytes to grow.

So how about upward stack, is it x or (x-1)?

of course x for upward growing stacks

x is the lowest address of your stack and y is the highest address of your stack

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

TONGARI J
2014-09-19 16:19 GMT+08:00 Oliver Kowalke <[hidden email]>:
boost.context is low level and the design decision was that higher level libraries using boost.context have to take care about the stack, e.g.
boost.context is not responsible for allocating/deallocating the stack.

I know boost.context is low level, and I don't expect it to alloc/dealloc the stack, what I proposed is:

```c++
fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext_portable(void* sp, std::size_t size, void (*fn)(intptr_t))
{
#if STACK_GROWS_UPWARD
    return make_fcontext(sp, size, fn);
#else
    return make_fcontext(sp + size, size, fn);
...
char stack[1024];
// works for both downward/upward stacks
auto ctx = make_fcontext_portable(stack, 1024, f);
```

Does that make sense?

Is it possible to embed the logic in asm so you don't have to use preprocessor condition at all?


Thanks.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

cppljevans
In reply to this post by TONGARI J
On 09/18/2014 10:02 PM, TONGARI J wrote:

> Hi,
>
> The problem had been discussed here:
> https://groups.google.com/forum/#!topic/boost-devel-archive/cl8B1oUPrVM
>
> But it's still not clear how to set the stack pointer portably, even after
> examining the code of Boost.Coroutine. For now, Boost.Context only supports
> downward stack, and Boost.Coroutine, which happened to be written by the
> same author, just assumes that the stack always grows downward, which is
> not really a portable implementation, if future Boost.Context supports
> upward stack, Boost.Coroutine has to be changed as well.

Several years ago, I had a look at the Boehm garbage collector:

http://www.hboehm.info/gc/

IIRC, it had to determine whether the stack grew upward or
downward.  I can't remember where in the code that was,
but I also vaguely remember reading (I think in the code
commets) that the method was not completely portable.

HTH.

-regards,
Larry


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

TONGARI J
2014-09-19 22:03 GMT+08:00 Larry Evans <[hidden email]>:
On 09/18/2014 10:02 PM, TONGARI J wrote:
> Hi,
>
> The problem had been discussed here:
> https://groups.google.com/forum/#!topic/boost-devel-archive/cl8B1oUPrVM
>
> But it's still not clear how to set the stack pointer portably, even after
> examining the code of Boost.Coroutine. For now, Boost.Context only supports
> downward stack, and Boost.Coroutine, which happened to be written by the
> same author, just assumes that the stack always grows downward, which is
> not really a portable implementation, if future Boost.Context supports
> upward stack, Boost.Coroutine has to be changed as well.

Several years ago, I had a look at the Boehm garbage collector:

http://www.hboehm.info/gc/

IIRC, it had to determine whether the stack grew upward or
downward.  I can't remember where in the code that was,
but I also vaguely remember reading (I think in the code
commets) that the method was not completely portable.

I guess something like below should work?

    #include <iostream>
    
    __attribute__((noinline)) bool is_upward_test(char* a)
    {
        char b[32];
        return a < b;
    }
    
    bool is_upward()
    {
        char a[32];
        return is_upward_test(a);
    }
    
    int main(int argc, char** argv) {
        std::cout << is_upward();
    return 0;
    }

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

cppljevans
On 09/20/2014 02:20 AM, TONGARI J wrote:

> 2014-09-19 22:03 GMT+08:00 Larry Evans <[hidden email]>:
>
>> On 09/18/2014 10:02 PM, TONGARI J wrote:
>>> Hi,
>>>
>>> The problem had been discussed here:
>>> https://groups.google.com/forum/#!topic/boost-devel-archive/cl8B1oUPrVM
>>>
>>> But it's still not clear how to set the stack pointer portably, even
>> after
>>> examining the code of Boost.Coroutine. For now, Boost.Context only
>> supports
>>> downward stack, and Boost.Coroutine, which happened to be written by the
>>> same author, just assumes that the stack always grows downward, which is
>>> not really a portable implementation, if future Boost.Context supports
>>> upward stack, Boost.Coroutine has to be changed as well.
>>
>> Several years ago, I had a look at the Boehm garbage collector:
>>
>> http://www.hboehm.info/gc/
>>
>> IIRC, it had to determine whether the stack grew upward or
>> downward.  I can't remember where in the code that was,
>> but I also vaguely remember reading (I think in the code
>> commets) that the method was not completely portable.
>>
>
> I guess something like below should work?
>
>     #include <iostream>
>
>     __attribute__((noinline)) bool is_upward_test(char* a)
>     {
>         char b[32];
>         return a < b;
>     }
>
>     bool is_upward()
>     {
>         char a[32];
>         return is_upward_test(a);
>     }
>
>     int main(int argc, char** argv) {
>         std::cout << is_upward();
>     return 0;
>     }
>
Yep.  Something like that.  I, again, vaguely remember
seeing code something like that in the Boehm GC source code.

-regards,
Larry



_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

Nat Goodspeed-2
In reply to this post by TONGARI J
On Sat, Sep 20, 2014 at 3:20 AM, TONGARI J <[hidden email]> wrote:

> I guess something like below should work?
>
>     #include <iostream>
>
>     __attribute__((noinline)) bool is_upward_test(char* a)
>     {
>         char b[32];
>         return a < b;
>     }
>
>     bool is_upward()
>     {
>         char a[32];
>         return is_upward_test(a);
>     }
>
>     int main(int argc, char** argv) {
>         std::cout << is_upward();
>     return 0;
>     }

Doesn't the standard say pointer comparisons are only defined between
pointers into the same container? Therefore wouldn't the above be UB?
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

TONGARI J
2014-09-21 1:48 GMT+08:00 Nat Goodspeed <[hidden email]>:
On Sat, Sep 20, 2014 at 3:20 AM, TONGARI J <[hidden email]> wrote:

> I guess something like below should work?
>
>     #include <iostream>
>
>     __attribute__((noinline)) bool is_upward_test(char* a)
>     {
>         char b[32];
>         return a < b;
>     }
>
>     bool is_upward()
>     {
>         char a[32];
>         return is_upward_test(a);
>     }
>
>     int main(int argc, char** argv) {
>         std::cout << is_upward();
>     return 0;
>     }

Doesn't the standard say pointer comparisons are only defined between
pointers into the same container? Therefore wouldn't the above be UB?

o_O!? That would be scary, do you really mean pointer or iterator? Where's the paragraph?

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [context] How to set stack pointer in a platform-independent way?

Bjorn Reese
On 09/21/2014 07:06 AM, TONGARI J wrote:
> 2014-09-21 1:48 GMT+08:00 Nat Goodspeed <[hidden email]
> <mailto:[hidden email]>>:

>     Doesn't the standard say pointer comparisons are only defined between
>     pointers into the same container? Therefore wouldn't the above be UB?
>
>
> o_O!? That would be scary, do you really mean pointer or iterator?
> Where's the paragraph?

Paragraph [expr.rel]/3 does not specify this general case. Think of
near pointers in the segmented memory model.

For an in-depth discussion see commentary 1209 in:

   http://c0x.coding-guidelines.com/6.5.8.pdf

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users