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
|
#ifndef __DGL_H_
#define __DGL_H_
/**
* TODO: reduce size of types
*/
#include <litmus/color.h>
#include <linux/list.h>
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
|