aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-07-28 23:05:28 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-07-28 23:05:28 +0000
commitcc7efcc843411a956524a00c91425b9d626b03c3 (patch)
treebc74f366f789730ed4d3cba88f02d3fa1fa75ac3 /src/testbed
parent22d40dc40f33986ced0f6dafd01d62a73171a014 (diff)
downloadgnunet-cc7efcc843411a956524a00c91425b9d626b03c3.tar.gz
gnunet-cc7efcc843411a956524a00c91425b9d626b03c3.zip
testbed operations
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/testbed_api_operations.c187
-rw-r--r--src/testbed/testbed_api_operations.h2
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 */
33struct 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 */
56struct 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
76enum 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 */
33struct GNUNET_TESTBED_Operation 95struct 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;
60struct 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 */
147static void
148call_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 */
166static void
167check_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)
98void 209void
99GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue) 210GNUNET_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
119GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue, 231GNUNET_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
136GNUNET_TESTBED_operation_queue_remove_ (struct OperationQueue *queue, 257GNUNET_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 */
149void 287void
150operation_release_ (struct GNUNET_TESTBED_Operation *operation) 288GNUNET_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 */
137void 137void
138operation_release_ (struct GNUNET_TESTBED_Operation *operation); 138GNUNET_TESTBED_operation_release_ (struct GNUNET_TESTBED_Operation *operation);
139 139
140 140
141#endif 141#endif