--- orig/linux-2.4.20/mm/mlock.c	2001-09-17 18:30:23.000000000 -0400
+++ linux/mm/mlock.c	2003-03-19 22:05:01.000000000 -0500
@@ -12,6 +12,10 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+
+extern unsigned long enable_user_rt;
+
+
 static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags)
 {
 	spin_lock(&vma->vm_mm->page_table_lock);
@@ -151,7 +155,7 @@ static int do_mlock(unsigned long start,
 	struct vm_area_struct * vma, * next;
 	int error;
 
-	if (on && !capable(CAP_IPC_LOCK))
+	if (on && !capable(CAP_IPC_LOCK) && !enable_user_rt)
 		return -EPERM;
 	len = PAGE_ALIGN(len);
 	end = start + len;
@@ -241,7 +245,7 @@ static int do_mlockall(int flags)
 	unsigned int def_flags;
 	struct vm_area_struct * vma;
 
-	if (!capable(CAP_IPC_LOCK))
+	if (!capable(CAP_IPC_LOCK) && !enable_user_rt)
 		return -EPERM;
 
 	def_flags = 0;
--- orig/linux-2.4.20/kernel/sched.c	2003-03-17 23:24:02.000000000 -0500
+++ linux/kernel/sched.c	2003-03-19 22:06:05.000000000 -0500
@@ -43,6 +43,14 @@ extern void immediate_bh(void);
 
 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
 
+unsigned long rt_period_start = 0; 
+unsigned long rt_period_end = 0; 
+unsigned long rt_period_remain = 0; 
+unsigned long rt_period_length = 50;
+unsigned long rt_period_reserved = 45;
+unsigned long enable_user_rt = 0;
+
+
 extern void mem_use(void);
 
 /*
@@ -188,7 +196,35 @@ static inline int goodness(struct task_s
 	 * runqueue (taking priorities within processes
 	 * into account).
 	 */
+
+	
+	
+	/*
+	 *   check if we are in the right time period
+	 *
+	 *   XXX if it burns though it's entire quantum and
+	 *       into the next ? 
+	 *     
+	 */
+	if (jiffies >= rt_period_end) { 
+	  /* no, start over from now */
+	  rt_period_start = jiffies;
+	  rt_period_end = rt_period_length + rt_period_start;
+	  rt_period_remain = rt_period_reserved; 
+	}
+	
+	/*
+	 *  is there any remaining time ? 
+	 *  
+	 */
+	
+	if (rt_period_remain > 0) { 
 	weight = 1000 + p->rt_priority;
+	}  else { 
+	  /* redundent, for clarity */
+	  weight = -1; 
+	}
+
 out:
 	return weight;
 }
@@ -955,7 +991,7 @@ static int setscheduler(pid_t pid, int p
 
 	retval = -EPERM;
 	if ((policy == SCHED_FIFO || policy == SCHED_RR) && 
-	    !capable(CAP_SYS_NICE))
+	    !capable(CAP_SYS_NICE) && !enable_user_rt)
 		goto out_unlock;
 	if ((current->euid != p->euid) && (current->euid != p->uid) &&
 	    !capable(CAP_SYS_NICE))
--- orig/linux-2.4.20/kernel/sysctl.c	2003-03-17 23:24:02.000000000 -0500
+++ linux/kernel/sysctl.c	2003-03-19 22:03:03.000000000 -0500
@@ -51,6 +51,12 @@ extern int sysrq_enabled;
 extern int core_uses_pid;
 extern int cad_pid;
 
+
+extern unsigned long rt_period_length;
+extern unsigned long rt_period_reserved;
+extern unsigned long enable_user_rt;
+
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -260,6 +266,13 @@ static ctl_table kern_table[] = {
 	{KERN_LOWLATENCY, "lowlatency", &enable_lowlatency, sizeof (int),
 	 0644, NULL, &proc_dointvec},
 #endif
+
+	{KERN_FIFOSCHED_PERIOD, "rtsched-period", &rt_period_length, 
+	   sizeof (int), 0644, NULL, &proc_dointvec},
+	{KERN_FIFOSCHED_RESERV, "rtsched-reserve", 
+	 &rt_period_reserved, sizeof (int), 0644, NULL, &proc_dointvec},
+	{KERN_USERRT_SYSCTL, "userrealtime", 
+	 &enable_user_rt, sizeof (int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
--- orig/linux-2.4.20/include/linux/sysctl.h	2003-03-17 23:24:02.000000000 -0500
+++ linux/include/linux/sysctl.h	2003-03-19 21:40:56.000000000 -0500
@@ -125,6 +125,10 @@ enum
 	KERN_TAINTED=53,	/* int: various kernel tainted flags */
 	KERN_CADPID=54,		/* int: PID of the process to notify on CAD */
 	KERN_LOWLATENCY=55,     /* int: enable low latency scheduling */
+	KERN_FIFOSCHED_PERIOD=56, /* int: max time rt processes can take up */
+	KERN_FIFOSCHED_RESERV=57, /* "" */
+	KERN_USERRT_SYSCTL=58, /* int: let users mlock and use rt */
+	KERN_USER_MLOCK_MAX=59, /* int: max memory all users can mlock */
 };
 
 
--- orig/linux-2.4.20/kernel/timer.c	2002-11-28 18:53:15.000000000 -0500
+++ linux/kernel/timer.c	2003-03-18 12:41:05.000000000 -0500
@@ -105,6 +105,16 @@ static struct list_head * run_timer_list
 
 #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
 
+extern unsigned long rt_period_start; 
+extern unsigned long rt_period_end;  
+extern unsigned long rt_period_remain; 
+extern unsigned long rt_period_length;
+extern unsigned long rt_period_reserved;
+
+
+
+
+
 void init_timervecs (void)
 {
 	int i;
@@ -610,6 +620,15 @@ void update_process_times(int user_tick)
 				p->need_resched = 1;
 			}
 		}
+		
+		if (p->policy == SCHED_FIFO) { 
+		  if (rt_period_remain == 0) { 
+		    p->need_resched = 1;
+		  } else { 
+		    rt_period_remain--;
+		  }
+		}
+
 		if (p->nice > 0)
 			kstat.per_cpu_nice[cpu] += user_tick;
 		else
