~martin-decky/helenos/rcu

« back to all changes in this revision

Viewing changes to kernel/generic/src/synch/rcu.c

  • Committer: Martin Decky
  • Date: 2012-06-20 12:49:14 UTC
  • Revision ID: martin@decky.cz-20120620124914-pz3zbgxsh651ab52
initial work queue implementation

Show diffs side-by-side

added added

removed removed

Lines of Context:
288
288
                 * callbacks could exist in the old queue and a new one
289
289
                 * at the same time.
290
290
                 */
291
 
                // workq_t *workq = RCU_VOL(workq_t *, rcu_cb.workq);
 
291
                workq_t *workq = RCU_VOLATILE(workq_t *, rcu_cb.workq);
292
292
                
293
293
                /*
294
294
                 * This is where the nextlist from last grace period is
311
311
                                 * so that all the non-exclusive callbacks are
312
312
                                 * processed as soon as possible.
313
313
                                 */
314
 
#if 0
315
 
                                if (!workq_dispatch(workq,
316
 
                                    (task_func_t *) list->rcu_func, list,
317
 
                                    TQ_NOSLEEP | TQ_NOQUEUE)) {
 
314
                                if (!workq_dispatch(workq, (workq_fn_t) list->func,
 
315
                                    list, WORKQ_FLAG_NOQUEUE)) {
318
316
                                        *failed_end = list;
319
317
                                        failed_end = &list->next;
320
318
                                        list = next;
321
319
                                        goto failure;
322
320
                                }
323
 
#endif
 
321
                                
324
322
                                break;
325
323
                        }
326
324
                } while ((list = next) != NULL);
339
337
                 * and sleep waiting for the queue later on, with the correct
340
338
                 * order of the exclusive callbacks.
341
339
                 */
342
 
//failure:
 
340
failure:
343
341
                for (; list; list = next) {
344
342
                        next = list->next;
345
343
                        weight_sum += atomic_get(&list->weight);
365
363
                
366
364
                do {
367
365
                        next = failed_list->next;
368
 
#if 0
369
 
                        (void) workq_dispatch(workq,
370
 
                            (task_func_t *)failed_list->rcu_func,
371
 
                            failed_list, TQ_SLEEP);
372
 
#endif
 
366
                        (void) workq_dispatch(workq, (workq_fn_t) failed_list->func,
 
367
                            failed_list, 0);
373
368
                } while ((failed_list = next) != NULL);
374
369
                
375
370
                /*
379
374
                atomic_postsub(&CPU->rcu.weight, weight_sum);
380
375
        }
381
376
        
382
 
        CPU->rcu.curlist = RCU_VOL(rcu_t *, CPU->rcu.nextlist);
 
377
        CPU->rcu.curlist = RCU_VOLATILE(rcu_t *, CPU->rcu.nextlist);
383
378
        if (CPU->rcu.curlist) {
384
379
                /*
385
380
                 * The following two assignments must not be reordered. The
386
381
                 * volatile cast makes sure it will not happen.
387
382
                 */
388
 
                RCU_VOL(rcu_t *, CPU->rcu.nextlist) = NULL;
389
 
                RCU_VOL(rcu_t **, CPU->rcu.curtail) =
 
383
                RCU_VOLATILE(rcu_t *, CPU->rcu.nextlist) = NULL;
 
384
                RCU_VOLATILE(rcu_t **, CPU->rcu.curtail) =
390
385
                    atomic_swap_ptr(&CPU->rcu.nexttail,
391
386
                        &CPU->rcu.nextlist);
392
387
        }
463
458
 
464
459
static workq_t *rcu_start_workq(const char *name)
465
460
{
466
 
#if 0
467
 
        return workq_create(name, RCU_WORKQ_NCPUS * rcu_cpu_tasks,
468
 
            RCU_WORKQ_NCPUS + rcu_cpu_tasks, INT_MAX,
469
 
            rcu_cb.proc, WORKQ_DYNAMIC | WORKQ_PREPOPULATE);
470
 
#endif
471
 
        return NULL;  // FIXME
 
461
        return workq_create(RCU_WORKQ_NCPUS * rcu_cpu_tasks, name);
472
462
}
473
463
 
474
464
void rcu_init(void)