Path: blob/main/sys/contrib/ck/include/ck_hp_fifo.h
48254 views
/*1* Copyright 2010-2015 Samy Al Bahra.2* Copyright 2011 David Joseph.3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627#ifndef CK_HP_FIFO_H28#define CK_HP_FIFO_H2930#include <ck_cc.h>31#include <ck_hp.h>32#include <ck_pr.h>33#include <ck_stddef.h>3435#define CK_HP_FIFO_SLOTS_COUNT (2)36#define CK_HP_FIFO_SLOTS_SIZE (sizeof(void *) * CK_HP_FIFO_SLOTS_COUNT)3738/*39* Though it is possible to embed the data structure, measurements need40* to be made for the cost of this. If we were to embed the hazard pointer41* state into the data structure, this means every deferred reclamation42* will also include a cache invalidation when linking into the hazard pointer43* pending queue. This may lead to terrible cache line bouncing.44*/45struct ck_hp_fifo_entry {46void *value;47ck_hp_hazard_t hazard;48struct ck_hp_fifo_entry *next;49};50typedef struct ck_hp_fifo_entry ck_hp_fifo_entry_t;5152struct ck_hp_fifo {53struct ck_hp_fifo_entry *head;54struct ck_hp_fifo_entry *tail;55};56typedef struct ck_hp_fifo ck_hp_fifo_t;5758CK_CC_INLINE static void59ck_hp_fifo_init(struct ck_hp_fifo *fifo, struct ck_hp_fifo_entry *stub)60{6162fifo->head = fifo->tail = stub;63stub->next = NULL;64return;65}6667CK_CC_INLINE static void68ck_hp_fifo_deinit(struct ck_hp_fifo *fifo, struct ck_hp_fifo_entry **stub)69{7071*stub = fifo->head;72fifo->head = fifo->tail = NULL;73return;74}7576CK_CC_INLINE static void77ck_hp_fifo_enqueue_mpmc(ck_hp_record_t *record,78struct ck_hp_fifo *fifo,79struct ck_hp_fifo_entry *entry,80void *value)81{82struct ck_hp_fifo_entry *tail, *next;8384entry->value = value;85entry->next = NULL;86ck_pr_fence_store_atomic();8788for (;;) {89tail = ck_pr_load_ptr(&fifo->tail);90ck_hp_set_fence(record, 0, tail);91if (tail != ck_pr_load_ptr(&fifo->tail))92continue;9394next = ck_pr_load_ptr(&tail->next);95if (next != NULL) {96ck_pr_cas_ptr(&fifo->tail, tail, next);97continue;98} else if (ck_pr_cas_ptr(&fifo->tail->next, next, entry) == true)99break;100}101102ck_pr_fence_atomic();103ck_pr_cas_ptr(&fifo->tail, tail, entry);104return;105}106107CK_CC_INLINE static bool108ck_hp_fifo_tryenqueue_mpmc(ck_hp_record_t *record,109struct ck_hp_fifo *fifo,110struct ck_hp_fifo_entry *entry,111void *value)112{113struct ck_hp_fifo_entry *tail, *next;114115entry->value = value;116entry->next = NULL;117ck_pr_fence_store_atomic();118119tail = ck_pr_load_ptr(&fifo->tail);120ck_hp_set_fence(record, 0, tail);121if (tail != ck_pr_load_ptr(&fifo->tail))122return false;123124next = ck_pr_load_ptr(&tail->next);125if (next != NULL) {126ck_pr_cas_ptr(&fifo->tail, tail, next);127return false;128} else if (ck_pr_cas_ptr(&fifo->tail->next, next, entry) == false)129return false;130131ck_pr_fence_atomic();132ck_pr_cas_ptr(&fifo->tail, tail, entry);133return true;134}135136CK_CC_INLINE static struct ck_hp_fifo_entry *137ck_hp_fifo_dequeue_mpmc(ck_hp_record_t *record,138struct ck_hp_fifo *fifo,139void *value)140{141struct ck_hp_fifo_entry *head, *tail, *next;142143for (;;) {144head = ck_pr_load_ptr(&fifo->head);145ck_pr_fence_load();146tail = ck_pr_load_ptr(&fifo->tail);147ck_hp_set_fence(record, 0, head);148if (head != ck_pr_load_ptr(&fifo->head))149continue;150151next = ck_pr_load_ptr(&head->next);152ck_hp_set_fence(record, 1, next);153if (head != ck_pr_load_ptr(&fifo->head))154continue;155156if (head == tail) {157if (next == NULL)158return NULL;159160ck_pr_cas_ptr(&fifo->tail, tail, next);161continue;162} else if (ck_pr_cas_ptr(&fifo->head, head, next) == true)163break;164}165166ck_pr_store_ptr_unsafe(value, next->value);167return head;168}169170CK_CC_INLINE static struct ck_hp_fifo_entry *171ck_hp_fifo_trydequeue_mpmc(ck_hp_record_t *record,172struct ck_hp_fifo *fifo,173void *value)174{175struct ck_hp_fifo_entry *head, *tail, *next;176177head = ck_pr_load_ptr(&fifo->head);178ck_pr_fence_load();179tail = ck_pr_load_ptr(&fifo->tail);180ck_hp_set_fence(record, 0, head);181if (head != ck_pr_load_ptr(&fifo->head))182return NULL;183184next = ck_pr_load_ptr(&head->next);185ck_hp_set_fence(record, 1, next);186if (head != ck_pr_load_ptr(&fifo->head))187return NULL;188189if (head == tail) {190if (next == NULL)191return NULL;192193ck_pr_cas_ptr(&fifo->tail, tail, next);194return NULL;195} else if (ck_pr_cas_ptr(&fifo->head, head, next) == false)196return NULL;197198ck_pr_store_ptr_unsafe(value, next->value);199return head;200}201202#define CK_HP_FIFO_ISEMPTY(f) ((f)->head->next == NULL)203#define CK_HP_FIFO_FIRST(f) ((f)->head->next)204#define CK_HP_FIFO_NEXT(m) ((m)->next)205#define CK_HP_FIFO_FOREACH(fifo, entry) \206for ((entry) = CK_HP_FIFO_FIRST(fifo); \207(entry) != NULL; \208(entry) = CK_HP_FIFO_NEXT(entry))209#define CK_HP_FIFO_FOREACH_SAFE(fifo, entry, T) \210for ((entry) = CK_HP_FIFO_FIRST(fifo); \211(entry) != NULL && ((T) = (entry)->next, 1); \212(entry) = (T))213214#endif /* CK_HP_FIFO_H */215216217