/*
 * Copyright (c) 2001 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _SYS_FX_H
#define	_SYS_FX_H

#pragma ident	"@(#)fx.h	1.1	01/09/12 SMI"

#include <sys/types.h>
#include <sys/thread.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Fixed-priority dispatcher parameter table entry
 */
typedef struct fxdpent {
	pri_t	fx_globpri;	/* global (class independent) priority */
	int	fx_quantum;	/* time quantum given to procs at this level */
} fxdpent_t;

#ifdef _KERNEL

typedef uintptr_t fx_cookie_t;	/* handle for callback supplied storage */

/*
 * callbacks supplied by custom scheduler. In general, a change to quantum
 * and/or priority when returning from a callback has immediate effect.
 *
 * fx_exit - called when a thread exits. This also needs to free any storage
 *	for the fx_cookie_t.
 *
 * fx_callb_tick - called at every clock tick attributed to this thread
 *
 * fx_callb_preempt - called when a thread is being preempted or yielding
 *
 * fx_callb_stop/fx_callb_sleep - called when a thread stops running
 *
 * fx_callb_wakeup - called when a thread is again runnable
*/
typedef struct fx_callbacks {
	int fx_callb_version;
	void (*fx_callb_exit)(fx_cookie_t);
	void (*fx_callb_tick)(fx_cookie_t, clock_t *, pri_t *);
	void (*fx_callb_preempt)(fx_cookie_t, clock_t *, pri_t *);
	void (*fx_callb_stop)(fx_cookie_t);
	void (*fx_callb_sleep)(fx_cookie_t);
	void (*fx_callb_wakeup)(fx_cookie_t, clock_t *, pri_t *);

} fx_callbacks_t;


#define	FX_CALLB_VERSION_1	1

#define	FX_CALLB_REV	FX_CALLB_VERSION_1

#define	FX_CB_VERSION(cb)		cb->fx_callb_version

#define	FX_CB_EXIT(cb, c)		cb->fx_callb_exit(c)

#define	FX_CB_TICK(cb, c, q, p)		cb->fx_callb_tick(c, q, p)

#define	FX_CB_PREEMPT(cb, c, q, p)	cb->fx_callb_preempt(c, q, p)

#define	FX_CB_STOP(cb, c)		cb->fx_callb_stop(c)

#define	FX_CB_SLEEP(cb, c)		cb->fx_callb_sleep(c)

#define	FX_CB_WAKEUP(cb, c, q, p)	cb->fx_callb_wakeup(c, q, p)

/* priority setting */
#define	FX_CB_NOCHANGE	-32768


/*
 * Fixed-priority class specific thread structure
 */
typedef struct fxproc {
	int		fx_pquantum;	/* time quantum given to this proc */
	int		fx_timeleft;	/* time remaining in procs quantum */

	pri_t		fx_pri;		/* relative priority within fx class */
					/* same as user priority */

	pri_t		fx_uprilim;	/* user priority limit */

	char		fx_nice;	/* nice value for compatibility */
	uchar_t 	fx_flags;	/* flags defined below */
	kthread_t 	*fx_tp;		/* pointer to thread */
	struct fxproc 	*fx_next;	/* pointer to next fxproc */

	struct fxproc 	*fx_prev;	/* pointer to previous fxproc */

	/* the following are used only when we have callbacks registered */
	kt_did_t	fx_ktid;
	struct fxproc 	*fx_cb_next;	/* pointer to next fxproc that */
					/* has a callback */

	struct fxproc 	*fx_cb_prev;	/* pointer to previous fxproc that */
					/* has a callback */
	fx_cookie_t	fx_cookie;	/* cookie with which callback */
					/* was registered */
	fx_callbacks_t 	*fx_callback;	/* pointer to callback structure */
} fxproc_t;


#define	FX_CALLB(fxpp)	fxpp->fx_callback


/* flags */
#define	FXBACKQ	0x02	/* thread goes to back of disp q when preempted */

/*
 * Kernel version of fixed-priority class specific parameter structure
 */
typedef struct	fxkparms {
	pri_t	fx_upri;
	pri_t	fx_uprilim;
	int	fx_tqntm;
	uint_t	fx_cflags;
} fxkparms_t;



/*
 * Interface for partner private code. This is not a public interface.
 */
extern int fx_register_callbacks(fx_callbacks_t *, fx_cookie_t, pri_t, clock_t);
extern int fx_unregister_callbacks();
extern int fx_modify_priority(kt_did_t, clock_t, pri_t);
extern void *fx_get_mutex_cookie();
extern pri_t fx_get_maxpri();

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_FX_H */
