aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/locking.c')
-rw-r--r--litmus/locking.c123
1 files changed, 123 insertions, 0 deletions
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