Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 46 additions & 11 deletions cilksan/cilksan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,33 +169,68 @@ class CilkSanImpl_t {
hyper_table::bucket *b = reducer_views->find(key);
if (b) {
assert(key == b->key);
return b->value.view;
return b->data.view;
}
return nullptr;
}

// Create a new reducer view.
void *create_reducer_view(hyper_table *__restrict__ reducer_views,
uintptr_t key, size_t size, void *identity_ptr,
void *reduce_ptr) {
__cilk_identity_fn identity = (__cilk_identity_fn)identity_ptr;
__cilk_reduce_fn reduce = (__cilk_reduce_fn)reduce_ptr;
void *create_reducer_view_0(hyper_table *__restrict__ reducer_views,
__reducer_base *key) {
// Create a new view and initialize it with the identity function.
size_t size = key->size();
void *new_view = malloc(size);
DBG_TRACE(REDUCER, "create_reducer_view_0(%p): created view %p -> %p\n",
(void *)reducer_views, (void *)key, new_view);
mark_alloc(new_view, size);
__reducer_base *base = key->identity(new_view);
// Insert the new view into the local hypertable.
hyper_table::bucket new_bucket = {
.key = (uintptr_t)key,
.data = {.view = new_view, .extra = base}};
[[maybe_unused]] bool success = reducer_views->insert(new_bucket);
assert(success && "create_reducer_view failed to insert new reducer.");

// Return the new view.
return new_view;
}

void *create_reducer_view_1(hyper_table *__restrict__ reducer_views,
uintptr_t key,
const __reducer_callbacks &callbacks) {
// Create a new view and initialize it with the identity function.
void *new_view = malloc(callbacks.size);
DBG_TRACE(REDUCER, "create_reducer_view_1(%p): created view %p -> %p\n",
(void *)reducer_views, (void *)key, new_view);
mark_alloc(new_view, callbacks.size);
callbacks.identity(new_view);
// Insert the new view into the local hypertable.
hyper_table::bucket new_bucket = {
.key = (uintptr_t)key,
.data = {.view = new_view, .extra = &callbacks.reduce}};
[[maybe_unused]] bool success = reducer_views->insert(new_bucket);
assert(success && "create_reducer_view failed to insert new reducer.");

// Return the new view.
return new_view;
}

void *create_reducer_view_2(hyper_table *__restrict__ reducer_views,
uintptr_t key, size_t size, void (*identity)(void *),
void (*reduce)(void *, void *)) {
// Allocate and initialize a new view. Make sure the shadow memory is clear
// for that allocation.
void *new_view = malloc(size);
DBG_TRACE(REDUCER, "create_reducer_view(%p): created view %p -> %p\n",
DBG_TRACE(REDUCER, "create_reducer_view_2(%p): created view %p -> %p\n",
(void *)reducer_views, (void *)key, new_view);
mark_alloc(new_view, size);
identity(new_view);

// Insert the view into the table of reducer_views.
hyper_table::bucket new_bucket = {
.key = (uintptr_t)key,
.value = {.view = new_view, .reduce_fn = reduce}};
bool success = reducer_views->insert(new_bucket);
.key = (uintptr_t)key, .data = {.view = new_view, .extra = reduce}};
[[maybe_unused]] bool success = reducer_views->insert(new_bucket);
assert(success && "create_reducer_view failed to insert new reducer.");
(void)success;

// Return the new view.
return new_view;
Expand Down
18 changes: 10 additions & 8 deletions cilksan/hyperobject_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@
#ifndef _HYPEROBJECT_BASE
#define _HYPEROBJECT_BASE

#include <cilk/cilk_api.h>
#include <cstdlib>
#include <cilk/reducer>
#include <variant>

// Reducer data.
//
// NOTE: Since the size and identity_fn are only used when a worker
// looks up a reducer after a steal, we don't need to store these in
// the reducer_base structure as long as the reducer_lookup function
// the reducer_data structure as long as the reducer_lookup function
// gets them as parameters.
//
// TODO: For small reducer views of size less than sizeof(void *),
// consider storing the view directly within the reducer_base
// consider storing the view directly within the reducer_data.
// structure.
// - Problem: A reducer_base structure may move around in the hash
// - Problem: A reducer_data structure may move around in the hash
// table as other reducers are inserted. As a result, a pointer to
// a view may be invalidated by other hyper_lookup operations.
// - Problem: Need a way to keep track of whether the view in a
// reducer_base is storing a pointer to the view or the view itself.
struct reducer_base {
// reducer_data is storing a pointer to the view or the view itself.
struct reducer_data {
void *view = nullptr;
__cilk_reduce_fn reduce_fn = nullptr;
std::variant<__reducer_base *, const std::function<void(void *, void *)> *,
void (*)(void *, void *)>
extra;
};

#endif /* _HYPEROBJECT_BASE */
10 changes: 8 additions & 2 deletions cilksan/hypertable.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ class hyper_table {
struct bucket {
uintptr_t key = KEY_EMPTY; /* EMPTY, DELETED, or a user-provided pointer. */
index_t hash = 0; /* hash of the key when inserted into the table. */
reducer_base value;
reducer_data data;

static void reduce(bucket *left, bucket *right);

bool is_empty() const { return key == KEY_EMPTY; }
bool is_tombstone() const { return key == KEY_DELETED; }
bool is_valid() const { return key != KEY_EMPTY && key != KEY_DELETED; }

void make_tombstone() { key = KEY_DELETED; }
};
Expand Down Expand Up @@ -370,7 +376,7 @@ class hyper_table {
// Found the key? Overwrite that bucket.
// TODO: Reconsider what to do in this case.
if (b.key == curr_key) {
buckets[i].value = b.value;
buckets[i].data = b.data;
return true;
}

Expand Down
Loading
Loading