aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJohn M. Calandrino <jmc@jupiter-cs.cs.unc.edu>2007-04-25 00:51:29 -0400
committerJohn M. Calandrino <jmc@jupiter-cs.cs.unc.edu>2007-04-25 00:51:29 -0400
commitd7b3de3825379e73327785fee0770a1e52c504bb (patch)
tree929f206b3cf9005e5e3969a7745bff8095321165 /arch
parent24f2277dbbd9616eb5b34150bd5ecb7c0c840f5f (diff)
Fixed a few comment inconsistencies. Added stubs for an SRP "semaphore",
which needs to be expanded in the LSO and by adding system call numbers in kernel space.
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/pi_sem_syscalls.c2
-rw-r--r--arch/i386/kernel/sem_syscalls.c2
-rw-r--r--arch/i386/kernel/srp_sem_syscalls.c149
4 files changed, 152 insertions, 3 deletions
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index b8815ad4e8..f77d3e4bc7 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ 8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
9 pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\ 9 pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\
10 quirks.o i8237.o topology.o alternative.o i8253.o tsc.o \ 10 quirks.o i8237.o topology.o alternative.o i8253.o tsc.o \
11 pi_sem_syscalls.o sem_syscalls.o 11 pi_sem_syscalls.o sem_syscalls.o srp_sem_syscalls.o
12 12
13obj-$(CONFIG_STACKTRACE) += stacktrace.o 13obj-$(CONFIG_STACKTRACE) += stacktrace.o
14obj-y += cpu/ 14obj-y += cpu/
diff --git a/arch/i386/kernel/pi_sem_syscalls.c b/arch/i386/kernel/pi_sem_syscalls.c
index 72fd67e6e5..6aa66d2081 100644
--- a/arch/i386/kernel/pi_sem_syscalls.c
+++ b/arch/i386/kernel/pi_sem_syscalls.c
@@ -29,7 +29,7 @@ static int __init pi_sema_boot_init(void)
29} 29}
30__initcall(pi_sema_boot_init); 30__initcall(pi_sema_boot_init);
31 31
32/* Find a free semaphore and assign to sem. */ 32/* Find a free semaphore and return. */
33asmlinkage long sys_pi_sema_init (void) 33asmlinkage long sys_pi_sema_init (void)
34{ 34{
35 pi_sema_id sem_id; 35 pi_sema_id sem_id;
diff --git a/arch/i386/kernel/sem_syscalls.c b/arch/i386/kernel/sem_syscalls.c
index 8b3270d0d4..1a70e0dbbc 100644
--- a/arch/i386/kernel/sem_syscalls.c
+++ b/arch/i386/kernel/sem_syscalls.c
@@ -26,7 +26,7 @@ static int __init sema_boot_init(void)
26} 26}
27__initcall(sema_boot_init); 27__initcall(sema_boot_init);
28 28
29/* Find a free semaphore and assign to sem. */ 29/* Find a free semaphore and return. */
30asmlinkage long sys_sema_init (void) 30asmlinkage long sys_sema_init (void)
31{ 31{
32 sema_id sem_id; 32 sema_id sem_id;
diff --git a/arch/i386/kernel/srp_sem_syscalls.c b/arch/i386/kernel/srp_sem_syscalls.c
new file mode 100644
index 0000000000..3a7e63b550
--- /dev/null
+++ b/arch/i386/kernel/srp_sem_syscalls.c
@@ -0,0 +1,149 @@
1#ifdef __KERNEL__
2
3/*
4 * Uniprocessor SRP "semaphores".
5 */
6
7#include <linux/sched.h>
8#include <linux/queuelock.h>
9#include <linux/sched_plugin.h>
10
11#define MAX_SRP_SEMAPHORES 256
12
13/* struct for uniprocessor SRP "semaphore" */
14struct srp_semaphore {
15 struct task_struct *pc_task; /* task representing prio ceil of sem */
16 int claimed; /* is the resource claimed (ceiling should be used)? */
17 int used; /* is the semaphore being used? */
18};
19
20struct srp_semaphore srp_sems[MAX_SRP_SEMAPHORES]; /* all SRP sems */
21typedef int srp_sema_id; /* Userspace ID of a srp_semaphore */
22
23/* System-wide priority ceiling, represented as a pointer to a task. */
24struct task_struct *spc_task = NULL;
25
26/* Used to serialize access to SRP semaphores and system priority ceiling. */
27static queuelock_t srp_lock;
28
29/* Initialize SRP semaphores at boot time. */
30static int __init srp_sema_boot_init(void)
31{
32 srp_sema_id sem_id;
33
34 printk("Initializing SRP semaphores...");
35 for (sem_id = 0; sem_id < MAX_SRP_SEMAPHORES; sem_id++)
36 srp_sems[sem_id].used = 0;
37 queue_lock_init(&srp_lock);
38 printk(" complete!\n");
39
40 return 0;
41}
42__initcall(srp_sema_boot_init);
43
44/* Find a free semaphore and return. */
45asmlinkage long sys_srp_sema_init (void)
46{
47 srp_sema_id sem_id;
48
49 for (sem_id = 0; sem_id < MAX_SRP_SEMAPHORES; sem_id++) {
50 if (!cmpxchg(&srp_sems[sem_id].used, 0, 1)) {
51 srp_sems[sem_id].pc_task = NULL;
52 srp_sems[sem_id].claimed = 0;
53 return sem_id;
54 }
55 }
56 return -ENOMEM;
57}
58
59/* Adjust the system-wide priority ceiling if resource is claimed. */
60asmlinkage long sys_srp_down(srp_sema_id sem_id)
61{
62 unsigned long flags;
63
64 if (sem_id < 0 || sem_id >= MAX_SRP_SEMAPHORES)
65 return -EINVAL;
66
67 queue_lock_irqsave(&srp_lock, flags);
68 srp_sems[sem_id].claimed = 1;
69 if (/* srp_sems[sem_id].pc_task higher prio than spc_task */1) {
70 spc_task = srp_sems[sem_id].pc_task;
71 }
72 queue_unlock_irqrestore(&srp_lock, flags);
73
74 return 0;
75}
76
77/* Adjust the system-wide priority ceiling if resource is freed. */
78asmlinkage long sys_srp_up(srp_sema_id sem_id)
79{
80 srp_sema_id sem_ctr;
81 unsigned long flags;
82
83 if (sem_id < 0 || sem_id >= MAX_SRP_SEMAPHORES)
84 return -EINVAL;
85
86 queue_lock_irqsave(&srp_lock, flags);
87 srp_sems[sem_id].claimed = 0;
88 spc_task = NULL;
89 for (sem_ctr = 0; sem_ctr < MAX_SRP_SEMAPHORES; sem_ctr++) {
90 if (srp_sems[sem_ctr].used && srp_sems[sem_ctr].claimed /* && */
91 /* srp_sems[sem_ctr].pc_task higher prio than spc_task */) {
92 spc_task = srp_sems[sem_ctr].pc_task;
93 }
94 }
95 queue_unlock_irqrestore(&srp_lock, flags);
96
97 return 0;
98}
99
100/* Indicate that task will use a resource associated with a given
101 * semaphore. Should be done *a priori* before RT task system is
102 * executed, so this does *not* update the system priority
103 * ceiling! (The ceiling would be meaningless anyway, as the SRP
104 * breaks without this a priori knowledge.)
105 */
106asmlinkage long register_task_with_srp_sem(srp_sema_id sem_id,
107 struct task_struct *t)
108{
109 unsigned long flags;
110
111 if (sem_id < 0 || sem_id >= MAX_SRP_SEMAPHORES)
112 return -EINVAL;
113
114 queue_lock_irqsave(&srp_lock, flags);
115 if (/* t higher prio than srp_sems[sem_id].pc_task */1) {
116 srp_sems[sem_id].pc_task = t;
117 }
118 queue_unlock_irqrestore(&srp_lock, flags);
119
120 return 0;
121}
122
123/* Wait for current task priority to exceed system-wide priority ceiling.
124 * Can be used to determine when it is safe to run a job after its release.
125 */
126void wait_until_exceed_spc(void)
127{
128 unsigned long flags;
129
130 queue_lock_irqsave(&srp_lock, flags);
131 for (;;) { /* use callbacks here... */
132 if (/* current higher prio than spc_task */1) {
133 break;
134 }
135 queue_unlock_irqrestore(&srp_lock, flags);
136 schedule();
137 queue_lock_irqsave(&srp_lock, flags);
138 }
139 queue_unlock_irqrestore(&srp_lock, flags);
140}
141
142/* Free semaphore. */
143asmlinkage long sys_srp_sema_free(srp_sema_id sem_id)
144{
145 srp_sems[sem_id].used = 0;
146 return 0;
147}
148
149#endif