#ifndef _LINUX_SCHED_RUNQUEUE_H
#define _LINUX_SCHED_RUNQUEUE_H

#include <linux/config.h>

/*
 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
 * priority is 0..MAX_RT_PRIO-1, and SCHED_OTHER tasks are
 * in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values
 * are inverted: lower p->prio value means higher priority.
 *
 * The MAX_RT_USER_PRIO value allows the actual maximum
 * RT priority to be separate from the value exported to
 * user-space.  This allows kernel threads to set their
 * priority to a value higher than any user task. Note:
 * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
 *
 * Both values are configurable at compile-time.
 */

#if CONFIG_MAX_USER_RT_PRIO < 100
#define MAX_USER_RT_PRIO	100
#elif CONFIG_MAX_USER_RT_PRIO > 1000
#define MAX_USER_RT_PRIO	1000
#else
#define MAX_USER_RT_PRIO	CONFIG_MAX_USER_RT_PRIO
#endif

#if CONFIG_MAX_RT_PRIO < 0
#define MAX_RT_PRIO		MAX_USER_RT_PRIO
#elif CONFIG_MAX_RT_PRIO > 200
#define MAX_RT_PRIO		(MAX_USER_RT_PRIO + 200)
#else
#define MAX_RT_PRIO		(MAX_USER_RT_PRIO + CONFIG_MAX_RT_PRIO)
#endif

#define MAX_PRIO		(MAX_RT_PRIO + 40)

/*
 * These are the runqueue data structures:
 */

#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long))

struct prio_array {
	int nr_active;
	unsigned long bitmap[BITMAP_SIZE];
	list_t queue[MAX_PRIO];
};

/*
 * This is the main, per-CPU runqueue data structure.
 *
 * Locking rule: those places that want to lock multiple runqueues
 * (such as the load balancing or the process migration code), lock
 * acquire operations must be ordered by ascending &runqueue.
 */
struct runqueue {
	spinlock_t lock;
	unsigned long nr_running, nr_switches, expired_timestamp;
	long quiescent; /* RCU */
	task_t *curr, *idle;
	prio_array_t *active, *expired, arrays[2];
	unsigned long nr_uninterruptible;
	struct mm_struct * prev_mm;
#ifdef CONFIG_KWATCHDOG
	unsigned long soft_lockup_timestamp;
	unsigned long soft_lockup_message;
#endif
#ifdef CONFIG_SMP
	long last_jiffy;
	int prev_nr_running[NR_CPUS];
	task_t *migration_thread;
	list_t migration_queue;
#endif
} ____cacheline_aligned;

typedef struct runqueue runqueue_t;
extern runqueue_t runqueues[];

#define cpu_rq(cpu)		(runqueues + (cpu))
#define this_rq()		cpu_rq(smp_processor_id())
#define task_rq(p)		cpu_rq(task_cpu(p))
#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
#define rt_task(p)		((p)->prio < MAX_RT_PRIO)
#define task_running(rq, p)	((rq)->curr == (p))
#define RCU_quiescent(cpu)	(cpu_rq(cpu)->quiescent)

#endif /* _LINUX_SCHED_RUNQUEUE_H */
