ck_epoch: Allow for deferral from callbacks.

This makes things much easier in cases where deferral is mixed
with other reclamation mechanisms such as reference counters.
ck_pring
Samy Al Bahra 10 years ago
parent 0f7827f479
commit b3f374cb55

@ -1,6 +1,6 @@
.PHONY: check clean distribution .PHONY: check clean distribution
OBJECTS=ck_stack ck_epoch_synchronize ck_epoch_poll OBJECTS=ck_stack ck_epoch_synchronize ck_epoch_poll ck_epoch_call
HALF=`expr $(CORES) / 2` HALF=`expr $(CORES) / 2`
all: $(OBJECTS) all: $(OBJECTS)
@ -16,6 +16,9 @@ ck_epoch_synchronize: ck_epoch_synchronize.c ../../../include/ck_stack.h ../../.
ck_epoch_poll: ck_epoch_poll.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../../../src/ck_epoch.c ck_epoch_poll: ck_epoch_poll.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../../../src/ck_epoch.c
$(CC) $(CFLAGS) -o ck_epoch_poll ck_epoch_poll.c ../../../src/ck_epoch.c $(CC) $(CFLAGS) -o ck_epoch_poll ck_epoch_poll.c ../../../src/ck_epoch.c
ck_epoch_call: ck_epoch_call.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../../../src/ck_epoch.c
$(CC) $(CFLAGS) -o ck_epoch_call ck_epoch_call.c ../../../src/ck_epoch.c
ck_stack: ck_stack.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../../../src/ck_epoch.c ck_stack: ck_stack.c ../../../include/ck_stack.h ../../../include/ck_epoch.h ../../../src/ck_epoch.c
$(CC) $(CFLAGS) -o ck_stack ck_stack.c ../../../src/ck_epoch.c $(CC) $(CFLAGS) -o ck_stack ck_stack.c ../../../src/ck_epoch.c

@ -0,0 +1,64 @@
/*
* Copyright 2014 Samy Al Bahra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <ck_epoch.h>
#include "../../common.h"
static ck_epoch_t epoch;
static unsigned int counter;
static ck_epoch_record_t record[2];
static void
cb(ck_epoch_entry_t *p)
{
if (counter == 0)
ck_epoch_call(&epoch, &record[1], p, cb);
printf("Counter value: %u -> %u\n",
counter, counter + 1);
counter++;
return;
}
int
main(void)
{
static ck_epoch_entry_t entry;
ck_epoch_register(&epoch, &record[0]);
ck_epoch_register(&epoch, &record[1]);
ck_epoch_call(&epoch, &record[1], &entry, cb);
ck_epoch_barrier(&epoch, &record[1]);
ck_epoch_barrier(&epoch, &record[1]);
if (counter != 2)
ck_error("Expected counter value 2, read %u.\n", counter);
return 0;
}

@ -257,12 +257,16 @@ static void
ck_epoch_dispatch(struct ck_epoch_record *record, unsigned int e) ck_epoch_dispatch(struct ck_epoch_record *record, unsigned int e)
{ {
unsigned int epoch = e & (CK_EPOCH_LENGTH - 1); unsigned int epoch = e & (CK_EPOCH_LENGTH - 1);
ck_stack_entry_t *next, *cursor; ck_stack_entry_t *head, *next, *cursor;
unsigned int i = 0; unsigned int i = 0;
CK_STACK_FOREACH_SAFE(&record->pending[epoch], cursor, next) { head = CK_STACK_FIRST(&record->pending[epoch]);
ck_stack_init(&record->pending[epoch]);
for (cursor = head; cursor != NULL; cursor = next) {
struct ck_epoch_entry *entry = ck_epoch_entry_container(cursor); struct ck_epoch_entry *entry = ck_epoch_entry_container(cursor);
next = CK_STACK_NEXT(cursor);
entry->function(entry); entry->function(entry);
i++; i++;
} }
@ -272,7 +276,6 @@ ck_epoch_dispatch(struct ck_epoch_record *record, unsigned int e)
record->n_dispatch += i; record->n_dispatch += i;
record->n_pending -= i; record->n_pending -= i;
ck_stack_init(&record->pending[epoch]);
return; return;
} }

Loading…
Cancel
Save