#ifndef __DGL_H_ #define __DGL_H_ /** * TODO: reduce size of types */ #include #include struct dgl; struct dgl_group_req; typedef void (*acquired_t)(struct dgl_group_req *greq); typedef void (*preempted_t)(struct dgl_group_req *greq); typedef unsigned long long (*prio_t)(struct dgl *dgl, struct dgl_group_req *greq); /* * A request for @replica amount of a single resource. */ struct dgl_req { struct dgl_group_req *greq; unsigned short replicas; struct list_head list; }; /* * Simultaneous @requests for multiple resources. */ struct dgl_group_req { unsigned int cpu; /* Request status flags */ unsigned long *requested; /* Resources requested */ unsigned long *need_prio; /* Resources it can't take */ unsigned long *blocked; /* TODO: use bitops to reduce number of requests to only needed, * get index by counting number of 1s up to a point */ struct dgl_req *requests; /* Request priority in lists */ unsigned long long priority; struct task_struct *task; /* Tie-breaking */ }; /* * A single resource. */ struct dgl_resource { int goal_free; int real_free; /* Requests whose group requests don't have priority on all replicas. * group request state: need_prio && dgl->acquired[cpu] != greq */ struct list_head waiting; /* Hi-to-lo */ /* Requests whose group requests no longer have priority, but currently * hold all resources. * group request state: need_prio && dgl->acquired[cpu] == greq */ struct list_head will_wait; /* Hi-to-lo */ /* Requests whose group requests both have priority and hold all * requested resources. * group request state: !need_prio && !blocking && acquired[cpu] == greq */ struct list_head acquired; /* Lo-to-hi */ /* Requests whose group requests have priority but are blocked from * acquiring some resource. * group request state: need_prio && blocking && acquired[cpu] != greq */ struct list_head will_acquire; /* Lo-to-hi */ }; /* * A group of resources. */ struct dgl { struct dgl_resource *resources; struct dgl_group_req* *acquired; int requests; unsigned long long ts; unsigned long num_resources; unsigned long num_replicas; /* A group request now owns all of its resources */ acquired_t cpu_acquired; /* Assign priority (lower is better) to a group request */ prio_t assign_priority; /* Called when a request is preempted. Leave at NULL for no calls */ preempted_t cpu_preempted; }; void dgl_init(struct dgl *dgl, unsigned long num_resources, unsigned long num_replicas); void dgl_free(struct dgl *dgl); void dgl_group_req_init(struct dgl *dgl, struct dgl_group_req *greq); void dgl_group_req_free(struct dgl_group_req *greq); void set_req(struct dgl *dgl, struct dgl_group_req *greq, int resource, int replicas); void add_group_req(struct dgl *dgl, struct dgl_group_req *greq, int cpu); void remove_group_req(struct dgl *dgl, struct dgl_group_req *greq); void update_group_req(struct dgl *dgl, struct dgl_group_req *greq); #endif