void *thr_reader(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), (unsigned long) gettid()); set_affinity(); while (!test_go) { } for (;;) { pthread_rwlock_rdlock(&lock); assert(test_array.a == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); pthread_rwlock_unlock(&lock); URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), (unsigned long) gettid()); return ((void*)1); }
void *thr_reader(void *data) { unsigned long tidx = (unsigned long)data; printf_verbose("thread_begin %s, tid %lu\n", "reader", urcu_get_thread_id()); set_affinity(); while (!test_go) { } for (;;) { pthread_mutex_lock(&per_thread_lock[tidx].lock); assert(test_array.a == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); pthread_mutex_unlock(&per_thread_lock[tidx].lock); URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; } tot_nr_reads[tidx] = URCU_TLS(nr_reads); printf_verbose("thread_end %s, tid %lu\n", "reader", urcu_get_thread_id()); return ((void*)1); }
void *thr_writer(void *data) { unsigned long wtidx = (unsigned long)data; printf_verbose("thread_begin %s, tid %lu\n", "writer", urcu_get_thread_id()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { pthread_mutex_lock(&lock); test_array.a = 0; test_array.a = 8; if (caa_unlikely(wduration)) loop_sleep(wduration); pthread_mutex_unlock(&lock); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); } printf_verbose("thread_end %s, tid %lu\n", "writer", urcu_get_thread_id()); tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); }
void *thr_writer(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), (unsigned long) gettid()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { pthread_rwlock_wrlock(&lock); test_array.a = 0; test_array.a = 8; if (caa_unlikely(wduration)) loop_sleep(wduration); pthread_rwlock_unlock(&lock); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); } printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), (unsigned long) gettid()); *count = URCU_TLS(nr_writes); return ((void*)2); }
LTTNG_HIDDEN const char *log_add_time(void) { int ret; struct tm tm, *res; struct timespec tp; time_t now; ret = lttng_clock_gettime(CLOCK_REALTIME, &tp); if (ret < 0) { goto error; } now = (time_t) tp.tv_sec; res = localtime_r(&now, &tm); if (!res) { goto error; } /* Format time in the TLS variable. */ ret = snprintf(URCU_TLS(error_log_time).str, sizeof(URCU_TLS(error_log_time).str), "%02d:%02d:%02d.%09ld", tm.tm_hour, tm.tm_min, tm.tm_sec, tp.tv_nsec); if (ret < 0) { goto error; } return URCU_TLS(error_log_time).str; error: /* Return an empty string on error so logging is not affected. */ return ""; }
void *test_hash_rw_thr_reader(void *_count) { unsigned long long *count = _count; struct lfht_test_node *node; struct cds_lfht_iter iter; printf_verbose("thread_begin %s, tid %lu\n", "reader", urcu_get_thread_id()); URCU_TLS(rand_lookup) = urcu_get_thread_id() ^ time(NULL); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { rcu_read_lock(); cds_lfht_test_lookup(test_ht, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % lookup_pool_size) + lookup_pool_offset), sizeof(void *), &iter); node = cds_lfht_iter_get_test_node(&iter); if (node == NULL) { if (validate_lookup) { printf("[ERROR] Lookup cannot find initial node.\n"); exit(-1); } URCU_TLS(lookup_fail)++; } else { URCU_TLS(lookup_ok)++; } rcu_debug_yield_read(); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); URCU_TLS(nr_reads)++; if (caa_unlikely(!test_duration_read())) break; if (caa_unlikely((URCU_TLS(nr_reads) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } rcu_unregister_thread(); *count = URCU_TLS(nr_reads); printf_verbose("thread_end %s, tid %lu\n", "reader", urcu_get_thread_id()); printf_verbose("read tid : %lx, lookupfail %lu, lookupok %lu\n", urcu_get_thread_id(), URCU_TLS(lookup_fail), URCU_TLS(lookup_ok)); return ((void*)1); }
static void *thr_dequeuer(void *_count) { unsigned long long *count = _count; unsigned int counter = 0; printf_verbose("thread_begin %s, tid %lu\n", "dequeuer", urcu_get_thread_id()); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); assert(test_pop || test_pop_all); for (;;) { if (test_pop && test_pop_all) { /* both pop and pop all */ if (counter & 1) do_test_pop(test_sync); else do_test_pop_all(test_sync); counter++; } else { if (test_pop) do_test_pop(test_sync); else do_test_pop_all(test_sync); } if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) loop_sleep(rduration); } rcu_unregister_thread(); printf_verbose("dequeuer thread_end, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", urcu_get_thread_id(), URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); }
/* * Return 0 on success, -1 if should quit. * The lock is taken in both cases. * Signal-safe. */ int ust_lock(void) { sigset_t sig_all_blocked, orig_mask; int ret, oldstate; ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); if (ret) { ERR("pthread_setcancelstate: %s", strerror(ret)); } if (oldstate != PTHREAD_CANCEL_ENABLE) { ERR("pthread_setcancelstate: unexpected oldstate"); } sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } if (!URCU_TLS(ust_mutex_nest)++) pthread_mutex_lock(&ust_mutex); ret = pthread_sigmask(SIG_SETMASK, &orig_mask, NULL); if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } if (lttng_ust_comm_should_quit) { return -1; } else { return 0; } }
static void *thr_enqueuer(void *_count) { unsigned long long *count = _count; bool was_nonempty; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "enqueuer", (unsigned long) pthread_self(), (unsigned long) gettid()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct cds_wfs_node *node = malloc(sizeof(*node)); if (!node) goto fail; cds_wfs_node_init(node); was_nonempty = cds_wfs_push(&s, node); URCU_TLS(nr_successful_enqueues)++; if (!was_nonempty) URCU_TLS(nr_empty_dest_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } uatomic_inc(&test_enqueue_stopped); count[0] = URCU_TLS(nr_enqueues); count[1] = URCU_TLS(nr_successful_enqueues); count[2] = URCU_TLS(nr_empty_dest_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu, " "empty_dest_enqueues %llu\n", pthread_self(), (unsigned long) gettid(), URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues), URCU_TLS(nr_empty_dest_enqueues)); return ((void*)1); }
static void do_test_pop(enum test_sync sync) { struct cds_wfs_node *node; int state; if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_lock(&s); node = __cds_wfs_pop_with_state_blocking(&s, &state); if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_unlock(&s); if (node) { if (state & CDS_WFS_STATE_LAST) URCU_TLS(nr_pop_last)++; free(node); URCU_TLS(nr_successful_dequeues)++; } URCU_TLS(nr_dequeues)++; }
static void do_test_pop_all(enum test_sync sync) { struct cds_lfs_node *snode; struct cds_lfs_head *head; struct cds_lfs_node *n; head = __cds_lfs_pop_all(&s); cds_lfs_for_each_safe(head, snode, n) { struct test *node; node = caa_container_of(snode, struct test, list); if (sync == TEST_SYNC_RCU) call_rcu(&node->rcu, free_node_cb); else free(node); URCU_TLS(nr_successful_dequeues)++; URCU_TLS(nr_dequeues)++; } }
void *thr_writer(void *data) { unsigned long wtidx = (unsigned long)data; long tidx; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), (unsigned long) gettid()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { for (tidx = 0; tidx < nr_readers; tidx++) { pthread_mutex_lock(&per_thread_lock[tidx].lock); } test_array.a = 0; test_array.a = 8; if (caa_unlikely(wduration)) loop_sleep(wduration); for (tidx = (long)nr_readers - 1; tidx >= 0; tidx--) { pthread_mutex_unlock(&per_thread_lock[tidx].lock); } URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); } printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), (unsigned long) gettid()); tot_nr_writes[wtidx] = URCU_TLS(nr_writes); return ((void*)2); }
int test_hash_rw_populate_hash(void) { struct lfht_test_node *node; if (!init_populate) return 0; printf("Starting rw test\n"); URCU_TLS(rand_lookup) = urcu_get_thread_id() ^ time(NULL); if ((add_unique || add_replace) && init_populate * 10 > init_pool_size) { printf("WARNING: required to populate %lu nodes (-k), but random " "pool is quite small (%lu values) and we are in add_unique (-u) or add_replace (-s) mode. Try with a " "larger random pool (-p option). This may take a while...\n", init_populate, init_pool_size); } while (URCU_TLS(nr_add) < init_populate) { struct cds_lfht_node *ret_node = NULL; node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % init_pool_size) + init_pool_offset), sizeof(void *)); rcu_read_lock(); if (add_unique) { ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); } else { if (add_replace) ret_node = cds_lfht_add_replace(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); else cds_lfht_add(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), &node->node); } rcu_read_unlock(); if (add_unique && ret_node != &node->node) { free(node); URCU_TLS(nr_addexist)++; } else { if (add_replace && ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); URCU_TLS(nr_addexist)++; } else { URCU_TLS(nr_add)++; } } URCU_TLS(nr_writes)++; } return 0; }
static void do_test_pop_all(enum test_sync sync) { struct cds_wfs_head *head; struct cds_wfs_node *node, *n; if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_lock(&s); head = __cds_wfs_pop_all(&s); if (sync == TEST_SYNC_MUTEX) cds_wfs_pop_unlock(&s); /* Check if empty */ if (cds_wfs_first(head) == NULL) return; URCU_TLS(nr_pop_all)++; URCU_TLS(nr_pop_last)++; cds_wfs_for_each_blocking_safe(head, node, n) { free(node); URCU_TLS(nr_successful_dequeues)++; URCU_TLS(nr_dequeues)++; }
static void do_test_pop(enum test_sync sync) { struct cds_lfs_node *snode; if (sync == TEST_SYNC_RCU) rcu_read_lock(); snode = __cds_lfs_pop(&s); if (sync == TEST_SYNC_RCU) rcu_read_unlock(); if (snode) { struct test *node; node = caa_container_of(snode, struct test, list); if (sync == TEST_SYNC_RCU) call_rcu(&node->rcu, free_node_cb); else free(node); URCU_TLS(nr_successful_dequeues)++; } URCU_TLS(nr_dequeues)++; }
void *thr_dequeuer(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, tid %lu\n", "dequeuer", urcu_get_thread_id()); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct cds_lfq_node_rcu *qnode; rcu_read_lock(); qnode = cds_lfq_dequeue_rcu(&q); rcu_read_unlock(); if (qnode) { struct test *node; node = caa_container_of(qnode, struct test, list); call_rcu(&node->rcu, free_node_cb); URCU_TLS(nr_successful_dequeues)++; } URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) loop_sleep(rduration); } rcu_unregister_thread(); printf_verbose("dequeuer thread_end, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", urcu_get_thread_id(), URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); }
void *thr_enqueuer(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, tid %lu\n", "enqueuer", urcu_get_thread_id()); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct test *node = malloc(sizeof(*node)); if (!node) goto fail; cds_lfq_node_init_rcu(&node->list); rcu_read_lock(); cds_lfq_enqueue_rcu(&q, &node->list); rcu_read_unlock(); URCU_TLS(nr_successful_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: URCU_TLS(nr_enqueues)++; if (caa_unlikely(!test_duration_enqueue())) break; } rcu_unregister_thread(); count[0] = URCU_TLS(nr_enqueues); count[1] = URCU_TLS(nr_successful_enqueues); printf_verbose("enqueuer thread_end, tid %lu, " "enqueues %llu successful_enqueues %llu\n", urcu_get_thread_id(), URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); return ((void*)1); }
/* * Signal-safe. */ void ust_unlock(void) { sigset_t sig_all_blocked, orig_mask; int ret, oldstate; sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } if (!--URCU_TLS(ust_mutex_nest)) pthread_mutex_unlock(&ust_mutex); ret = pthread_sigmask(SIG_SETMASK, &orig_mask, NULL); if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); if (ret) { ERR("pthread_setcancelstate: %s", strerror(ret)); } if (oldstate != PTHREAD_CANCEL_DISABLE) { ERR("pthread_setcancelstate: unexpected oldstate"); } }
void *thr_dequeuer(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "dequeuer", (unsigned long) pthread_self(), (unsigned long) gettid()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct cds_wfq_node *node = cds_wfq_dequeue_blocking(&q); if (node) { free(node); URCU_TLS(nr_successful_dequeues)++; } URCU_TLS(nr_dequeues)++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) loop_sleep(rduration); } printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", pthread_self(), (unsigned long) gettid(), URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); return ((void*)2); }
void *test_hash_rw_thr_writer(void *_count) { struct lfht_test_node *node; struct cds_lfht_node *ret_node; struct cds_lfht_iter iter; struct wr_count *count = _count; int ret; printf_verbose("thread_begin %s, tid %lu\n", "writer", urcu_get_thread_id()); URCU_TLS(rand_lookup) = urcu_get_thread_id() ^ time(NULL); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { if ((addremove == AR_ADD || add_only) || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *)); rcu_read_lock(); if (add_unique) { ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); } else { if (add_replace) ret_node = cds_lfht_add_replace(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); else cds_lfht_add(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), &node->node); } rcu_read_unlock(); if (add_unique && ret_node != &node->node) { free(node); URCU_TLS(nr_addexist)++; } else { if (add_replace && ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); URCU_TLS(nr_addexist)++; } else { URCU_TLS(nr_add)++; } } } else { /* May delete */ rcu_read_lock(); cds_lfht_test_lookup(test_ht, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *), &iter); ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); rcu_read_unlock(); if (ret == 0) { node = cds_lfht_iter_get_test_node(&iter); call_rcu(&node->head, free_node_cb); URCU_TLS(nr_del)++; } else URCU_TLS(nr_delnoent)++; } #if 0 //if (URCU_TLS(nr_writes) % 100000 == 0) { if (URCU_TLS(nr_writes) % 1000 == 0) { rcu_read_lock(); if (rand_r(&URCU_TLS(rand_lookup)) & 1) { ht_resize(test_ht, 1); } else { ht_resize(test_ht, -1); } rcu_read_unlock(); } #endif //0 URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } rcu_unregister_thread(); printf_verbose("thread_end %s, tid %lu\n", "writer", urcu_get_thread_id()); printf_verbose("info tid %lu: nr_add %lu, nr_addexist %lu, nr_del %lu, " "nr_delnoent %lu\n", urcu_get_thread_id(), URCU_TLS(nr_add), URCU_TLS(nr_addexist), URCU_TLS(nr_del), URCU_TLS(nr_delnoent)); count->update_ops = URCU_TLS(nr_writes); count->add = URCU_TLS(nr_add); count->add_exist = URCU_TLS(nr_addexist); count->remove = URCU_TLS(nr_del); return ((void*)2); }