node_t* new_node(skey_t key, sval_t val, int initializing) { volatile node_t* node; #if GC == 1 if (unlikely(initializing)) /* for initialization AND the coupling algorithm */ { node = (volatile node_t*) ssalloc(sizeof(node_t)); } else { node = (volatile node_t*) ssmem_alloc(alloc, sizeof(node_t)); } #else node = (volatile node_t*) ssalloc(sizeof(node_t)); #endif if (node == NULL) { perror("malloc @ new_node"); exit(1); } node->key = key; node->val = val; node->left = node->right = NULL; #if defined(__tile__) /* on tilera you may have store reordering causing the pointer to a new node to become visible, before the contents of the node are visible */ MEM_BARRIER; #endif /* __tile__ */ return (node_t*) node; }
node_t* new_node(skey_t key, sval_t val, node_t *next, int initializing) { volatile node_t *node; #if GC == 1 if (unlikely(initializing)) { node = (volatile node_t *) ssalloc(sizeof(node_t)); } else { node = (volatile node_t *) ssmem_alloc(alloc, sizeof(node_t)); } #else node = (volatile node_t *) ssalloc(sizeof(node_t)); #endif if (node == NULL) { perror("malloc @ new_node"); exit(1); } node->key = key; node->val = val; node->next = next; return (node_t*) node; }
node_t* new_node(skey_t key, sval_t val, node_t* l, node_t* r, int initializing) { node_t* node; #if GC == 1 if (likely(!initializing)) /* for initialization AND the coupling algorithm */ { node = (node_t*) ssmem_alloc(alloc, sizeof(node_t)); } else { node = (node_t*) ssalloc(sizeof(node_t)); } #else node = (node_t*) ssalloc(sizeof(node_t)); #endif if (node == NULL) { perror("malloc @ new_node"); exit(1); } node->key = key; node->val = val; node->left = l; node->right = r; node->lock.to_uint64 = 0; return (node_t*) node; }
static chm_node_t* chm_node_new(skey_t key, sval_t val, chm_node_t* next) { volatile chm_node_t* node; #if GC == 1 node = (volatile chm_node_t*) ssmem_alloc(alloc, sizeof(chm_node_t)); #else node = (volatile chm_node_t*) ssalloc(sizeof(chm_node_t)); #endif if (node == NULL) { perror("malloc @ new_node"); exit(1); } node->key = key; node->val = val; node->next = next; #if defined(__tile__) /* on tilera you may have store reordering causing the pointer to a new node to become visible, before the contents of the node are visible */ MEM_BARRIER; #endif /* __tile__ */ return (chm_node_t*) node; }
static inline array_ll_t* array_ll_new(size_t size) { array_ll_t* all; all = ssmem_alloc(alloc, sizeof(array_ll_t) + (array_ll_fixed_size * sizeof(kv_t))); assert(all != NULL); all->size = size; all->kvs = (kv_t*) ((uintptr_t) all + sizeof(array_ll_t)); return all; }
operation_t* alloc_op() { volatile operation_t * new_op; #if GC == 1 new_op = (volatile operation_t*) ssmem_alloc(alloc, sizeof(operation_t)); #else new_op = (volatile operation_t*) ssalloc(sizeof(operation_t)); #endif if (new_op==NULL) { perror("malloc in bst create node"); exit(1); } return (operation_t*) new_op; }
queue_node_t* queue_new_node(skey_t key, sval_t val, queue_node_t* next) { #if GC == 1 queue_node_t* node = ssmem_alloc(alloc, sizeof(*node)); #else queue_node_t* node = ssalloc(sizeof(*node)); #endif node->key = key; node->val = val; node->next = next; #ifdef __tile__ MEM_BARRIER; #endif return node; }
node_t* new_node_no_init() { node_t* node; #if GC == 1 node = (node_t*) ssmem_alloc(alloc, sizeof(node_t)); #else node = (node_t*) ssalloc(sizeof(node_t)); #endif if (unlikely(node == NULL)) { perror("malloc @ new_node"); exit(1); } node->val = 0; node->lock.to_uint64 = 0; return (node_t*) node; }
node_t* create_node(skey_t k, sval_t value, int initializing) { volatile node_t* new_node; #if GC == 1 if (unlikely(initializing)) { new_node = (volatile node_t*) ssalloc_aligned(CACHE_LINE_SIZE, sizeof(node_t)); } else { new_node = (volatile node_t*) ssmem_alloc(alloc, sizeof(node_t)); } #else new_node = (volatile node_t*) ssalloc(sizeof(node_t)); #endif if (new_node == NULL) { perror("malloc in bst create node"); exit(1); } new_node->left = NULL; new_node->right = NULL; new_node->key = k; new_node->value = value; asm volatile("" ::: "memory"); return (node_t*) new_node; }
void* test(void* thread) { size_t num_retry_cas1 = 0, num_retry_cas2 = 0, num_retry_cas3 = 0 , num_retry_cas4 = 0, num_retry_cas5 = 0; thread_data_t* td = (thread_data_t*) thread; uint8_t ID = td->id; phys_id = the_cores[ID % (NUMBER_OF_SOCKETS * CORES_PER_SOCKET)]; set_cpu(phys_id); ssmem_allocator_t* alloc = (ssmem_allocator_t*) memalign(CACHE_LINE_SIZE, sizeof(ssmem_allocator_t)); assert(alloc != NULL); ssmem_alloc_init(alloc, SSMEM_DEFAULT_MEM_SIZE, ID); ssmem_gc_thread_init(alloc, ID); PF_INIT(3, SSPFD_NUM_ENTRIES, ID); #if defined(COMPUTE_LATENCY) volatile ticks my_putting_succ = 0; volatile ticks my_putting_fail = 0; volatile ticks my_getting_succ = 0; volatile ticks my_getting_fail = 0; volatile ticks my_removing_succ = 0; volatile ticks my_removing_fail = 0; #endif uint64_t my_putting_count = 0; uint64_t my_getting_count = 0; uint64_t my_removing_count = 0; uint64_t my_putting_count_succ = 0; uint64_t my_getting_count_succ = 0; uint64_t my_removing_count_succ = 0; #if defined(COMPUTE_LATENCY) && PFD_TYPE == 0 volatile ticks start_acq, end_acq; volatile ticks correction = getticks_correction_calc(); #endif seeds = seed_rand(); MEM_BARRIER; barrier_cross(&barrier); barrier_cross(&barrier_global); size_t obj_size_bytes = obj_size * sizeof(size_t); volatile size_t* dat = (size_t*) malloc(obj_size_bytes); assert(dat != NULL); size_t* obj = NULL; while (stop == 0) { size_t rand = (my_random(&(seeds[0]), &(seeds[1]), &(seeds[2]))); size_t k = (rand & 1) + 2; rand &= 1023; /* search baby! */ int i; for (i = 0; i < KEY_BUCKT; i++) { volatile uintptr_t v = val[i]; if (snap->map[i] == MAP_VALID && key[i] == k) { if (val[i] == v) { if (GET_VAL(v) != k) { printf("[%02d] :get: key != val for %zu\n", ID, k); } break; } } } if (rand > 513) { my_putting_count++; if (obj != NULL) { ssmem_free(alloc, (void*) obj); } obj = ssmem_alloc(alloc, 8); *obj = k; int empty_index = -2; clht_snapshot_t s; retry: s.snapshot = snap->snapshot; int i; for (i = 0; i < KEY_BUCKT; i++) { volatile uintptr_t v = val[i]; if (snap->map[i] == MAP_VALID && key[i] == k) { if (val[i] == v) { if (empty_index > 0) { snap->map[empty_index] = MAP_INVLD; } goto end; } } } clht_snapshot_all_t s1; if (empty_index < 0) { empty_index = snap_get_empty_index(s.snapshot); if (empty_index < 0) { num_retry_cas1++; goto end; } s1 = snap_set_map(s.snapshot, empty_index, MAP_INSRT); if (CAS_U64(&snap->snapshot, s.snapshot, s1) != s.snapshot) { empty_index = -2; num_retry_cas2++; goto retry; } val[empty_index] = (uintptr_t) obj; key[empty_index] = k; } else { s1 = snap_set_map(s.snapshot, empty_index, MAP_INSRT); } clht_snapshot_all_t s2 = snap_set_map_and_inc_version(s1, empty_index, MAP_VALID); if (CAS_U64(&snap->snapshot, s1, s2) != s1) { num_retry_cas3++; /* key[empty_index] = 0; */ /* val[empty_index] = 0; */ goto retry; } obj = NULL; my_putting_count_succ++; end: ; } else { my_removing_count++; clht_snapshot_t s; retry_rem: s.snapshot = snap->snapshot; volatile uintptr_t v; int i, removed = 0; for (i = 0; i < KEY_BUCKT && !removed; i++) { if (key[i] == k && s.map[i] == MAP_VALID) { v = val[i]; clht_snapshot_all_t s1 = snap_set_map(s.snapshot, i, MAP_INVLD); if (CAS_U64(&snap->snapshot, s.snapshot, s1) == s.snapshot) { /* snap->map[i] = MAP_INVLD; */ removed = 1; } else { num_retry_cas4++; goto retry_rem; } } } if (removed) { ssmem_free(alloc, (void*) v); my_removing_count_succ++; } } } free((void*) dat); #if defined(DEBUG) if (put_num_restarts | put_num_failed_expand | put_num_failed_on_new) { /* printf("put_num_restarts = %3u / put_num_failed_expand = %3u / put_num_failed_on_new = %3u \n", */ /* put_num_restarts, put_num_failed_expand, put_num_failed_on_new); */ } #endif if (ID < 2) { printf("#retry-stats-thread-%d: #cas1: %-8zu / #cas2: %-8zu /" "#cas3: %-8zu / #cas4: %-8zu / #cas5: %-8zu\n", ID, num_retry_cas1, num_retry_cas2, num_retry_cas3, num_retry_cas4, num_retry_cas5); } /* printf("gets: %-10llu / succ: %llu\n", num_get, num_get_succ); */ /* printf("rems: %-10llu / succ: %llu\n", num_rem, num_rem_succ); */ barrier_cross(&barrier); #if defined(COMPUTE_LATENCY) putting_succ[ID] += my_putting_succ; putting_fail[ID] += my_putting_fail; getting_succ[ID] += my_getting_succ; getting_fail[ID] += my_getting_fail; removing_succ[ID] += my_removing_succ; removing_fail[ID] += my_removing_fail; #endif putting_count[ID] += my_putting_count; getting_count[ID] += my_getting_count; removing_count[ID]+= my_removing_count; putting_count_succ[ID] += my_putting_count_succ; getting_count_succ[ID] += my_getting_count_succ; removing_count_succ[ID]+= my_removing_count_succ; #if (PFD_TYPE == 1) && defined(COMPUTE_LATENCY) if (ID == 0) { printf("get ----------------------------------------------------\n"); SSPFDPN(0, SSPFD_NUM_ENTRIES, print_vals_num); printf("put ----------------------------------------------------\n"); SSPFDPN(1, SSPFD_NUM_ENTRIES, print_vals_num); printf("rem ----------------------------------------------------\n"); SSPFDPN(2, SSPFD_NUM_ENTRIES, print_vals_num); } #endif /* SSPFDTERM(); */ pthread_exit(NULL); }