blob: 5ef5e54d600d27f41f0ed7abdabddac877b9efa8 (
plain) (
tree)
|
|
#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);
}
|