Ultrix threads??? (LONG article)

Matt Cross mcross at pennies.sw.stratus.com
Wed Jul 11 00:00:27 AEST 1990


I am trying to install Xtank on a Dec Station 3100 runnin X11R3 - I am having
no problem with the X part, but it does a couple neat things that I cannot
get to work.  You can write 'robot' programs to control the tanks, and in
order to run these, you have to have some sort of threading package running.
There is one included, but since I don't know a heck of a lot about threading
(or about the specifics of Ultrix), I couldn't seem to get it to work.  It
seems to me that what it does is to set the stack space of thread to it's own
buffer space, and then use longjmp's and signals to move itself around...  I
*think* I put in the right code to set the stack pointer in the setjmp
buffer, but I'm not sure.  Anyways, whenever it runs, all I get is a 'longjmp
botch', from the setjmp library.  Any help you give me would be greatly
appreciated.  (thread code follows:)

-----
File thread.h:
-----
/*
** Xtank
**
** Copyright 1988 by Terry Donahue
**
** thread.h
*/

#include "config.h"

/****************************************************************************/
/* thread.h - THREAD CLUSTER (INTERFACE)				    */
/* Created:  10/31/87		Release:  0.7		Version:  06/27/88  */
/****************************************************************************
(c) Copyright 1987 by Michael Benjamin Parker           (USA SS# 557-49-4130)

All Rights Reserved unless specified in the following include files:
#include "thread.cpy"

DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
****************************************************************************/

/* This threads package is known to run correctly on the following hardware:
 *      IBM RT
 *      DEC VAX
 *      Sun 3   (doesn't always work.  If not, use THREAD_SUNLWP below)
 *      HP9000 Series 800
 */

#include <signal.h>

#ifndef vax
#include <setjmp.h>

#ifdef hp9000s800
#define setjmp _setjmp
#define longjmp _longjmp
#endif

#else
/* Replacement setjmp and longjmp functions for vax */
typedef int jmp_buf[17];
int vax_setjmp(), vax_longjmp();
#define setjmp(jmp)       vax_setjmp(jmp)
#define longjmp(jmp,ret)  vax_longjmp(jmp,ret)
#endif

typedef struct _Thd {
    jmp_buf	state;		/* Current state of thread */
    int		sigstate;	/* Signal mask when at thread creation */
    struct _Thd *oldthd;	/* Thread which executed prior to this one */
    struct _Thd	*(*func)();	/* Main function for thread */
    int		stackoverflow;	/* Stack overflow boolean */
				/* Stack for thread lies here */
} Thread;

/* Call this once at start, returns pointer to main thread */
Thread *thread_setup();

/* Call this once for each new thread, returns pointer to the thread */
Thread *thread_init(/*  char *buf, unsigned int bufsize, int (*func)()  */);

/* Call this to switch to a new thread, returns pointer to previous thread */
Thread *thread_switch(/*  Thread *newthd  */);

/* Call this to destroy a thread.  It does not deallocate the thread memory */
Thread *thread_kill(/*  Thread *thd  */);

-----
File thread.c:
-----
#include "malloc.h"
/*
** Xtank
**
** Copyright 1988 by Terry Donahue
**
** thread.c
*/

#include "thread.h"

/* The current thread that is executing */
Thread *curthd;

/****************************************************************************/
/* thread.c - THREAD CLUSTER (IMPLEMENTATION)				    */
/* Created:  10/31/87		Release:  0.7		Version:  06/27/88  */
/****************************************************************************
(c) Copyright 1987 by Michael Benjamin Parker           (USA SS# 557-49-4130)

All Rights Reserved unless specified in the following include files: */
#include "thread.cpy" /*

DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
****************************************************************************/


Thread *thread_setup()
{
    static Thread mainthd[10];
    extern main();
    
    /* Initialize thread for the main program */
    curthd = mainthd;
    return thread_init(curthd,10*sizeof(Thread),main);
}

