chergert / iris

Message passing, Work-Stealing, Lock-Free, Dynamic Scheduling, and other buzzwords for GLib

This URL has Read+Write access

iris / iris / iris-coordination-arbiter.c
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 1 /* iris-coordination-arbiter.c
085ceaad » chergert 2009-04-17 Beginning of large API addi... 2 *
3 * Copyright (C) 2009 Christian Hergert <chris@dronelabs.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
18 * 02110-1301 USA
19 */
20
21 #include "iris-arbiter.h"
42d899f8 » chergert 2009-09-19 Cleanup of the public API a... 22 #include "iris-arbiter-private.h"
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 23 #include "iris-coordination-arbiter.h"
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 24 #include "iris-coordination-arbiter-private.h"
085ceaad » chergert 2009-04-17 Beginning of large API addi... 25 #include "iris-port.h"
26 #include "iris-receiver.h"
27 #include "iris-receiver-private.h"
28
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 29 #define ATTACH_ARBITER(r,a) \
30 G_STMT_START { \
31 if (r && !r->priv->arbiter) \
32 r->priv->arbiter = g_object_ref (a); \
085ceaad » chergert 2009-04-17 Beginning of large API addi... 33 } G_STMT_END
34
35 /**
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 36 * SECTION:iris-coordination-receiver
085ceaad » chergert 2009-04-17 Beginning of large API addi... 37 * @short_description: #IrisArbiter to manage exclusive vs concurrent messages
38 *
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 39 * The #IrisCoordinationArbiter provides management over how incoming messages
085ceaad » chergert 2009-04-17 Beginning of large API addi... 40 * can be handled. Its primary purpose is to allow messages to be as
41 * concurrent as possible until an exclusive message is received. When that
42 * happens, it will bleed off the concurrent messages and then run the
43 * exclusive messages. After the exclusive messages have processed, the flood
44 * gates can re-open and throttle back up to full concurrency.
45 */
46
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 47 G_DEFINE_TYPE (IrisCoordinationArbiter,
48 iris_coordination_arbiter,
085ceaad » chergert 2009-04-17 Beginning of large API addi... 49 IRIS_TYPE_ARBITER);
50
51 static IrisReceiveDecision
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 52 can_receive (IrisArbiter *arbiter,
53 IrisReceiver *receiver)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 54 {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 55 IrisCoordinationArbiter *coord;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 56 IrisCoordinationArbiterPrivate *priv;
f411e4bc » chergert 2009-04-20 Try to resume the concurren... 57 IrisReceiver *resume = NULL;
58 IrisReceiveDecision decision = IRIS_RECEIVE_NEVER;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 59
60 g_return_val_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter), IRIS_RECEIVE_NEVER);
61 g_return_val_if_fail (IRIS_IS_RECEIVER (receiver), IRIS_RECEIVE_NEVER);
62
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 63 coord = IRIS_COORDINATION_ARBITER (arbiter);
64 priv = coord->priv;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 65
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 66 g_static_rec_mutex_lock (&priv->mutex);
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 67
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 68 /* Current Receiver: ANY
69 * Request Receiver: ANY
70 * Has Active......: ANY
71 * Pending.........: ANY
72 * Completed.......: YES
73 * Receive.........: NEVER
74 */
75 if (priv->flags & IRIS_COORD_COMPLETE) {
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 76 decision = IRIS_RECEIVE_NEVER;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 77 goto finish;
78 }
79
80 /* Current Receiver: TEARDOWN
81 * Request Receiver: CONCURRENT or EXCLUSIVE
82 * Has Active......: ANY
83 * Pending.........: ANY
84 * Receive.........: NEVER
85 */
86 if (priv->flags & IRIS_COORD_TEARDOWN) {
87 if (receiver == priv->concurrent || receiver == priv->exclusive) {
88 decision = IRIS_RECEIVE_NEVER;
89 goto finish;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 90 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 91 }
92
93 /* Current Receiver: TEARDOWN
94 * Request Receiver: TEARDOWN
95 * Has Active......: 0
96 * Pending.........: NONE
97 * Completed.......: NO
98 * Receive.........: NOW
99 */
100 if (priv->flags & IRIS_COORD_TEARDOWN) {
101 if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
102 if (receiver == priv->teardown) {
103 if (priv->active == 0) {
104 decision = IRIS_RECEIVE_NOW;
105 priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN;
106 priv->flags |= IRIS_COORD_COMPLETE;
107 goto finish;
108 }
eaf6c2dc » chergert 2009-04-19 Make sure we disable the ne... 109 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 110 }
111 }
112
19a2f54e » chergert 2009-04-20 Handle a missing branch for... 113 /* Current Receiver: TEARDOWN
114 * Request Receiver: TEARDOWN
115 * Has Active......: YES
116 * Pending.........: NONE
117 * Completed.......: NO
118 * Receive.........: NEVER
119 */
120 if (priv->flags & IRIS_COORD_TEARDOWN) {
121 if (receiver == priv->teardown) {
122 if (priv->active > 0) {
123 if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
124 decision = IRIS_RECEIVE_NEVER;
125 goto finish;
126 }
127 }
128 }
129 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 130
131 /* Current Receiver: ANY
132 * Request Receiver: CONCURRENT or EXCUSIVE
133 * Has Active......: ANY
134 * Pending.........: TEARDOWN
135 * Receive.........: NEVER
136 */
137 if (receiver == priv->concurrent || receiver == priv->exclusive) {
138 if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
139 decision = IRIS_RECEIVE_NEVER;
140 goto finish;
141 }
142 }
143
144 /* Current Receiver: CONCURRENT
145 * Request Receiver: CONCURRENT
146 * Has Active......: *
147 * Pending.........: NONE or CONCURRENT
148 * Receive.........: NOW
149 */
150 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
151 if (receiver == priv->concurrent) {
152 if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) {
153 decision = IRIS_RECEIVE_NOW;
154 priv->flags &= ~IRIS_COORD_NEEDS_CONCURRENT;
f411e4bc » chergert 2009-04-20 Try to resume the concurren... 155 resume = priv->concurrent;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 156 goto finish;
eaf6c2dc » chergert 2009-04-19 Make sure we disable the ne... 157 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 158 }
159 }
160
161 /* Current Receiver: CONCURRENT
162 * Request Receiver: CONCURRENT
163 * Has Active......: *
164 * Pending.........: ANY
165 * Receive.........: LATER
166 */
167 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
168 if (receiver == priv->concurrent) {
169 if ((priv->flags & IRIS_COORD_NEEDS_ANY) != 0) {
170 decision = IRIS_RECEIVE_LATER;
171 priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
172 goto finish;
eaf6c2dc » chergert 2009-04-19 Make sure we disable the ne... 173 }
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 174 }
175 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 176
177 /* Current Receiver: CONCURRENT
178 * Request Receiver: EXCLUSIVE
179 * Has Active......: YES
180 * Pending.........: ANY
181 * Receive.........: LATER
182 */
183 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 184 if (receiver == priv->exclusive) {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 185 if (priv->active > 0) {
186 decision = IRIS_RECEIVE_LATER;
187 priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
188 goto finish;
189 }
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 190 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 191 }
192
193 /* Current Receiver: CONCURRENT
194 * Request Receiver: EXCLUSIVE
195 * Has Active......: NO
196 * Pending.........: NONE or EXCLUSIVE
197 * Receive.........: NOW
198 */
199 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
200 if (receiver == priv->exclusive) {
201 if (priv->active == 0) {
202 if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_EXCLUSIVE) == IRIS_COORD_NEEDS_EXCLUSIVE) {
203 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 204 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
205 priv->flags |= IRIS_COORD_EXCLUSIVE;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 206 goto finish;
207 }
208 }
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 209 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 210 }
211
212 /* Current Receiver: CONCURRENT
213 * Request Receiver: EXCLUSIVE
214 * Has Active......: NO
215 * Pending.........: EXCLUSIVE or TEARDOWN
216 * Receive.........: NOW
217 */
218 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
219 if (receiver == priv->exclusive) {
220 if (priv->active == 0) {
221 if ((priv->flags & IRIS_COORD_NEEDS_ANY) != IRIS_COORD_NEEDS_CONCURRENT) {
222 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 223 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
224 priv->flags |= IRIS_COORD_EXCLUSIVE;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 225 goto finish;
226 }
227 }
228 }
229 }
230
231 /* Current Receiver: CONCURRENT
232 * Request Receiver: TEARDOWN
233 * Has Active......: NO
234 * Pending.........: NONE or TEARDOWN
235 * Receive.........: NOW
236 */
237 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
238 if (receiver == priv->teardown) {
239 if (priv->active == 0) {
240 if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) {
241 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 242 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
243 priv->flags |= IRIS_COORD_TEARDOWN;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 244 goto finish;
245 }
246 }
247 }
248 }
249
250 /* Current Receiver: CONCURRENT
251 * Request Receiver: TEARDOWN
252 * Has Active......: YES
253 * Pending.........: ANY
254 * Receive.........: LATER
255 */
256 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
257 if (receiver == priv->teardown) {
258 if (priv->active > 0) {
259 decision = IRIS_RECEIVE_LATER;
260 priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
261 goto finish;
262 }
263 }
264 }
265
266 /* Current Receiver: CONCURRENT
267 * Request Receiver: TEARDOWN
268 * Has Active......: NO
269 * Pending.........: ANY
270 * Receive.........: NOW
271 */
272 if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
273 if (receiver == priv->teardown) {
274 if (priv->active == 0) {
275 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 276 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
277 priv->flags |= IRIS_COORD_TEARDOWN;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 278 goto finish;
279 }
280 }
281 }
282
283 /* Current Receiver: EXCLUSIVE
284 * Request Receiver: EXCLUSIVE
285 * Has Active......: YES
286 * Pending.........: ANY
287 * Receive.........: LATER
288 */
289 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
290 if (receiver == priv->exclusive) {
291 if (priv->active > 0) {
292 decision = IRIS_RECEIVE_LATER;
293 priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
294 goto finish;
295 }
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 296 }
297 }
298
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 299 /* Current Receiver: EXCLUSIVE
300 * Request Receiver: EXCLUSIVE
301 * Has Active......: NO
b122d360 » chergert 2009-04-20 Handle a few more common ca... 302 * Pending.........: ANY
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 303 * Receive.........: NOW
b122d360 » chergert 2009-04-20 Handle a few more common ca... 304 * Notes...........: This should help us utilize our exclusive mode
305 * better so we don't do so many switches when
306 * already in exclusive mode.
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 307 */
308 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
309 if (receiver == priv->exclusive) {
310 if (priv->active == 0) {
b122d360 » chergert 2009-04-20 Handle a few more common ca... 311 decision = IRIS_RECEIVE_NOW;
312 priv->flags &= ~IRIS_COORD_NEEDS_EXCLUSIVE;
313 goto finish;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 314 }
315 }
316 }
317
318 /* Current Receiver: EXCLUSIVE
319 * Request Receiver: EXCLUSIVE
320 * Has Active......: NO
321 * Pending.........: CONCURRENT or TEARDOWN
322 * Receive.........: LATER
323 */
324 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
325 if (receiver == priv->exclusive) {
326 if (priv->active == 0) {
327 if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_EXCLUSIVE) {
328 decision = IRIS_RECEIVE_LATER;
329 priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
330 goto finish;
331 }
332 }
333 }
334 }
335
336 /* Current Receiver: EXCLUSIVE
337 * Request Receiver: EXCLUSIVE
338 * Has Active......: YES
339 * Pending.........: ANY
340 * Receive.........: LATER
341 */
342 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
343 if (receiver == priv->exclusive) {
344 if (priv->active > 0) {
345 decision = IRIS_RECEIVE_LATER;
346 priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
347 goto finish;
348 }
349 }
350 }
351
352 /* Current Receiver: EXCLUSIVE
353 * Request Receiver: CONCURRENT
354 * Has Active......: NO
355 * Pending.........: NONE or CONCURRENT
356 * Receive.........: NOW
357 */
358 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
359 if (receiver == priv->concurrent) {
360 if (priv->active == 0) {
361 if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) {
362 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 363 priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT);
364 priv->flags |= IRIS_COORD_CONCURRENT;
f411e4bc » chergert 2009-04-20 Try to resume the concurren... 365 resume = priv->concurrent;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 366 goto finish;
367 }
368 }
369 }
370 }
371
372 /* Current Receiver: EXCLUSIVE
373 * Request Receiver: CONCURRENT
374 * Has Active......: NO
375 * Pending.........: EXCLUSIVE or TEARDOWN
376 * Receive.........: LATER
377 */
378 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
379 if (receiver == priv->concurrent) {
380 if (priv->active == 0) {
381 if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_CONCURRENT) {
382 decision = IRIS_RECEIVE_LATER;
383 priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
384 goto finish;
385 }
386 }
387 }
388 }
389
390 /* Current Receiver: EXCLUSIVE
391 * Request Receiver: CONCURRENT
392 * Has Active......: YES
393 * Pending.........: ANY
394 * Receive.........: LATER
395 */
396 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
397 if (receiver == priv->concurrent) {
398 if (priv->active > 0) {
399 decision = IRIS_RECEIVE_LATER;
400 priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
401 goto finish;
402 }
403 }
404 }
405
406 /* Current Receiver: EXCLUSIVE
407 * Request Receiver: TEARDOWN
408 * Has Active......: NO
409 * Pending.........: NONE or TEARDOWN
410 * Receive.........: NOW
411 */
412 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
413 if (receiver == priv->teardown) {
414 if (priv->active == 0) {
415 if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) {
416 decision = IRIS_RECEIVE_NOW;
4014a22d » chergert 2009-04-20 Swap flags for IRIS_RECEIVE... 417 priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN);
418 priv->flags |= IRIS_COORD_TEARDOWN;
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 419 goto finish;
420 }
421 }
422 }
423 }
424
425 /* Current Receiver: EXCLUSIVE
426 * Request Receiver: TEARDOWN
427 * Has Active......: YES
428 * Pending.........: ANY
429 * Receive.........: LATER
430 */
431 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
432 if (receiver == priv->teardown) {
433 if (priv->active > 0) {
434 decision = IRIS_RECEIVE_LATER;
435 priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
436 goto finish;
437 }
438 }
439 }
440
441 /* Current Receiver: EXCLUSIVE
442 * Request Receiver: TEARDOWN
443 * Has Active......: NO
444 * Pending.........: ANY
445 * Receive.........: LATER
446 */
447 if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
448 if (receiver == priv->teardown) {
7d413868 » chergert 2009-05-26 Fix comparison for branch, ... 449 if (priv->active <= 0) {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 450 decision = IRIS_RECEIVE_LATER;
451 priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
452 goto finish;
453 }
454 }
455 }
456
457 g_print ("\nMISSING ARBITER BRANCH REPORT\n"
458 "====================================\n"
459 "Current.....: %s\n"
460 "Receiver....: %s\n"
461 "Active......: %lu\n"
462 "Pending.....: %u\n",
463 (priv->flags & IRIS_COORD_EXCLUSIVE) ? "EXCLUSIVE" : (priv->flags & IRIS_COORD_CONCURRENT) ? "CONCURRENT" : "TEARDOWN",
464 (receiver == priv->exclusive) ? "EXCLUSIVE" : (receiver == priv->concurrent) ? "CONCURRENT" : "TEARDOWN",
465 priv->active,
466 priv->flags & IRIS_COORD_NEEDS_ANY);
467
468 finish:
19a2f54e » chergert 2009-04-20 Handle a missing branch for... 469 if (decision == IRIS_RECEIVE_NOW) {
470 if (receiver == priv->teardown)
471 priv->flags |= IRIS_COORD_COMPLETE;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 472 g_atomic_int_inc ((gint*)&priv->active);
19a2f54e » chergert 2009-04-20 Handle a missing branch for... 473 }
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 474
582b140f » chergert 2009-04-20 Fix a deadlock. 475 /* It would be nice to hold on to this lock while we resume to make
476 * sure our resuming receiver gets more in, but it can create a
477 * dead-lock if we are calling resume and try to lock on the receiver
478 * while someone in the receiver thread is trying to lock on us to
479 * try to deliver. */
480 g_static_rec_mutex_unlock (&priv->mutex);
481
f411e4bc » chergert 2009-04-20 Try to resume the concurren... 482 if (resume)
483 iris_receiver_resume (resume);
484
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 485 return decision;
085ceaad » chergert 2009-04-17 Beginning of large API addi... 486 }
487
488 static void
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 489 receive_completed (IrisArbiter *arbiter,
490 IrisReceiver *receiver)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 491 {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 492 IrisCoordinationArbiter *coord;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 493 IrisCoordinationArbiterPrivate *priv;
494 IrisReceiver *resume = NULL;
495
496 g_return_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter));
497 g_return_if_fail (IRIS_IS_RECEIVER (receiver));
498
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 499 coord = IRIS_COORDINATION_ARBITER (arbiter);
500 priv = coord->priv;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 501
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 502 g_static_rec_mutex_lock (&priv->mutex);
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 503
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 504 if (g_atomic_int_dec_and_test ((gint*)&priv->active)) {
582b140f » chergert 2009-04-20 Fix a deadlock. 505 if (priv->flags & IRIS_COORD_COMPLETE) {
506 }
507 else if (priv->flags & IRIS_COORD_CONCURRENT) {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 508 if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) {
509 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
510 priv->flags |= IRIS_COORD_EXCLUSIVE;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 511 resume = priv->exclusive;
512 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 513 else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
514 priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
515 priv->flags |= IRIS_COORD_TEARDOWN;
516 resume = priv->teardown;
517 }
e85fdaa4 » chergert 2009-05-27 In case we were paused duri... 518 else if (!priv->concurrent->priv->active) {
519 resume = priv->concurrent;
520 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 521 }
522 else if (priv->flags & IRIS_COORD_EXCLUSIVE) {
b122d360 » chergert 2009-04-20 Handle a few more common ca... 523 if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) {
524 /* Try to save mode switches by running exclusive now
525 * regardless of what other modes want to run. */
526 resume = priv->exclusive;
527 }
528 else if (priv->flags & IRIS_COORD_NEEDS_CONCURRENT) {
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 529 priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT);
530 priv->flags |= IRIS_COORD_CONCURRENT;
eaf6c2dc » chergert 2009-04-19 Make sure we disable the ne... 531 resume = priv->concurrent;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 532 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 533 else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
534 priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN);
535 priv->flags |= IRIS_COORD_TEARDOWN;
eaf6c2dc » chergert 2009-04-19 Make sure we disable the ne... 536 resume = priv->teardown;
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 537 }
e85fdaa4 » chergert 2009-05-27 In case we were paused duri... 538 else if (!priv->exclusive->priv->active) {
539 resume = priv->exclusive;
540 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 541 }
542 else if (priv->flags & IRIS_COORD_TEARDOWN) {
582b140f » chergert 2009-04-20 Fix a deadlock. 543 if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
544 priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN;
545 resume = priv->teardown;
546 }
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 547 }
548 else {
42d899f8 » chergert 2009-09-19 Cleanup of the public API a... 549 g_warn_if_reached ();
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 550 }
551 }
552
582b140f » chergert 2009-04-20 Fix a deadlock. 553 g_static_rec_mutex_unlock (&priv->mutex);
554
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 555 if (resume)
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 556 iris_receiver_resume (resume);
085ceaad » chergert 2009-04-17 Beginning of large API addi... 557 }
558
559 static void
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 560 iris_coordination_arbiter_finalize (GObject *object)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 561 {
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 562 G_OBJECT_CLASS (iris_coordination_arbiter_parent_class)->finalize (object);
085ceaad » chergert 2009-04-17 Beginning of large API addi... 563 }
564
565 static void
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 566 iris_coordination_arbiter_class_init (IrisCoordinationArbiterClass *klass)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 567 {
568 GObjectClass *object_class = G_OBJECT_CLASS (klass);
569 IrisArbiterClass *arbiter_class = IRIS_ARBITER_CLASS (klass);
570
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 571 arbiter_class->can_receive = can_receive;
572 arbiter_class->receive_completed = receive_completed;
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 573 object_class->finalize = iris_coordination_arbiter_finalize;
085ceaad » chergert 2009-04-17 Beginning of large API addi... 574
42d899f8 » chergert 2009-09-19 Cleanup of the public API a... 575 g_type_class_add_private (object_class, sizeof (IrisCoordinationArbiterPrivate));
085ceaad » chergert 2009-04-17 Beginning of large API addi... 576 }
577
578 static void
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 579 iris_coordination_arbiter_init (IrisCoordinationArbiter *arbiter)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 580 {
581 arbiter->priv = G_TYPE_INSTANCE_GET_PRIVATE (arbiter,
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 582 IRIS_TYPE_COORDINATION_ARBITER,
583 IrisCoordinationArbiterPrivate);
1f3bcfea » chergert 2009-04-20 Implement an easier to mana... 584 g_static_rec_mutex_init (&arbiter->priv->mutex);
585 arbiter->priv->flags = IRIS_COORD_CONCURRENT;
085ceaad » chergert 2009-04-17 Beginning of large API addi... 586 }
587
ea49f81c » chergert 2009-06-06 Add basic debian packaging. 588 static IrisArbiter*
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 589 iris_coordination_arbiter_new (IrisReceiver *exclusive,
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 590 IrisReceiver *concurrent,
591 IrisReceiver *teardown)
085ceaad » chergert 2009-04-17 Beginning of large API addi... 592 {
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 593 IrisCoordinationArbiter *arbiter;
085ceaad » chergert 2009-04-17 Beginning of large API addi... 594
595 g_return_val_if_fail (exclusive == NULL || IRIS_IS_RECEIVER (exclusive), NULL);
596 g_return_val_if_fail (concurrent == NULL || IRIS_IS_RECEIVER (concurrent), NULL);
597 g_return_val_if_fail (teardown == NULL || IRIS_IS_RECEIVER (teardown), NULL);
76ba41c2 » chergert 2009-04-19 Add more guards to iris_coo... 598
786ad23d » chergert 2009-04-19 Fix comparison logic. 599 g_return_val_if_fail (!exclusive || exclusive != concurrent, NULL);
600 g_return_val_if_fail (!teardown || exclusive != teardown, NULL);
601 g_return_val_if_fail (!concurrent || concurrent != teardown, NULL);
602 g_return_val_if_fail (exclusive || concurrent || teardown, NULL);
085ceaad » chergert 2009-04-17 Beginning of large API addi... 603
1d512571 » chergert 2009-04-17 Rename concurrency to coord... 604 arbiter = g_object_new (IRIS_TYPE_COORDINATION_ARBITER, NULL);
65bb9d6f » chergert 2009-04-17 Start implementing coordina... 605 arbiter->priv->exclusive = exclusive ? g_object_ref (exclusive) : NULL;
606 arbiter->priv->concurrent = concurrent ? g_object_ref (concurrent) : NULL;
607 arbiter->priv->teardown = teardown ? g_object_ref (teardown) : NULL;
085ceaad » chergert 2009-04-17 Beginning of large API addi... 608
609 ATTACH_ARBITER (exclusive, arbiter);
610 ATTACH_ARBITER (concurrent, arbiter);
611 ATTACH_ARBITER (teardown, arbiter);
612
613 return IRIS_ARBITER (arbiter);
614 }
ea49f81c » chergert 2009-06-06 Add basic debian packaging. 615
42d899f8 » chergert 2009-09-19 Cleanup of the public API a... 616 /**
617 * iris_arbiter_coordinate:
618 * @exclusive: An #IrisReceiver
619 * @concurrent: An #IrisReceiver
620 * @teardown: An #IrisReceiver
621 *
622 * Coordinates messages incoming to the receivers. This is used to guarantee
623 * semantics for the receivers.
624 *
625 * Any message received on the @exclusive receiver is guaranteed to be the
626 * only message received at a time. No other exclusive, concurrent, or
627 * teardown messages will be running.
628 *
629 * Messages received on the @concurrent receiver can be received concurrently
630 * meaning more than one message is allowed to be received at a time.
631 *
632 * Only one message can be recieved on @teardown ever. After a message has
633 * been received on @teardown, no further messages will ever be received
634 * on any receivers.
635 *
636 * Return value: An new #IrisArbiter that will arbitrate messages incoming
637 * to the passed receivers.
638 */
ea49f81c » chergert 2009-06-06 Add basic debian packaging. 639 IrisArbiter*
640 iris_arbiter_coordinate (IrisReceiver *exclusive,
641 IrisReceiver *concurrent,
642 IrisReceiver *teardown)
643 {
644 return iris_coordination_arbiter_new (exclusive, concurrent, teardown);
645 }