> Joel Sherrill <joel.sherr...@oarcorp.com> writes:
>
>> On 01/12/2012 12:16 PM, Andreas Schwab wrote:
>>> Ian Lance Taylor<i...@google.com>  writes:
>>>
>>>> The functions required are makecontext, getcontext, and setcontext.
>>> Note that these functions are obsolescent in POSIX.1-2004 and removed
>>> from POSIX.1-2008.
>> Are there any alternatives? It is bad that Go is already starting
>> out dependent on obsolete methods.  :(
>
> I would be glad to use alternatives but I'm not aware of any.
>
> The getcontext and setcontext functions are easy.  The harder one is
> makecontext.  POSIX appears to be assuming that any use of makecontext
> can be replaced with pthread_create, but if you care about efficiency
> that simply isn't true.
>
> Ian
>

Stuff from the opensolaris project isn't going to help here is it ?


void
makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
{
        greg_t *reg;
        long *tsp;
        char *sp;
        int argno;
        va_list ap;
        size_t size;

        reg = ucp->uc_mcontext.gregs;
        reg[REG_PC] = (greg_t)func;
        reg[REG_nPC] = reg[REG_PC] + 0x4;

        /*
         * Reserve enough space for a frame and the arguments beyond the
         * sixth; round to stack alignment.
         */
        size = sizeof (struct frame);
        size += (argc > 6 ? argc - 6 : 0) * sizeof (long);

        /*
         * The legacy implemenation of makecontext() on sparc has been to
         * interpret the uc_stack.ss_sp member incorrectly as the top of the
         * stack rather than the base. We preserve this behavior here, but
         * provide the correct semantics in __makecontext_v2().
         */
        sp = (char *)(((uintptr_t)ucp->uc_stack.ss_sp - size) &
            ~(STACK_ALIGN - 1));

        /*
         * Copy all args to the stack, and put the first 6 args into the
         * ucontext_t. Zero the other fields of the frame.
         */
        /* LINTED pointer cast may result in improper alignment */
        tsp = &((struct frame *)sp)->fr_argd[0];
        bzero(sp, sizeof (struct frame));

        va_start(ap, argc);

        for (argno = 0; argno < argc; argno++) {
                if (argno < 6)
                        *tsp++ = reg[REG_O0 + argno] = va_arg(ap, long);
                else
                        *tsp++ = va_arg(ap, long);
        }

        va_end(ap);

        reg[REG_SP] = (greg_t)sp - STACK_BIAS;          /* sp (when done) */
        reg[REG_O7] = (greg_t)resumecontext - 8;        /* return pc */

}

-- 
--
http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x1D936C72FA35B44B
+-------------------------+-----------------------------------+
| Dennis Clarke           | Solaris and Linux and Open Source |
| dcla...@blastwave.org   | Respect for open standards.       |
+-------------------------+-----------------------------------+

Reply via email to