/*
 * @COPYRIGHT@
 * 
 * x-kernel v3.3
 * 
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 * 
 * @COPYRIGHT@
 *
 * $RCSfile: scout_thread.h,v $
 *
 * HISTORY
 * $Log: scout_thread.h,v $
 * Revision 1.3  1996/02/01 15:18:54  slm
 * Updated copyright and version.
 *
 * Revision 1.2  1995/08/28  16:12:56  acb
 * Initial revision for x3.3
 *
 * Revision 1.2  1994/11/22  21:15:38  hkaram
 * changed NORETURN to XNORETURN; removed fpu_dirty field
 * removed platform.h
 *
 * Revision 1.1  1994/10/26  20:17:36  hkaram
 * Initial revision
 */
#ifndef scout_thread_h
#define scout_thread_h

#include "scout_queue.h"

#define SCOUT_THREAD_PRIORITY_MIN	2
#define SCOUT_THREAD_PRIORITY_STD	1
#define SCOUT_THREAD_PRIORITY_MAX	0

typedef void	(*Scout_Thread_Func)(void *arg);

typedef struct {
    char	*name;		/* thread name */
    void	*arg;		/* argument to be passed to FUN */
    u_int	stack_size;	/* (initial) stack size in bytes */
    u_int	priority;	/* thread priority */
} Scout_Thread_Options;

typedef	struct scout_thread {
    struct scout_thread	*next;		/* singly-linked list of threads */
    long		running   : 1;	/* has thread been started? */
    struct scout_stack	*stack;
    Scout_Thread_Func	fun;
    Scout_Thread_Options option;
    long		magic;
} Scout_Thread;

extern const Scout_Thread_Options	*scout_thread_default_options;
extern Scout_Thread			*scout_thread_self;

#define scout_thread_self()			(scout_thread_self)
#define scout_thread_get_name(t)		((t)->option.name)
#define scout_thread_set_cont_fun(t,f)		{(t)->option.fun = (f);}
#define scout_thread_set_cont_arg(t,a)		{(t)->option.arg = (a);}

extern void		scout_thread_init (Scout_Thread_Func init, void *arg);
extern Scout_Thread	*scout_thread_create (Scout_Thread_Func	fun,
					      const Scout_Thread_Options *opt);
extern void		scout_thread_stop (void)
     /* XNORETURN */ ;
extern void		scout_thread_suspend (void);
extern void		scout_thread_suspend_with_continuation (void)
     /* XNORETURN */ ;
extern void		scout_thread_wakeup (Scout_Thread *t);
extern void		scout_thread_async_wakeup (Scout_Thread *t);
extern void		scout_thread_yield (void);
extern int		scout_thread_free_stack (void);

#endif /* scout_thread_h */
