/*
**
**   Copyright 1995 David F. Carlson  (carlson@dot4.com)
**   Copyright 1995 Dot4, Inc.
**   All rights reserved
**
**   POSIX 1003.1b Process Scheduler
**   Provided to the Linux Community by Dot4, Inc.
**
**   Dot4 is a provider of professional services for POSIX-based 
**   real-time systems from embedded to distributed.
**
**   For more information call:
**
**   Dot4, Inc.  (800) 834-1951 **  email: dot4@dot4.com
**   The Real-Time Specialists
**
********************************************************************************
**
** Permission is granted to any individual or institution to use, copy,
** or redistribute this software so long as it is not sold for profit,
** and provided redistributions must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE COMPANY ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE COMPANY BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
********************************************************************************
**
*/

#ifndef _LINUX_PSCHED_H_
#define _LINUX_PSCHED_H_

/* 
**	Enable POSIX scheduling
*/

#ifndef _POSIX_PRIORITY_SCHEDULING
#define _POSIX_PRIORITY_SCHEDULING

#include <linux/types.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/sched.h>

/*
**	Policy values
**
** Choose bitmasks so that a scheduler can schedule classes of processes. 
*/


#define SCHED_TS      (0)		/* default non-POSIX scheduler */
#define SCHED_FIFO    (1)
#define SCHED_RR      (2)
#define SCHED_OTHER   (0)		/* same as TS for this system */
#define SCHED_DEFAULT (0)

/*
**	Priority values
*/
#define SCHED_MIN		(0)		/* PRIVATE: use sched_get_priority_min() !!! */
#define SCHED_MAX		(31)		/* PRIVATE: use sched_get_priority_max() !!! */

/* 
**	The generic structure for get/set_* 
*/

struct sched_param	{
	int sched_priority;
};


/* 
**	 Miscellaneous Linux-isms
*/

#define POSIX_RR_INTERVAL	{ 0, 10000000 };  /* 0 seconds, 10000000 nSec */

#define TIMESPEC_to_JIFFIES(tsp)	(((tsp)->tv_sec * 100) + (tsp)->tv_nsec / 10000000)

#define PSCHED_N_PRI	(SCHED_MAX+1)

#define POSIX_SCHED_CLASS		(SCHED_RR|SCHED_FIFO)  /* what we schedule for */

#define IS_TIMESHARE_SCHEDULED(task)	((task)->psched_policy == SCHED_TS)
#define IS_POSIX_SCHEDULED(task)	((task)->psched_policy & POSIX_SCHED_CLASS)


/* 
**	 Kernel External Declarations
*/

#ifdef __KERNEL__

#ifdef TASK_STRUCT  /* this won't work in nested includes! */

	/* psched_yield called in do_timer() */
extern void psched_yield(struct task_struct *p);

	/* psched_enqueue called in sys_fork() */
extern void psched_enqueue(struct task_struct *p);

	/* psched_setsched_default() is called by sys_exit() */
extern void psched_setsched_default(struct task_struct *p);
#endif /* TASK_STRUCT */

extern volatile unsigned long psched_runq_bits;  /* reference for below macro */

#define POSIX_RUNQ(task)	if ( IS_POSIX_SCHEDULED(task) && \
                               ((task)->state == TASK_RUNNING))	{	\
                               unsigned long flags;	\
                               save_flags(flags);	\
                               cli();	\
                               psched_runq_bits |= 1 << (task)->psched_priority;	\
                               if ((task)->psched_priority > current->psched_priority) need_resched = 1; \
                               restore_flags(flags);	\
                           }

#endif /* __KERNEL__ */

#ifndef __KERNEL__


/*
** POSIX.1b Function Prototypes
*/

int sched_setparam(pid_t pid, const struct sched_param *param);
int sched_getparam(pid_t pid, const struct sched_param *param);
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
int sched_getscheduler(pid_t pid);
int sched_yield(void);
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
int sched_rr_get_interval(pid_t pid, struct timespec *interval);


#endif /* __KERNEL__ */

#endif /* _POSIX_PRIORITY_SCHEDULING */
#endif /* _LINUX_PSCHED_H_ */
