Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Dec 2001 16:01:03 -0500
From:      Daniel Eischen <eischen@vigrid.com>
To:        current@freebsd.org
Cc:        alpha@freebsd.org
Subject:   Munging jmp_bufs on alpha
Message-ID:  <3C21000F.994BD53D@vigrid.com>

next in thread | raw e-mail | index | archive | help
libc_r seems to be broke on alpha and I'm trying to fix it.
We munge jmp_bufs to create new contexts for threads and for
the thread scheduler.  It seems that sometime over the last
few weeks/months something broke that.  It doesn't look like
_setjmp of _longjmp have changed at all, though.

Included is a sample program that includes the jmp_buf-munging
macros that use to work and that no longer work.  [ Drew, you
out there?  You got these to work before ;-) ]

Any help would be appreciated.

Thanks,

-- 
Dan Eischen

--------------

#include <unistd.h>
#include <stdlib.h>
#include <machine/param.h>	/* for PAGE_SIZE */

#include <assert.h>
#include <setjmp.h>
#include <stdio.h>


#if	defined(__i386__)
#define	SET_STACK_JB(jb, stk)		(jb)[0]._jb[2] = (int)(stk)
#define	GET_STACK_JB(jb)		((unsigned long)((jb)[0]._jb[2]))
#define SET_RETURN_ADDR_JB(jb, ra)	(jb)[0]._jb[0] = (int)(ra)
#elif	defined(__alpha__)
#include <machine/reg.h>
#define	SET_STACK_JB(jb, stk)		(jb)[0]._jb[R_SP + 4] = (long)(stk)
#define	GET_STACK_JB(jb)		((unsigned long)((jb)[0]._jb[R_SP + 4]))
#define SET_RETURN_ADDR_JB(jb, ra) do {		\
	(jb)[0]._jb[2] = (unsigned long)(ra) + 8UL;	\
	(jb)[0]._jb[R_RA + 4] = 0;		\
	(jb)[0]._jb[R_T12 + 4] = (long)(ra);	\
} while (0)
#else
#error "Don't recognize this architecture!"
#endif


static jmp_buf	retjb;
static jmp_buf	schedjb;

static void
dump_jmpbuf(jmp_buf jb)
{
	long	*larr = (long *)jb[0]._jb;
	int	i;

	for (i = 0; i < (sizeof(jmp_buf) / sizeof(long)); i++) {
		printf("    0x%lx\n", larr[i]);
	}
}

static void
scheduler()
{
	int	tmp;

	printf("Entered scheduler, stack is %p\n", &tmp);
	_longjmp(retjb, 1);
}

int
main(int argc, char *argv[])
{
	long	schedstack;
	long	stacktop;
	int	i;

	/* Create a stack for the scheduler: */
	assert((schedstack = (long)malloc (PAGE_SIZE)) != NULL);

	/* Stack starts high and grows up/low: */
	stacktop = schedstack + PAGE_SIZE - sizeof (double);

	/* Initialize the context for the scheduler: */
	_setjmp(schedjb);
	printf("Scheduler jmp_buf after _setjmp:\n");
	dump_jmpbuf(schedjb);

	SET_STACK_JB(schedjb, stacktop);
	SET_RETURN_ADDR_JB(schedjb, scheduler);

	printf("\nScheduler jmp_buf after tamporing:\n");
	dump_jmpbuf(schedjb);
	printf("\n");

	for (i = 0; i < 10; i++) {
		if (_setjmp(retjb) == 0) {
			printf("Switching to scheduler, count %d.\n", i);
			_longjmp(schedjb, 1);
		}
	}

	return (0);
}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3C21000F.994BD53D>