diff options
Diffstat (limited to 'litmus/kexclu_affinity.c')
-rw-r--r-- | litmus/kexclu_affinity.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/litmus/kexclu_affinity.c b/litmus/kexclu_affinity.c new file mode 100644 index 000000000000..5ef5e54d600d --- /dev/null +++ b/litmus/kexclu_affinity.c | |||
@@ -0,0 +1,92 @@ | |||
1 | #include <litmus/fdso.h> | ||
2 | #include <litmus/sched_plugin.h> | ||
3 | #include <litmus/trace.h> | ||
4 | #include <litmus/litmus.h> | ||
5 | #include <litmus/locking.h> | ||
6 | |||
7 | #include <litmus/kexclu_affinity.h> | ||
8 | |||
9 | static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg); | ||
10 | static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg); | ||
11 | static int close_generic_aff_obs(struct od_table_entry* entry); | ||
12 | static void destroy_generic_aff_obs(obj_type_t type, void* sem); | ||
13 | |||
14 | struct fdso_ops generic_affinity_ops = { | ||
15 | .create = create_generic_aff_obs, | ||
16 | .open = open_generic_aff_obs, | ||
17 | .close = close_generic_aff_obs, | ||
18 | .destroy = destroy_generic_aff_obs | ||
19 | }; | ||
20 | |||
21 | static atomic_t aff_obs_id_gen = ATOMIC_INIT(0); | ||
22 | |||
23 | static inline bool is_affinity_observer(struct od_table_entry *entry) | ||
24 | { | ||
25 | return (entry->class == &generic_affinity_ops); | ||
26 | } | ||
27 | |||
28 | static inline struct affinity_observer* get_affinity_observer(struct od_table_entry* entry) | ||
29 | { | ||
30 | BUG_ON(!is_affinity_observer(entry)); | ||
31 | return (struct affinity_observer*) entry->obj->obj; | ||
32 | } | ||
33 | |||
34 | static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg) | ||
35 | { | ||
36 | struct affinity_observer* aff_obs; | ||
37 | int err; | ||
38 | |||
39 | err = litmus->allocate_aff_obs(&aff_obs, type, arg); | ||
40 | if (err == 0) { | ||
41 | BUG_ON(!aff_obs->lock); | ||
42 | aff_obs->type = type; | ||
43 | *obj_ref = aff_obs; | ||
44 | } | ||
45 | return err; | ||
46 | } | ||
47 | |||
48 | static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg) | ||
49 | { | ||
50 | struct affinity_observer* aff_obs = get_affinity_observer(entry); | ||
51 | if (aff_obs->ops->open) | ||
52 | return aff_obs->ops->open(aff_obs, arg); | ||
53 | else | ||
54 | return 0; /* default: any task can open it */ | ||
55 | } | ||
56 | |||
57 | static int close_generic_aff_obs(struct od_table_entry* entry) | ||
58 | { | ||
59 | struct affinity_observer* aff_obs = get_affinity_observer(entry); | ||
60 | if (aff_obs->ops->close) | ||
61 | return aff_obs->ops->close(aff_obs); | ||
62 | else | ||
63 | return 0; /* default: closing succeeds */ | ||
64 | } | ||
65 | |||
66 | static void destroy_generic_aff_obs(obj_type_t type, void* obj) | ||
67 | { | ||
68 | struct affinity_observer* aff_obs = (struct affinity_observer*) obj; | ||
69 | aff_obs->ops->deallocate(aff_obs); | ||
70 | } | ||
71 | |||
72 | |||
73 | struct litmus_lock* get_lock_from_od(int od) | ||
74 | { | ||
75 | extern struct fdso_ops generic_lock_ops; | ||
76 | |||
77 | struct od_table_entry *entry = get_entry_for_od(od); | ||
78 | |||
79 | if(entry && entry->class == &generic_lock_ops) { | ||
80 | return (struct litmus_lock*) entry->obj->obj; | ||
81 | } | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | void affinity_observer_new(struct affinity_observer* aff, | ||
86 | struct affinity_observer_ops* ops, | ||
87 | struct affinity_observer_args* args) | ||
88 | { | ||
89 | aff->ops = ops; | ||
90 | aff->lock = get_lock_from_od(args->lock_od); | ||
91 | aff->ident = atomic_inc_return(&aff_obs_id_gen); | ||
92 | } \ No newline at end of file | ||