Thread *thread_init(buf, bufsize, func)
	char *buf;
	unsigned int bufsize;
	Thread *(*func)();
{
    int bufend;
    Thread *thd;
     
    /* If buffer size is too small, return 0 */
    if(bufsize < 3 * sizeof(Thread))
        return (Thread *) 0;
    
    /* Initialize local variables for new state */
    thd = (Thread *) buf;
    thd->func = func;
    thd->stackoverflow = 0;
    
    /* Copy current signal state and setjmp to the thread */
    thd->sigstate = sigsetmask(~0);
    if(setjmp(thd->state)) {
	sigsetmask(curthd->sigstate);
	for(;;)
	    curthd->oldthd = thread_switch((*curthd->func) (curthd->oldthd));
    }
    sigsetmask(thd->sigstate);    

    /* Modify current state's stack pointer in jmp_buf state */
    bufend = (unsigned int)buf + bufsize - 1 - sizeof(thd->state);

    /* Set stack pointer in jmp_buf to bufend.
     * This is extremely machine and OS dependent.
     * Often you can find out what register of the jmp_buf has the
     * stack pointer by looking in /usr/include/setjmp.h on your machine.
     */
#ifdef vax  /* Vaxen */
    bufend -= sizeof(Thread);
    thd->state[0] = bufend;
#endif
#if	(defined(ibm032) || defined(ibm370)) /* IBM RT */
    thd->state[0] = bufend;
#endif
#ifdef sun
#ifdef SUNOS4_0  /* Suns running 4.0 or higher */
    thd->state[2] = bufend;
#endif
#ifdef SUNOS3_0  /* Suns running less than 4.0 */
    thd->state[14] = bufend;
#endif
#endif
#ifdef hp9000s800
    /* Stack grows upwards, SP in state[1].
     * 48 is stack frame size, align to doubleword boundary 
     */
    thd->state[1] = ((unsigned)(thd+1) + 48 + 7) & ~7;
#endif
#ifdef mips
#ifdef ultrix
     ((int *) (thd->state))[JB_SP] = bufend;
#endif
#endif

    return thd;
}

Thread *thread_switch(newthd)
	Thread *newthd;
{
    /* Check for stack overflow */
    if(newthd->stackoverflow) return 0;

    /* If not switching to current thread, longjmp to new thread */
    if(newthd != curthd) {
        int sigstate = sigsetmask(~0);
	if(!setjmp(curthd->state)) {
	    newthd->oldthd = curthd;
	    curthd = newthd;
	    longjmp(curthd->state,1);
	}
	newthd = curthd->oldthd;
 	sigsetmask(sigstate);
     }

    /* Return the previous current thread */
    return newthd;
}

Thread *thread_kill(thd)
     Thread *thd;
{
    return thd;
}
-----
File thread.cpy (author's copying notice)
-----
/****************************************************************************/
/* thread.cpy -- COPYRIGHT NOTICE FOR MAILBOX MULTITASKER & ASSOCIATED FILES*/
/* Created:  06/01/87		Release:  0.7		Version:  06/27/88  */
/****************************************************************************
(c) Copyright 1987, 1988 by Michael Benjamin Parker     (USA SS# 557-49-4130)

Welcome to Mike Parker's Mailbox Multitasker Package,
			the Portable "C" Multitasking Environment!

The purpose of this package is to 1) encourage multitasking exploration and
use and 2) to provide a portable standard for multitasking on personal
computers.

There are three layers to the Mailbox Multitasker.  Release 0.7 (06/27/88) is
a beta release of the lowest (MPTHD) layer (works) and a alpha release of the
middle (MPTSK) layer.  The highest (MPRES) layer is included but untested.  A
complete 1.0 release forthcoming.


Permission is granted to put the lowest (MPTHD) and middle (MPTSK) layer
into applications and to experiment with the third layer (MPRES).

Permission is also granted to BYTE Magazine to distribute this package and
associated files on the BIX bulletin board system (see the article "First
Come, First Served" in the July 1988 BYTE for more details).

In general, this package is distributed as "shareware": permission is granted
to freely distribute Mailbox and associated files and documentation at no
cost, provided:

		It is not DISTRIBUTED or PUBLISHED for commercial gain
		(except for BYTE MAGAZINE)

		It is not USED (in programs) for commercial gain WITHOUT
		paying the license fee (see below).

		All copyright notices and provisions are preserved.

	All other rights reserved.

IF YOU FIND MAILBOX USEFUL, $35 IS ASKED TO HELP RECOVER DEVELOPMENT COSTS.
This licensing fee is a requirement for all commercial applications of the
package.


I would greatly appreciate any comments you have about the thread cluster and
associated context switching article.  Useful enhancements should be
submitted to me directly for inclusion in future releases.

I may be reached at the following addresses:

COLLEGE:
	Massachusetts Institute of Technology, '89
	East Campus - Munroe 303
	3 Ames Street.
	Cambridge, MA 02139
	(617) 225-6303 / mbparker at athena.mit.edu

HOME:
	721 East Walnut Ave.
	Orange, CA 92667-6833
	(714) 639-9497

SUMMER WORK:
	Bell Communications Research
	MRE 2E375 / (201) 829-4420
	
	University Relations
	444 Hoes Lane, RRC 4C-128
	Piscataway, NJ 08854
	(201) 699-2846

SUMMER HOME:
	Bell Communications Summer Internship
	Rutger's Unv, Busch Campus, Nichols Apt. 17
	P.O. Box 459
	Piscataway, NJ 08854
	(201) 932-0774

DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
****************************************************************************/



-- 
These are my views, and in no way reflect the views of Stratus Computer, Inc.

Mail to: mcross at es.stratus.com or profesor at wpi.wpi.edu



More information about the Comp.unix.ultrix mailing list