aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/litmus/fdso.h7
-rw-r--r--litmus/Makefile1
-rw-r--r--litmus/fdso.c4
-rw-r--r--litmus/locking.c123
4 files changed, 130 insertions, 5 deletions
diff --git a/include/litmus/fdso.h b/include/litmus/fdso.h
index bfab9fdc756c..25a292d68d96 100644
--- a/include/litmus/fdso.h
+++ b/include/litmus/fdso.h
@@ -33,12 +33,13 @@ struct inode_obj_id {
33 unsigned int id; 33 unsigned int id;
34}; 34};
35 35
36struct fdso_ops;
36 37
37struct od_table_entry { 38struct od_table_entry {
38 unsigned int used; 39 unsigned int used;
39 40
40 struct inode_obj_id* obj; 41 struct inode_obj_id* obj;
41 void* extra; 42 const struct fdso_ops* class;
42}; 43};
43 44
44struct fdso_ops { 45struct fdso_ops {
@@ -51,14 +52,14 @@ struct fdso_ops {
51/* translate a userspace supplied od into the raw table entry 52/* translate a userspace supplied od into the raw table entry
52 * returns NULL if od is invalid 53 * returns NULL if od is invalid
53 */ 54 */
54struct od_table_entry* __od_lookup(int od); 55struct od_table_entry* get_entry_for_od(int od);
55 56
56/* translate a userspace supplied od into the associated object 57/* translate a userspace supplied od into the associated object
57 * returns NULL if od is invalid 58 * returns NULL if od is invalid
58 */ 59 */
59static inline void* od_lookup(int od, obj_type_t type) 60static inline void* od_lookup(int od, obj_type_t type)
60{ 61{
61 struct od_table_entry* e = __od_lookup(od); 62 struct od_table_entry* e = get_entry_for_od(od);
62 return e && e->obj->type == type ? e->obj->obj : NULL; 63 return e && e->obj->type == type ? e->obj->obj : NULL;
63} 64}
64 65
diff --git a/litmus/Makefile b/litmus/Makefile
index b7366b530749..4e019d4a6e0c 100644
--- a/litmus/Makefile
+++ b/litmus/Makefile
@@ -11,6 +11,7 @@ obj-y = sched_plugin.o litmus.o \
11 rt_domain.o \ 11 rt_domain.o \
12 edf_common.o \ 12 edf_common.o \
13 fdso.o \ 13 fdso.o \
14 locking.o \
14 srp.o \ 15 srp.o \
15 fmlp.o \ 16 fmlp.o \
16 bheap.o \ 17 bheap.o \
diff --git a/litmus/fdso.c b/litmus/fdso.c
index 3bb331e471df..faede9bcbbbf 100644
--- a/litmus/fdso.c
+++ b/litmus/fdso.c
@@ -190,7 +190,7 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
190 entry->used = 0; 190 entry->used = 0;
191 } else { 191 } else {
192 entry->obj = obj; 192 entry->obj = obj;
193 entry->extra = NULL; 193 entry->class = fdso_ops[type];
194 idx = entry - current->od_table; 194 idx = entry - current->od_table;
195 } 195 }
196 196
@@ -209,7 +209,7 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
209} 209}
210 210
211 211
212struct od_table_entry* __od_lookup(int od) 212struct od_table_entry* get_entry_for_od(int od)
213{ 213{
214 struct task_struct *t = current; 214 struct task_struct *t = current;
215 215
diff --git a/litmus/locking.c b/litmus/locking.c
new file mode 100644
index 000000000000..848407b79b4f
--- /dev/null
+++ b/litmus/locking.c
@@ -0,0 +1,123 @@
1#include <litmus/fdso.h>
2
3#ifdef CONFIG_LITMUS_LOCKING
4
5#include <litmus/sched_plugin.h>
6#include <litmus/trace.h>
7
8static void* create_generic_lock(obj_type_t type);
9static int open_generic_lock(struct od_table_entry* entry, void* __user arg);
10static int close_generic_lock(struct od_table_entry* entry);
11static void destroy_generic_lock(obj_type_t type, void* sem);
12
13struct fdso_ops generic_lock_ops = {
14 .create = create_generic_lock,
15 .open = open_generic_lock,
16 .close = close_generic_lock,
17 .destroy = destroy_generic_lock
18};
19
20static inline bool is_lock(struct od_table_entry* entry)
21{
22 return entry->class == &generic_lock_ops;
23}
24
25static inline struct litmus_lock* get_lock(struct od_table_entry* entry)
26{
27 BUG_ON(!is_lock(entry));
28 return (struct litmus_lock*) entry->obj->obj;
29}
30
31static void* create_generic_lock(obj_type_t type)
32{
33 struct litmus_lock* lock;
34 int err;
35
36 err = litmus->allocate_lock(&lock, type);
37 if (err == 0)
38 return lock;
39 else
40 return NULL;
41}
42
43static int open_generic_lock(struct od_table_entry* entry, void* __user arg)
44{
45 struct litmus_lock* lock = get_lock(entry);
46 if (lock->ops->open)
47 return lock->ops->open(lock, arg);
48 else
49 return 0; /* default: any task can open it */
50}
51
52static int close_generic_lock(struct od_table_entry* entry)
53{
54 struct litmus_lock* lock = get_lock(entry);
55 if (lock->ops->close)
56 return lock->ops->close(lock);
57 else
58 return 0; /* default: closing succeeds */
59}
60
61static void destroy_generic_lock(obj_type_t type, void* obj)
62{
63 struct litmus_lock* lock = (struct litmus_lock*) obj;
64 lock->ops->deallocate(lock);
65}
66
67asmlinkage long sys_litmus_lock(int lock_od)
68{
69 long err = -EINVAL;
70 struct od_table_entry* entry;
71 struct litmus_lock* l;
72
73 TS_PI_DOWN_START;
74
75 entry = get_entry_for_od(lock_od);
76 if (entry && is_lock(entry)) {
77 l = get_lock(entry);
78 err = l->ops->lock(l);
79 }
80
81 /* Note: task my have been suspended or preempted in between! Take
82 * this into account when computing overheads. */
83 TS_PI_DOWN_END;
84
85 return err;
86}
87
88asmlinkage long sys_litmus_unlock(int lock_od)
89{
90 long err = -EINVAL;
91 struct od_table_entry* entry;
92 struct litmus_lock* l;
93
94 TS_PI_UP_START;
95
96 entry = get_entry_for_od(lock_od);
97 if (entry && is_lock(entry)) {
98 l = get_lock(entry);
99 err = l->ops->lock(l);
100 }
101
102 /* Note: task my have been preempted in between! Take this into
103 * account when computing overheads. */
104 TS_PI_UP_END;
105
106 return err;
107}
108
109#else
110
111struct fdso_ops generic_lock_ops = {};
112
113asmlinkage long sys_litmus_lock(int sem_od)
114{
115 return -ENOSYS;
116}
117
118asmlinkage long sys_litmus_unlock(int sem_od)
119{
120 return -ENOSYS;
121}
122
123#endif