thread.h 5.53 KB
/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * Copyright (C) 1998 Digital Equipment Corporation
 *
 * This file is part of the SimOS distribution.
 * See LICENSE file for terms of the license.
 *
 */

#ifndef _THREAD_H_
#define _THREAD_H_
typedef struct thread * thread_ptr;
#include "page.h"
#include "queue.h"
#include "header.h"

/* mnemonics for the register indices into the args[] array */
#define RA 0
#define RB 1
#define RC 2

/* FP register indices into the args[] array */
#define FA 0
#define FB 1
#define FC 2

/* To get specific register belonging to a thread */
#if 0 
#define REG(Rn)    pthread->st.reg[picode->args[Rn]]
#define FP(Fn)    pthread->st.fp[picode->args[Fn]]
#endif

/* The time to sleep, before rechecking for I/O */
#define THREAD_SLEEP_TIME 200

#define WAKEUP(T) ((T)->runstate = R_RUN)
#define SLEEP(T) ((T)->runstate = R_SLEEP)
#define STALL(T) ((T)->runstate = R_STALL)

/* Max number of file descriptors/thread */
#define MAX_FDNUM 50

/*
 * This is not essential unless we need explicit call-stack information
 * Not used in this version of AINT
 */
#define MAX_CALLS 100

/* number of signals supported (0 not used) */
#define MAX_SIGNALS 33

#define SETSIG(sigvec, signum)    (sigvec |= (1 << ((signum)-1)))
#define CLRSIG(sigvec, signum)    (sigvec &= ~(1<<((signum)-1)))
#define ISSETSIG(sigvec, signum) (sigvec & (1 <<((signum)-1)))

/*
 * return pids starting from 3000 - having low pids could be a problem
 * for some applications.
 */
#define PID_OFFSET 3000

/* Run states */
typedef enum {
    R_RUN = 0,
    R_SLEEP,
    R_STALL,
    R_BLOCK,
    R_WAIT,
    R_ZOMBIE,
    R_DONE,
    R_FREE,
    R_MAX
} state_t;

typedef double aint_time_t;

typedef void (*sig_handler_t) (int,...);

struct my_sigvec {
    sig_handler_t sv_handler;
    int sv_mask;
    int sv_flags;
};


#ifdef gone
/*
 * The context of a thread struct (see below) that must be saved 
 * when executing a signal handler... Not implemented yet
 */
typedef struct context {
    thread_ptr next;
    thread_ptr prev;
    long reg[33];
    double fpreg[33];
    long fpcr;
    float fp[32];
    struct event *pevent;
    state_t runstate;
    long paddr;
    icode_ptr target;
    int (*ufunc) ();
    int *stall_addr;
    int exitcode;
    int semval;			/* waiting for this semaphore value */
    int sigblocked;
    struct context *psave;
    int errcode;

} context_t, *context_ptr;
#endif

/* The thread structure */
typedef struct thread {

    /* pointers to create various linked list of threads */
    thread_ptr next;
    thread_ptr prev;

    /* machine state */
   AlphaState st;
#ifdef gone
    long reg[33];		/* An extra reg for writes to r32 (redirected
				   r31) */  
    double fp[33];
    long fpcr;	
#endif		/* The Floating point control register */
    struct event *pevent;		/* pointer to an event structure */
    state_t runstate;		/* status of thread (runnable, sleeping etc. */

   int pid;			/* process id assigned by aint */
    int uid;                    /* effective uid */
    int gid;                    /* effective gid */
    
    /* virtual memory */
    long paddr;			/* phys addr computed by an event function */
    long vaddr;

    /* The per-process translation buffer */
    page_t *page_bucket[TB_SIZE]; 

    int num_pages;		/* Number of page-table entries allocated
				   - hack for speeding up fork */
    int num_private;		/* Number of actual pages allocated as
				   private */ 
    struct shm_descriptor *shmem_regions; /* List of shared regions attached by
					     process */
    long unsp_shmat_current;	/* Address to use in shmat called with NULL
				   addr */
    long mmap_size;             /* total size of the anonymous mmap pages */

    /*simulated time */
    aint_time_t time;		/*simulated time for this thread */
    aint_time_t cpu_time;	/* accumulated cpu time for this thread */
    double child_cpu;		/* accumulated cpu time for finished
				 * children */ 
#ifdef gone /* MINT */
    icode_ptr target;		/* place to store branch target during delay
				 * slot */
#endif 
    int is_zombie;		/* =1 if thread is almost dead */
    long mem_map;		/* add this to each private data address */

    /* this is read in by read_hdrs */
    struct header *headerp;
    /* program text */
    struct icode **itext;
    
    /* more relatives */
    thread_ptr parent;
    thread_ptr youngest;	/* child */
    thread_ptr sibling;		/* next older */

    /* misc stuff */
    int (*ufunc) ();		/* user defined or event-specific function to
				   call */
    long stacktop;		/* lowest address allowed in the stack */
    int exitcode;
    int semval;			/* waiting for this semaphore value */
    int *perrno;
    int errno;			/* most recent */
    int *fd;			/* file descriptors; =1 means open, =0 means
				   closed */ 

    /* support for load locked-store conditional */
    long locked_addr;		/* per processor locked address register */
    int lock_flag;		/* per processor lock flag */

    /* signal support */
    struct my_sigvec *sigv;	/* for signal handlers */
    int sigblocked;		/* bit i=1 if signal i currently blocked */
    int sigpending;		/* bit i=1 if signal i currently pending */
#if 0
    context_ptr psave;		/* ptr to thread save area (for signal
				   support) */ 
#endif
} thread_t;


#if gone
/* function prototypes */
void block_thr (thread_ptr q, thread_ptr pthread);
thread_ptr unblock_thr (thread_ptr q);
void unblock_list (thread_ptr waker, thread_ptr q);
icode_ptr terminate_thr(icode_ptr picode, thread_ptr pthread);
icode_ptr done_thr(icode_ptr picode, thread_ptr pthread);
#endif
#endif /* _THREAD_H_*/