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
|
#include <litmus/fdso.h>
#include <litmus/sched_plugin.h>
#include <litmus/trace.h>
#include <litmus/litmus.h>
#include <litmus/locking.h>
#include <litmus/kexclu_affinity.h>
static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg);
static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg);
static int close_generic_aff_obs(struct od_table_entry* entry);
static void destroy_generic_aff_obs(obj_type_t type, void* sem);
struct fdso_ops generic_affinity_ops = {
.create = create_generic_aff_obs,
.open = open_generic_aff_obs,
.close = close_generic_aff_obs,
.destroy = destroy_generic_aff_obs
};
static atomic_t aff_obs_id_gen = ATOMIC_INIT(0);
static inline bool is_affinity_observer(struct od_table_entry *entry)
{
return (entry->class == &generic_affinity_ops);
}
static inline struct affinity_observer* get_affinity_observer(struct od_table_entry* entry)
{
BUG_ON(!is_affinity_observer(entry));
return (struct affinity_observer*) entry->obj->obj;
}
static int create_generic_aff_obs(void** obj_ref, obj_type_t type, void* __user arg)
{
struct affinity_observer* aff_obs;
int err;
err = litmus->allocate_aff_obs(&aff_obs, type, arg);
if (err == 0) {
BUG_ON(!aff_obs->lock);
aff_obs->type = type;
*obj_ref = aff_obs;
}
return err;
}
static int open_generic_aff_obs(struct od_table_entry* entry, void* __user arg)
{
struct affinity_observer* aff_obs = get_affinity_observer(entry);
if (aff_obs->ops->open)
return aff_obs->ops->open(aff_obs, arg);
else
return 0; /* default: any task can open it */
}
static int close_generic_aff_obs(struct od_table_entry* entry)
{
struct affinity_observer* aff_obs = get_affinity_observer(entry);
if (aff_obs->ops->close)
return aff_obs->ops->close(aff_obs);
else
return 0; /* default: closing succeeds */
}
static void destroy_generic_aff_obs(obj_type_t type, void* obj)
{
struct affinity_observer* aff_obs = (struct affinity_observer*) obj;
aff_obs->ops->deallocate(aff_obs);
}
struct litmus_lock* get_lock_from_od(int od)
{
extern struct fdso_ops generic_lock_ops;
struct od_table_entry *entry = get_entry_for_od(od);
if(entry && entry->class == &generic_lock_ops) {
return (struct litmus_lock*) entry->obj->obj;
}
return NULL;
}
void affinity_observer_new(struct affinity_observer* aff,
struct affinity_observer_ops* ops,
struct affinity_observer_args* args)
{
aff->ops = ops;
aff->lock = get_lock_from_od(args->lock_od);
aff->ident = atomic_inc_return(&aff_obs_id_gen);
}
|