blob: ab643475093f4efa109b7eb3d7bc4c721b154484 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include <litmus/fdso.h>
#ifdef CONFIG_LITMUS_LOCKING
#include <litmus/sched_plugin.h>
#include <litmus/trace.h>
static void* create_generic_lock(obj_type_t type);
static int open_generic_lock(struct od_table_entry* entry, void* __user arg);
static int close_generic_lock(struct od_table_entry* entry);
static void destroy_generic_lock(obj_type_t type, void* sem);
struct fdso_ops generic_lock_ops = {
.create = create_generic_lock,
.open = open_generic_lock,
.close = close_generic_lock,
.destroy = destroy_generic_lock
};
static inline bool is_lock(struct od_table_entry* entry)
{
return entry->class == &generic_lock_ops;
}
static inline struct litmus_lock* get_lock(struct od_table_entry* entry)
{
BUG_ON(!is_lock(entry));
return (struct litmus_lock*) entry->obj->obj;
}
static void* create_generic_lock(obj_type_t type)
{
struct litmus_lock* lock;
int err;
err = litmus->allocate_lock(&lock, type);
if (err == 0)
return lock;
else
return NULL;
}
static int open_generic_lock(struct od_table_entry* entry, void* __user arg)
{
struct litmus_lock* lock = get_lock(entry);
if (lock->ops->open)
return lock->ops->open(lock, arg);
else
return 0; /* default: any task can open it */
}
static int close_generic_lock(struct od_table_entry* entry)
{
struct litmus_lock* lock = get_lock(entry);
if (lock->ops->close)
return lock->ops->close(lock);
else
return 0; /* default: closing succeeds */
}
static void destroy_generic_lock(obj_type_t type, void* obj)
{
struct litmus_lock* lock = (struct litmus_lock*) obj;
lock->ops->deallocate(lock);
}
asmlinkage long sys_litmus_lock(int lock_od)
{
long err = -EINVAL;
struct od_table_entry* entry;
struct litmus_lock* l;
TS_PI_DOWN_START;
entry = get_entry_for_od(lock_od);
if (entry && is_lock(entry)) {
l = get_lock(entry);
TRACE_CUR("attempts to lock 0x%p\n", l);
err = l->ops->lock(l);
}
/* Note: task my have been suspended or preempted in between! Take
* this into account when computing overheads. */
TS_PI_DOWN_END;
return err;
}
asmlinkage long sys_litmus_unlock(int lock_od)
{
long err = -EINVAL;
struct od_table_entry* entry;
struct litmus_lock* l;
TS_PI_UP_START;
entry = get_entry_for_od(lock_od);
if (entry && is_lock(entry)) {
l = get_lock(entry);
TRACE_CUR("attempts to unlock 0x%p\n", l);
err = l->ops->unlock(l);
}
/* Note: task my have been preempted in between! Take this into
* account when computing overheads. */
TS_PI_UP_END;
return err;
}
#else
struct fdso_ops generic_lock_ops = {};
asmlinkage long sys_litmus_lock(int sem_od)
{
return -ENOSYS;
}
asmlinkage long sys_litmus_unlock(int sem_od)
{
return -ENOSYS;
}
#endif
|