/* * initialize thread metadata for GC */ void clht_gc_thread_init(clht_t* h, int id) { clht_alloc = (ssmem_allocator_t*) malloc(sizeof(ssmem_allocator_t)); assert(clht_alloc != NULL); ssmem_alloc_init_fs_size(clht_alloc, SSMEM_DEFAULT_MEM_SIZE, SSMEM_GC_FREE_SET_SIZE, id); ht_ts_t* ts = (ht_ts_t*) memalign(CACHE_LINE_SIZE, sizeof(ht_ts_t)); assert(ts != NULL); ts->version = h->ht->version; ts->id = id; do { ts->next = h->version_list; } while (CAS_U64((volatile size_t*) &h->version_list, (size_t) ts->next, (size_t) ts) != (size_t) ts->next); clht_ts_thread = ts; }
/* * explicitely subscribe to the list of threads in order to used timestamps for GC */ void ssmem_gc_thread_init(ssmem_allocator_t* a, int id) { a->ts = (ssmem_ts_t*) ssmem_ts_local; if (a->ts == NULL) { a->ts = (ssmem_ts_t*) memalign(CACHE_LINE_SIZE, sizeof(ssmem_ts_t)); assert (a->ts != NULL); ssmem_ts_local = a->ts; a->ts->id = id; a->ts->version = 0; do { a->ts->next = ssmem_ts_list; } while (CAS_U64((volatile uint64_t*) &ssmem_ts_list, (uint64_t) a->ts->next, (uint64_t) a->ts) != (uint64_t) a->ts->next); __attribute__ ((unused)) uint32_t null = FAI_U32(&ssmem_ts_list_len); } }
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); }