diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-07-28 23:05:28 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-07-28 23:05:28 +0000 |
commit | cc7efcc843411a956524a00c91425b9d626b03c3 (patch) | |
tree | bc74f366f789730ed4d3cba88f02d3fa1fa75ac3 /src/testbed | |
parent | 22d40dc40f33986ced0f6dafd01d62a73171a014 (diff) | |
download | gnunet-cc7efcc843411a956524a00c91425b9d626b03c3.tar.gz gnunet-cc7efcc843411a956524a00c91425b9d626b03c3.zip |
testbed operations
Diffstat (limited to 'src/testbed')
-rw-r--r-- | src/testbed/testbed_api_operations.c | 187 | ||||
-rw-r--r-- | src/testbed/testbed_api_operations.h | 2 |
2 files changed, 168 insertions, 21 deletions
diff --git a/src/testbed/testbed_api_operations.c b/src/testbed/testbed_api_operations.c index 31a46d85a..10e9071c6 100644 --- a/src/testbed/testbed_api_operations.c +++ b/src/testbed/testbed_api_operations.c | |||
@@ -28,6 +28,68 @@ | |||
28 | 28 | ||
29 | 29 | ||
30 | /** | 30 | /** |
31 | * An entry in the operation queue | ||
32 | */ | ||
33 | struct QueueEntry | ||
34 | { | ||
35 | /** | ||
36 | * The next DLL pointer | ||
37 | */ | ||
38 | struct QueueEntry *next; | ||
39 | |||
40 | /** | ||
41 | * The prev DLL pointer | ||
42 | */ | ||
43 | struct QueueEntry *prev; | ||
44 | |||
45 | /** | ||
46 | * The operation this entry holds | ||
47 | */ | ||
48 | struct GNUNET_TESTBED_Operation *op; | ||
49 | }; | ||
50 | |||
51 | |||
52 | /** | ||
53 | * Queue of operations where we can only support a certain | ||
54 | * number of concurrent operations of a particular type. | ||
55 | */ | ||
56 | struct OperationQueue | ||
57 | { | ||
58 | /** | ||
59 | * The head of the operation queue | ||
60 | */ | ||
61 | struct QueueEntry *head; | ||
62 | |||
63 | /** | ||
64 | * The tail of the operation queue | ||
65 | */ | ||
66 | struct QueueEntry *tail; | ||
67 | |||
68 | /** | ||
69 | * Number of operations that can be concurrently | ||
70 | * active in this queue. | ||
71 | */ | ||
72 | unsigned int active; | ||
73 | }; | ||
74 | |||
75 | |||
76 | enum OperationState | ||
77 | { | ||
78 | /** | ||
79 | * The operation is currently waiting for resources | ||
80 | */ | ||
81 | OP_STATE_WAITING, | ||
82 | |||
83 | /** | ||
84 | * The operation has started | ||
85 | */ | ||
86 | OP_STATE_STARTED, | ||
87 | }; | ||
88 | |||
89 | |||
90 | |||
91 | |||
92 | /** | ||
31 | * Opaque handle to an abstract operation to be executed by the testing framework. | 93 | * Opaque handle to an abstract operation to be executed by the testing framework. |
32 | */ | 94 | */ |
33 | struct GNUNET_TESTBED_Operation | 95 | struct GNUNET_TESTBED_Operation |
@@ -48,27 +110,76 @@ struct GNUNET_TESTBED_Operation | |||
48 | */ | 110 | */ |
49 | void *cb_cls; | 111 | void *cb_cls; |
50 | 112 | ||
51 | // FIXME! | 113 | /** |
114 | * Array of operation queues this Operation belongs to. | ||
115 | */ | ||
116 | struct OperationQueue **queues; | ||
52 | 117 | ||
53 | }; | 118 | /** |
119 | * The Operation ID | ||
120 | */ | ||
121 | uint64_t id; | ||
54 | 122 | ||
123 | /** | ||
124 | * The id of the task which calls OperationStart for this operation | ||
125 | */ | ||
126 | GNUNET_SCHEDULER_TaskIdentifier start_task_id; | ||
55 | 127 | ||
56 | /** | 128 | /** |
57 | * Queue of operations where we can only support a certain | 129 | * Number of queues in the operation queues array |
58 | * number of concurrent operations of a particular type. | 130 | */ |
59 | */ | 131 | unsigned int nqueues; |
60 | struct OperationQueue | ||
61 | { | ||
62 | 132 | ||
63 | /** | 133 | /** |
64 | * Maximum number of operationst that can be concurrently | 134 | * The state of the operation |
65 | * active in this queue. | ||
66 | */ | 135 | */ |
67 | unsigned int max_active; | 136 | enum OperationState state; |
137 | |||
138 | }; | ||
68 | 139 | ||
69 | // FIXME! | ||
70 | 140 | ||
71 | }; | 141 | /** |
142 | * Task for calling OperationStart on operation | ||
143 | * | ||
144 | * @param cls the Operation | ||
145 | * @param tc the TaskContext from scheduler | ||
146 | */ | ||
147 | static void | ||
148 | call_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
149 | { | ||
150 | struct GNUNET_TESTBED_Operation *op = cls; | ||
151 | |||
152 | op->start_task_id = GNUNET_SCHEDULER_NO_TASK; | ||
153 | if (NULL != op->start) | ||
154 | { | ||
155 | op->start (op->cb_cls); | ||
156 | } | ||
157 | op->state = OP_STATE_STARTED; | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Checks for the readiness of an operation and schedules a operation start task | ||
163 | * | ||
164 | * @param op the operation | ||
165 | */ | ||
166 | static void | ||
167 | check_readiness (struct GNUNET_TESTBED_Operation *op) | ||
168 | { | ||
169 | unsigned int i; | ||
170 | |||
171 | for (i = 0; i < op->nqueues; i++) | ||
172 | { | ||
173 | if (0 == op->queues[i]->active) | ||
174 | return; | ||
175 | } | ||
176 | for (i = 0; i < op->nqueues; i++) | ||
177 | { | ||
178 | op->queues[i]->active--; | ||
179 | } | ||
180 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == op->start_task_id); | ||
181 | op->start_task_id = GNUNET_SCHEDULER_add_now (&call_start, op); | ||
182 | } | ||
72 | 183 | ||
73 | 184 | ||
74 | /** | 185 | /** |
@@ -84,7 +195,7 @@ GNUNET_TESTBED_operation_queue_create_ (unsigned int max_active) | |||
84 | struct OperationQueue *queue; | 195 | struct OperationQueue *queue; |
85 | 196 | ||
86 | queue = GNUNET_malloc (sizeof (struct OperationQueue)); | 197 | queue = GNUNET_malloc (sizeof (struct OperationQueue)); |
87 | queue->max_active = max_active; | 198 | queue->active = max_active; |
88 | return queue; | 199 | return queue; |
89 | } | 200 | } |
90 | 201 | ||
@@ -98,7 +209,8 @@ GNUNET_TESTBED_operation_queue_create_ (unsigned int max_active) | |||
98 | void | 209 | void |
99 | GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue) | 210 | GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue) |
100 | { | 211 | { |
101 | GNUNET_break (0); | 212 | GNUNET_assert (NULL == queue->head); |
213 | GNUNET_assert (NULL == queue->tail); | ||
102 | GNUNET_free (queue); | 214 | GNUNET_free (queue); |
103 | } | 215 | } |
104 | 216 | ||
@@ -119,7 +231,16 @@ void | |||
119 | GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, | 231 | GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, |
120 | struct GNUNET_TESTBED_Operation *operation) | 232 | struct GNUNET_TESTBED_Operation *operation) |
121 | { | 233 | { |
122 | GNUNET_break (0); | 234 | struct QueueEntry *entry; |
235 | |||
236 | entry = GNUNET_malloc (sizeof (struct QueueEntry)); | ||
237 | entry->op = operation; | ||
238 | GNUNET_CONTAINER_DLL_insert_tail (queue->head, queue->tail, entry); | ||
239 | operation->queues = | ||
240 | GNUNET_realloc (operation->queues, | ||
241 | sizeof (struct OperationQueue *) * (++operation->nqueues)); | ||
242 | operation->queues[operation->nqueues - 1] = queue; | ||
243 | check_readiness (operation); | ||
123 | } | 244 | } |
124 | 245 | ||
125 | 246 | ||
@@ -136,7 +257,24 @@ void | |||
136 | GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, | 257 | GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, |
137 | struct GNUNET_TESTBED_Operation *operation) | 258 | struct GNUNET_TESTBED_Operation *operation) |
138 | { | 259 | { |
139 | GNUNET_break (0); | 260 | struct QueueEntry *entry; |
261 | struct QueueEntry *entry2; | ||
262 | |||
263 | for (entry = queue->head; NULL != entry; entry = entry->next) | ||
264 | if (entry->op == operation) | ||
265 | break; | ||
266 | GNUNET_assert (NULL != entry); | ||
267 | if (OP_STATE_STARTED == operation->state) | ||
268 | queue->active++; | ||
269 | GNUNET_CONTAINER_DLL_remove (queue->head, queue->tail, entry); | ||
270 | entry2 = entry->next; | ||
271 | GNUNET_free (entry); | ||
272 | for (; NULL != entry2; entry2 = entry2->next) | ||
273 | if (OP_STATE_STARTED != entry2->op->state) | ||
274 | break; | ||
275 | if (NULL == entry2) | ||
276 | return; | ||
277 | check_readiness (entry2->op); | ||
140 | } | 278 | } |
141 | 279 | ||
142 | 280 | ||
@@ -147,10 +285,19 @@ GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, | |||
147 | * @param operation operation that finished | 285 | * @param operation operation that finished |
148 | */ | 286 | */ |
149 | void | 287 | void |
150 | operation_release_ (struct GNUNET_TESTBED_Operation *operation) | 288 | GNUNET_TESTBED_operation_release_ (struct GNUNET_TESTBED_Operation *operation) |
151 | { | 289 | { |
152 | // call operation->release, remove from queues | 290 | unsigned int i; |
153 | GNUNET_break (0); | 291 | |
292 | if (GNUNET_SCHEDULER_NO_TASK != operation->start_task_id) | ||
293 | { | ||
294 | GNUNET_SCHEDULER_cancel (operation->start_task_id); | ||
295 | operation->start_task_id = GNUNET_SCHEDULER_NO_TASK; | ||
296 | } | ||
297 | if (NULL != operation->release) | ||
298 | operation->release (operation->cb_cls); | ||
299 | for (i = 0; i < operation->nqueues; i++) | ||
300 | GNUNET_TESTBED_operation_queue_remove_ (operation->queues[i], operation); | ||
154 | } | 301 | } |
155 | 302 | ||
156 | 303 | ||
diff --git a/src/testbed/testbed_api_operations.h b/src/testbed/testbed_api_operations.h index 5edca152d..245e9a60e 100644 --- a/src/testbed/testbed_api_operations.h +++ b/src/testbed/testbed_api_operations.h | |||
@@ -135,7 +135,7 @@ GNUNET_TESTBED_operation_create_ (void *cls, | |||
135 | * @param operation operation that finished | 135 | * @param operation operation that finished |
136 | */ | 136 | */ |
137 | void | 137 | void |
138 | operation_release_ (struct GNUNET_TESTBED_Operation *operation); | 138 | GNUNET_TESTBED_operation_release_ (struct GNUNET_TESTBED_Operation *operation); |
139 | 139 | ||
140 | 140 | ||
141 | #endif | 141 | #endif |