ck_rhs: Use inlined functions instead of gruesome macros.

ck_pring
Olivier Houchard 12 years ago
parent 20b98dc271
commit 8f1ea8043b

@ -130,52 +130,117 @@ struct ck_rhs_map {
ck_rhs_probe_cb_t *probe_func; ck_rhs_probe_cb_t *probe_func;
}; };
#define CK_RHS_ENTRY(map, offset) (map->read_mostly ? map->entries.no_entries.entries[offset] : map->entries.descs[offset].entry) static CK_CC_INLINE void *
#define CK_RHS_ENTRY_ADDR(map, offset) (map->read_mostly ? &map->entries.no_entries.entries[offset] : &map->entries.descs[offset].entry) ck_rhs_entry(struct ck_rhs_map *map, long offset)
#define CK_RHS_DESC(map, offset) (CK_CC_UNLIKELY(map->read_mostly) ? (struct ck_rhs_entry_desc *)(void *)&map->entries.no_entries.descs[offset] : &map->entries.descs[offset]) {
#define CK_RHS_WANTED_INC(map, offset) do { \
if (CK_CC_UNLIKELY(map->read_mostly)) \ if (map->read_mostly)
map->entries.no_entries.descs[offset].wanted++; \ return (map->entries.no_entries.entries[offset]);
else \ else
map->entries.descs[offset].wanted++; \ return (map->entries.descs[offset].entry);
} while (0) }
#define CK_RHS_WANTED(map, offset) (CK_CC_UNLIKELY(map->read_mostly )? map->entries.no_entries.descs[offset].wanted : map->entries.descs[offset].wanted)
#define CK_RHS_SET_WANTED(map, offset, value) do { \ static CK_CC_INLINE void **
if (CK_CC_UNLIKELY(map->read_mostly)) \ ck_rhs_entry_addr(struct ck_rhs_map *map, long offset)
map->entries.no_entries.descs[offset].wanted = value; \ {
else \
map->entries.descs[offset].probes = value; \ if (map->read_mostly)
} while (0) return (&map->entries.no_entries.entries[offset]);
else
#define CK_RHS_WANTED_DEC(map, offset) do { \ return (&map->entries.descs[offset].entry);
if (CK_CC_UNLIKELY(map->read_mostly)) \ }
map->entries.no_entries.descs[offset].wanted--; \
else \ static CK_CC_INLINE struct ck_rhs_entry_desc *
map->entries.descs[offset].wanted--; \ ck_rhs_desc(struct ck_rhs_map *map, long offset)
} while (0) {
#define CK_RHS_PROBES(map, offset) (CK_CC_UNLIKELY(map->read_mostly) ? map->entries.no_entries.descs[offset].probes : map->entries.descs[offset].probes) if (CK_CC_UNLIKELY(map->read_mostly))
#define CK_RHS_SET_PROBES(map, offset, value) do { \ return ((struct ck_rhs_entry_desc *)(void *)&map->entries.no_entries.descs[offset]);
if (CK_CC_UNLIKELY(map->read_mostly)) \ else
map->entries.no_entries.descs[offset].probes = value; \ return (&map->entries.descs[offset]);
else \ }
map->entries.descs[offset].probes = value; \
} while (0) static CK_CC_INLINE void
#define CK_RHS_PROBE_BOUND(map, offset) (CK_CC_UNLIKELY(map->read_mostly) ? map->entries.no_entries.descs[offset].probe_bound : map->entries.descs[offset].probe_bound) ck_rhs_wanted_inc(struct ck_rhs_map *map, long offset)
#define CK_RHS_PROBE_BOUND_ADDR(map, offset) (CK_CC_UNLIKELY(map->read_mostly) ? (&map->entries.no_entries.descs[offset].probe_bound) : (&map->entries.descs[offset].probe_bound)) {
#define CK_RHS_IN_RH(map, offset) (CK_CC_UNLIKELY(map->read_mostly) ? map->entries.no_entries.descs[offset].in_rh : map->entries.descs[offset].in_rh)
#define CK_RHS_SET_RH(map, offset) do { \ if (CK_CC_UNLIKELY(map->read_mostly))
if (CK_CC_UNLIKELY(map->read_mostly)) \ map->entries.no_entries.descs[offset].wanted++;
map->entries.no_entries.descs[offset].in_rh = true; \ else
else \ map->entries.descs[offset].wanted++;
map->entries.descs[offset].in_rh = true; \ }
} while (0)
#define CK_RHS_UNSET_RH(map, offset) do { \ static CK_CC_INLINE unsigned int
if (CK_CC_UNLIKELY(map->read_mostly)) \ ck_rhs_probes(struct ck_rhs_map *map, long offset)
map->entries.no_entries.descs[offset].in_rh = false; \ {
else \
map->entries.descs[offset].in_rh = false; \ if (CK_CC_UNLIKELY(map->read_mostly))
} while (0) return (map->entries.no_entries.descs[offset].probes);
else
return (map->entries.descs[offset].probes);
}
static CK_CC_INLINE void
ck_rhs_set_probes(struct ck_rhs_map *map, long offset, unsigned int value)
{
if (CK_CC_UNLIKELY(map->read_mostly))
map->entries.no_entries.descs[offset].probes = value;
else
map->entries.descs[offset].probes = value;
}
static CK_CC_INLINE CK_RHS_WORD
ck_rhs_probe_bound(struct ck_rhs_map *map, long offset)
{
if (CK_CC_UNLIKELY(map->read_mostly))
return (map->entries.no_entries.descs[offset].probe_bound);
else
return (map->entries.descs[offset].probe_bound);
}
static CK_CC_INLINE CK_RHS_WORD *
ck_rhs_probe_bound_addr(struct ck_rhs_map *map, long offset)
{
if (CK_CC_UNLIKELY(map->read_mostly))
return (&map->entries.no_entries.descs[offset].probe_bound);
else
return (&map->entries.descs[offset].probe_bound);
}
static CK_CC_INLINE bool
ck_rhs_in_rh(struct ck_rhs_map *map, long offset)
{
if (CK_CC_UNLIKELY(map->read_mostly))
return (map->entries.no_entries.descs[offset].in_rh);
else
return (map->entries.descs[offset].in_rh);
}
static CK_CC_INLINE void
ck_rhs_set_rh(struct ck_rhs_map *map, long offset)
{
if (CK_CC_UNLIKELY(map->read_mostly))
map->entries.no_entries.descs[offset].in_rh = true;
else
map->entries.descs[offset].in_rh = true;
}
static CK_CC_INLINE void
ck_rhs_unset_rh(struct ck_rhs_map *map, long offset)
{
if (CK_CC_UNLIKELY(map->read_mostly))
map->entries.no_entries.descs[offset].in_rh = false;
else
map->entries.descs[offset].in_rh = false;
}
#define CK_RHS_LOAD_FACTOR 50 #define CK_RHS_LOAD_FACTOR 50
@ -201,7 +266,7 @@ ck_rhs_next(struct ck_rhs *hs, struct ck_rhs_iterator *i, void **key)
return false; return false;
do { do {
value = CK_RHS_ENTRY(map, i->offset); value = ck_rhs_entry(map, i->offset);
if (value != CK_RHS_EMPTY) { if (value != CK_RHS_EMPTY) {
#ifdef CK_RHS_PP #ifdef CK_RHS_PP
if (hs->mode & CK_RHS_MODE_OBJECT) if (hs->mode & CK_RHS_MODE_OBJECT)
@ -419,7 +484,7 @@ restart:
for (k = 0; k < map->capacity; k++) { for (k = 0; k < map->capacity; k++) {
unsigned long h; unsigned long h;
prev_saved = previous = CK_RHS_ENTRY(map, k); prev_saved = previous = ck_rhs_entry(map, k);
if (previous == CK_RHS_EMPTY) if (previous == CK_RHS_EMPTY)
continue; continue;
@ -433,7 +498,7 @@ restart:
probes = 0; probes = 0;
for (;;) { for (;;) {
void **cursor = CK_RHS_ENTRY_ADDR(update, offset); void **cursor = ck_rhs_entry_addr(update, offset);
if (probes++ == update->probe_limit) { if (probes++ == update->probe_limit) {
/* /*
@ -447,10 +512,10 @@ restart:
if (CK_CC_LIKELY(*cursor == CK_RHS_EMPTY)) { if (CK_CC_LIKELY(*cursor == CK_RHS_EMPTY)) {
*cursor = prev_saved; *cursor = prev_saved;
update->n_entries++; update->n_entries++;
CK_RHS_SET_PROBES(update, offset, probes); ck_rhs_set_probes(update, offset, probes);
ck_rhs_map_bound_set(update, h, probes); ck_rhs_map_bound_set(update, h, probes);
break; break;
} else if (CK_RHS_PROBES(update, offset) < probes) { } else if (ck_rhs_probes(update, offset) < probes) {
void *tmp = prev_saved; void *tmp = prev_saved;
unsigned int old_probes; unsigned int old_probes;
prev_saved = previous = *cursor; prev_saved = previous = *cursor;
@ -461,12 +526,12 @@ restart:
*cursor = tmp; *cursor = tmp;
ck_rhs_map_bound_set(update, h, probes); ck_rhs_map_bound_set(update, h, probes);
h = hs->hf(previous, hs->seed); h = hs->hf(previous, hs->seed);
old_probes = CK_RHS_PROBES(update, offset); old_probes = ck_rhs_probes(update, offset);
CK_RHS_SET_PROBES(update, offset, probes); ck_rhs_set_probes(update, offset, probes);
probes = old_probes - 1; probes = old_probes - 1;
continue; continue;
} }
CK_RHS_WANTED_INC(update, offset); ck_rhs_wanted_inc(update, offset);
offset = ck_rhs_map_probe_next(update, offset, probes); offset = ck_rhs_map_probe_next(update, offset, probes);
} }
@ -752,8 +817,8 @@ ck_rhs_gc(struct ck_rhs *hs)
unsigned int max_probes = 0; unsigned int max_probes = 0;
for (i = 0; i < map->capacity; i++) { for (i = 0; i < map->capacity; i++) {
if (CK_RHS_PROBES(map, i) > max_probes) if (ck_rhs_probes(map, i) > max_probes)
max_probes = CK_RHS_PROBES(map, i); max_probes = ck_rhs_probes(map, i);
} }
map->probe_maximum = max_probes; map->probe_maximum = max_probes;
return true; return true;
@ -777,7 +842,7 @@ ck_rhs_add_wanted(struct ck_rhs *hs, long end_offset, long old_slot,
if (offset == old_slot) if (offset == old_slot)
found_slot = true; found_slot = true;
if (found_slot) { if (found_slot) {
desc = CK_RHS_DESC(map, offset); desc = ck_rhs_desc(map, offset);
if (desc->wanted < CK_RHS_MAX_WANTED) if (desc->wanted < CK_RHS_MAX_WANTED)
desc->wanted++; desc->wanted++;
} }
@ -790,7 +855,7 @@ static unsigned long
ck_rhs_remove_wanted(struct ck_rhs *hs, long offset, long limit) ck_rhs_remove_wanted(struct ck_rhs *hs, long offset, long limit)
{ {
struct ck_rhs_map *map = hs->map; struct ck_rhs_map *map = hs->map;
int probes = CK_RHS_PROBES(map, offset); int probes = ck_rhs_probes(map, offset);
bool do_remove = true; bool do_remove = true;
struct ck_rhs_entry_desc *desc; struct ck_rhs_entry_desc *desc;
@ -800,7 +865,7 @@ ck_rhs_remove_wanted(struct ck_rhs *hs, long offset, long limit)
if (offset == limit) if (offset == limit)
do_remove = false; do_remove = false;
if (do_remove) { if (do_remove) {
desc = CK_RHS_DESC(map, offset); desc = ck_rhs_desc(map, offset);
if (desc->wanted != CK_RHS_MAX_WANTED) if (desc->wanted != CK_RHS_MAX_WANTED)
desc->wanted--; desc->wanted--;
} }
@ -841,14 +906,14 @@ ck_rhs_put_robin_hood(struct ck_rhs *hs,
first = orig_slot; first = orig_slot;
n_probes = desc->probes; n_probes = desc->probes;
restart: restart:
key = CK_RHS_ENTRY(map, first); key = ck_rhs_entry(map, first);
insert = key; insert = key;
#ifdef CK_RHS_PP #ifdef CK_RHS_PP
if (hs->mode & CK_RHS_MODE_OBJECT) if (hs->mode & CK_RHS_MODE_OBJECT)
key = CK_RHS_VMA(key); key = CK_RHS_VMA(key);
#endif #endif
orig_slot = first; orig_slot = first;
CK_RHS_SET_RH(map, orig_slot); ck_rhs_set_rh(map, orig_slot);
slot = map->probe_func(hs, map, &n_probes, &first, h, key, &object, slot = map->probe_func(hs, map, &n_probes, &first, h, key, &object,
map->probe_limit, prevs_nb == CK_RHS_MAX_RH ? map->probe_limit, prevs_nb == CK_RHS_MAX_RH ?
@ -857,16 +922,15 @@ restart:
if (slot == -1 && first == -1) { if (slot == -1 && first == -1) {
if (ck_rhs_grow(hs, map->capacity << 1) == false) { if (ck_rhs_grow(hs, map->capacity << 1) == false) {
desc->in_rh = false; desc->in_rh = false;
for (unsigned int i = 0; i < prevs_nb; i++) { for (unsigned int i = 0; i < prevs_nb; i++)
CK_RHS_UNSET_RH(map, prevs[i]); ck_rhs_unset_rh(map, prevs[i]);
}
return -1; return -1;
} }
return 1; return 1;
} }
if (first != -1) { if (first != -1) {
desc = CK_RHS_DESC(map, first); desc = ck_rhs_desc(map, first);
int old_probes = desc->probes; int old_probes = desc->probes;
desc->probes = n_probes; desc->probes = n_probes;
@ -880,17 +944,17 @@ restart:
/* An empty slot was found. */ /* An empty slot was found. */
h = ck_rhs_get_first_offset(map, slot, n_probes); h = ck_rhs_get_first_offset(map, slot, n_probes);
ck_rhs_map_bound_set(map, h, n_probes); ck_rhs_map_bound_set(map, h, n_probes);
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);
ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]); ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);
ck_pr_fence_atomic_store(); ck_pr_fence_atomic_store();
CK_RHS_SET_PROBES(map, slot, n_probes); ck_rhs_set_probes(map, slot, n_probes);
desc->in_rh = 0; desc->in_rh = 0;
ck_rhs_add_wanted(hs, slot, orig_slot, h); ck_rhs_add_wanted(hs, slot, orig_slot, h);
} }
while (prevs_nb > 0) { while (prevs_nb > 0) {
prev = prevs[--prevs_nb]; prev = prevs[--prevs_nb];
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, orig_slot), ck_pr_store_ptr(ck_rhs_entry_addr(map, orig_slot),
CK_RHS_ENTRY(map, prev)); ck_rhs_entry(map, prev));
h = ck_rhs_get_first_offset(map, orig_slot, h = ck_rhs_get_first_offset(map, orig_slot,
desc->probes); desc->probes);
ck_rhs_add_wanted(hs, orig_slot, prev, h); ck_rhs_add_wanted(hs, orig_slot, prev, h);
@ -898,7 +962,7 @@ restart:
ck_pr_fence_atomic_store(); ck_pr_fence_atomic_store();
orig_slot = prev; orig_slot = prev;
desc->in_rh = false; desc->in_rh = false;
desc = CK_RHS_DESC(map, orig_slot); desc = ck_rhs_desc(map, orig_slot);
} }
return 0; return 0;
} }
@ -907,7 +971,7 @@ static void
ck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot) ck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot)
{ {
struct ck_rhs_map *map = hs->map; struct ck_rhs_map *map = hs->map;
struct ck_rhs_entry_desc *desc = CK_RHS_DESC(map, slot), *new_desc = NULL; struct ck_rhs_entry_desc *desc = ck_rhs_desc(map, slot), *new_desc = NULL;
unsigned long h; unsigned long h;
h = ck_rhs_remove_wanted(hs, slot, -1); h = ck_rhs_remove_wanted(hs, slot, -1);
@ -924,7 +988,7 @@ ck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot)
probe = wanted_probes; probe = wanted_probes;
offset = ck_rhs_map_probe_next(map, slot, probe); offset = ck_rhs_map_probe_next(map, slot, probe);
while (probe < map->probe_maximum) { while (probe < map->probe_maximum) {
new_desc = CK_RHS_DESC(map, offset); new_desc = ck_rhs_desc(map, offset);
if (new_desc->probes == probe + 1) if (new_desc->probes == probe + 1)
break; break;
probe++; probe++;
@ -942,12 +1006,12 @@ ck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot)
desc->probes = wanted_probes; desc->probes = wanted_probes;
h = ck_rhs_remove_wanted(hs, offset, slot); h = ck_rhs_remove_wanted(hs, offset, slot);
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), ck_pr_store_ptr(ck_rhs_entry_addr(map, slot),
CK_RHS_ENTRY(map, offset)); ck_rhs_entry(map, offset));
ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]); ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);
ck_pr_fence_atomic_store(); ck_pr_fence_atomic_store();
if (wanted_probes < CK_RHS_WORD_MAX) { if (wanted_probes < CK_RHS_WORD_MAX) {
struct ck_rhs_entry_desc *hdesc = CK_RHS_DESC(map, h); struct ck_rhs_entry_desc *hdesc = ck_rhs_desc(map, h);
if (hdesc->wanted == 1) if (hdesc->wanted == 1)
CK_RHS_STORE(&hdesc->probe_bound, CK_RHS_STORE(&hdesc->probe_bound,
wanted_probes); wanted_probes);
@ -979,9 +1043,9 @@ ck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot)
slot = offset; slot = offset;
desc = new_desc; desc = new_desc;
} }
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), CK_RHS_EMPTY); ck_pr_store_ptr(ck_rhs_entry_addr(map, slot), CK_RHS_EMPTY);
if ((desc->probes - 1) < CK_RHS_WORD_MAX) if ((desc->probes - 1) < CK_RHS_WORD_MAX)
CK_RHS_STORE(CK_RHS_PROBE_BOUND_ADDR(map, h), CK_RHS_STORE(ck_rhs_probe_bound_addr(map, h),
desc->probes - 1); desc->probes - 1);
desc->probes = 0; desc->probes = 0;
} }
@ -1011,9 +1075,9 @@ restart:
if (first != -1) { if (first != -1) {
int ret; int ret;
desc = CK_RHS_DESC(map, slot);
desc2 = CK_RHS_DESC(map, first); desc = ck_rhs_desc(map, slot);
desc2 = ck_rhs_desc(map, first);
desc->in_rh = true; desc->in_rh = true;
ret = ck_rhs_put_robin_hood(hs, first, desc2); ret = ck_rhs_put_robin_hood(hs, first, desc2);
desc->in_rh = false; desc->in_rh = false;
@ -1022,15 +1086,15 @@ restart:
else if (CK_CC_UNLIKELY(ret != 0)) else if (CK_CC_UNLIKELY(ret != 0))
return false; return false;
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, first), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);
ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]); ck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);
ck_pr_fence_atomic_store(); ck_pr_fence_atomic_store();
desc2->probes = n_probes; desc2->probes = n_probes;
ck_rhs_add_wanted(hs, first, -1, h); ck_rhs_add_wanted(hs, first, -1, h);
ck_rhs_do_backward_shift_delete(hs, slot); ck_rhs_do_backward_shift_delete(hs, slot);
} else { } else {
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);
CK_RHS_SET_PROBES(map, slot, n_probes); ck_rhs_set_probes(map, slot, n_probes);
} }
*previous = object; *previous = object;
return true; return true;
@ -1066,20 +1130,20 @@ restart:
if (first != -1) { if (first != -1) {
struct ck_rhs_entry_desc *desc = NULL, *desc2; struct ck_rhs_entry_desc *desc = NULL, *desc2;
if (slot != -1) { if (slot != -1) {
desc = CK_RHS_DESC(map, slot); desc = ck_rhs_desc(map, slot);
desc->in_rh = true; desc->in_rh = true;
} }
desc2 = CK_RHS_DESC(map, first); desc2 = ck_rhs_desc(map, first);
int ret = ck_rhs_put_robin_hood(hs, first, desc2); int ret = ck_rhs_put_robin_hood(hs, first, desc2);
if (slot != -1) if (slot != -1)
desc->in_rh = false; desc->in_rh = false;
if (CK_CC_LIKELY(ret == 1)) if (CK_CC_UNLIKELY(ret == 1))
goto restart; goto restart;
if (CK_CC_LIKELY(ret == -1)) if (CK_CC_UNLIKELY(ret == -1))
return false; return false;
/* If an earlier bucket was found, then store entry there. */ /* If an earlier bucket was found, then store entry there. */
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, first), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);
desc2->probes = n_probes; desc2->probes = n_probes;
/* /*
* If a duplicate key was found, then delete it after * If a duplicate key was found, then delete it after
@ -1100,8 +1164,8 @@ restart:
* If we are storing into same slot, then atomic store is sufficient * If we are storing into same slot, then atomic store is sufficient
* for replacement. * for replacement.
*/ */
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);
CK_RHS_SET_PROBES(map, slot, n_probes); ck_rhs_set_probes(map, slot, n_probes);
if (object == NULL) if (object == NULL)
ck_rhs_add_wanted(hs, slot, -1, h); ck_rhs_add_wanted(hs, slot, -1, h);
} }
@ -1148,20 +1212,20 @@ restart:
insert = ck_rhs_marshal(hs->mode, key, h); insert = ck_rhs_marshal(hs->mode, key, h);
if (first != -1) { if (first != -1) {
struct ck_rhs_entry_desc *desc = CK_RHS_DESC(map, first); struct ck_rhs_entry_desc *desc = ck_rhs_desc(map, first);
int ret = ck_rhs_put_robin_hood(hs, first, desc); int ret = ck_rhs_put_robin_hood(hs, first, desc);
if (CK_CC_UNLIKELY(ret == 1)) if (CK_CC_UNLIKELY(ret == 1))
return ck_rhs_put_internal(hs, h, key, behavior); return ck_rhs_put_internal(hs, h, key, behavior);
else if (CK_CC_UNLIKELY(ret == -1)) else if (CK_CC_UNLIKELY(ret == -1))
return false; return false;
/* Insert key into first bucket in probe sequence. */ /* Insert key into first bucket in probe sequence. */
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, first), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);
desc->probes = n_probes; desc->probes = n_probes;
ck_rhs_add_wanted(hs, first, -1, h); ck_rhs_add_wanted(hs, first, -1, h);
} else { } else {
/* An empty slot was found. */ /* An empty slot was found. */
ck_pr_store_ptr(CK_RHS_ENTRY_ADDR(map, slot), insert); ck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);
CK_RHS_SET_PROBES(map, slot, n_probes); ck_rhs_set_probes(map, slot, n_probes);
ck_rhs_add_wanted(hs, slot, -1, h); ck_rhs_add_wanted(hs, slot, -1, h);
} }

Loading…
Cancel
Save