void *thr_reader(void *data) { unsigned long tidx = (unsigned long)data; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", pthread_self(), (unsigned long)gettid()); set_affinity(); while (!test_go) { } for (;;) { pthread_mutex_lock(&lock); assert(test_array.a == 8); if (unlikely(rduration)) loop_sleep(rduration); pthread_mutex_unlock(&lock); nr_reads++; if (unlikely(!test_duration_read())) break; } tot_nr_reads[tidx] = nr_reads; printf_verbose("thread_end %s, thread id : %lx, tid %lu\n", "reader", 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); }
static void init_hid_manager(void) { CFMutableDictionaryRef dict; IOReturn ret; if (hid_manager) return; hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { if (hid_manager) CFRelease(hid_manager); printf_verbose("no HID Manager - maybe this is a pre-Leopard (10.5) system?\n"); return; } dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (!dict) return; IOHIDManagerSetDeviceMatching(hid_manager, dict); CFRelease(dict); IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); if (ret != kIOReturnSuccess) { IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(hid_manager); printf_verbose("Error opening HID Manager"); } }
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_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); }
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); }
static int lttng_live_open_trace_read(const char *path) { int ret = 0; struct lttng_live_ctx *ctx; ctx = g_new0(struct lttng_live_ctx, 1); ctx->session = g_new0(struct lttng_live_session, 1); /* We need a pointer to the context from the packet_seek function. */ ctx->session->ctx = ctx; /* HT to store the CTF traces. */ ctx->session->ctf_traces = g_hash_table_new(g_direct_hash, g_direct_equal); ctx->port = -1; ctx->session_ids = g_array_new(FALSE, TRUE, sizeof(uint64_t)); ret = parse_url(path, ctx); if (ret < 0) { goto end_free; } #if 0 ret = setup_sighandler(); if (ret < 0) { goto end_free; } #endif ret = lttng_live_connect_viewer(ctx); if (ret < 0) { goto end_free; } printf_verbose("LTTng-live connected to relayd\n"); ret = lttng_live_establish_connection(ctx); if (ret < 0) { goto end_free; } printf_verbose("Listing sessions\n"); ret = lttng_live_list_sessions(ctx, path); if (ret < 0) { goto end_free; } if (ctx->session_ids->len > 0) { ret = lttng_live_read(ctx); } end_free: g_hash_table_destroy(ctx->session->ctf_traces); g_free(ctx->session); g_free(ctx->session->streams); g_free(ctx); if (lttng_live_should_quit()) { ret = 0; } return ret; }
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); }
void *thr_dequeuer(void *_count) { unsigned long long *count = _count; int ret; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "dequeuer", pthread_self(), (unsigned long)gettid()); set_affinity(); ret = rcu_defer_register_thread(); if (ret) { printf("Error in rcu_defer_register_thread\n"); exit(-1); } rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct cds_lfq_node_rcu *qnode; struct test *node; rcu_read_lock(); qnode = cds_lfq_dequeue_rcu(&q); node = caa_container_of(qnode, struct test, list); rcu_read_unlock(); if (node) { call_rcu(&node->rcu, free_node_cb); nr_successful_dequeues++; } nr_dequeues++; if (caa_unlikely(!test_duration_dequeue())) break; if (caa_unlikely(rduration)) loop_sleep(rduration); } rcu_unregister_thread(); rcu_defer_unregister_thread(); printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " "dequeues %llu, successful_dequeues %llu\n", pthread_self(), (unsigned long)gettid(), nr_dequeues, nr_successful_dequeues); count[0] = nr_dequeues; count[1] = nr_successful_dequeues; return ((void*)2); }
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); }
usb_dev_handle * open_usb_device(int vid, int pid) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *h; char buf[128]; int r; usb_init(); usb_find_busses(); usb_find_devices(); //printf_verbose("\nSearching for USB device:\n"); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { //printf_verbose("bus \"%s\", device \"%s\" vid=%04X, pid=%04X\n", // bus->dirname, dev->filename, // dev->descriptor.idVendor, // dev->descriptor.idProduct //); if (dev->descriptor.idVendor != vid) continue; if (dev->descriptor.idProduct != pid) continue; h = usb_open(dev); if (!h) { printf_verbose("Found device but unable to open"); continue; } #ifdef LIBUSB_HAS_GET_DRIVER_NP r = usb_get_driver_np(h, 0, buf, sizeof(buf)); if (r >= 0) { r = usb_detach_kernel_driver_np(h, 0); if (r < 0) { usb_close(h); printf_verbose("Device is in use by \"%s\" driver", buf); continue; } } #endif // Mac OS-X - removing this call to usb_claim_interface() might allow // this to work, even though it is a clear misuse of the libusb API. // normally Apple's IOKit should be used on Mac OS-X r = usb_claim_interface(h, 0); if (r < 0) { usb_close(h); printf_verbose("Unable to claim interface, check USB permissions"); continue; } return h; } } return NULL; }
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); }
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); }
int read_inotify(int inotify_fd, struct channel_trace_fd *fd_pairs, struct inotify_watch_array *iwatch_array) { char buf[sizeof(struct inotify_event) + PATH_MAX]; char path_channel[PATH_MAX]; char path_trace[PATH_MAX]; ssize_t len; struct inotify_event *ievent; size_t offset; unsigned int i; int ret; int old_num; offset = 0; len = read(inotify_fd, buf, sizeof(struct inotify_event) + PATH_MAX); if(len < 0) { if(errno == EAGAIN) return 0; /* another thread got the data before us */ printf("Error in read from inotify FD %s.\n", strerror(len)); return -1; } while(offset < len) { ievent = (struct inotify_event *)&(buf[offset]); for(i=0; i<iwatch_array->num; i++) { if(iwatch_array->elem[i].wd == ievent->wd && ievent->mask == IN_CREATE) { printf_verbose( "inotify wd %u event mask : %u for %s%s\n", ievent->wd, ievent->mask, iwatch_array->elem[i].path_channel, ievent->name); old_num = fd_pairs->num_pairs; strcpy(path_channel, iwatch_array->elem[i].path_channel); strcat(path_channel, ievent->name); strcpy(path_trace, iwatch_array->elem[i].path_trace); strcat(path_trace, ievent->name); if(ret = open_buffer_file(ievent->name, path_channel, path_trace, fd_pairs)) { printf("Error opening buffer file\n"); return -1; } if(ret = map_channels(fd_pairs, old_num, fd_pairs->num_pairs)) { printf("Error mapping channel\n"); return -1; } } } offset += sizeof(*ievent) + ievent->len; } }
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); }
void *thr_enqueuer(void *_count) { unsigned long long *count = _count; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "enqueuer", pthread_self(), (unsigned long)gettid()); set_affinity(); while (!test_go) { } cmm_smp_mb(); for (;;) { struct cds_wfq_node *node = malloc(sizeof(*node)); if (!node) goto fail; cds_wfq_node_init(node); cds_wfq_enqueue(&q, node); nr_successful_enqueues++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); fail: nr_enqueues++; if (caa_unlikely(!test_duration_enqueue())) break; } count[0] = nr_enqueues; count[1] = nr_successful_enqueues; printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " "enqueues %llu successful_enqueues %llu\n", pthread_self(), (unsigned long)gettid(), nr_enqueues, nr_successful_enqueues); return ((void*)1); }
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); }
int main(int argc, char **argv) { int err; pthread_t *tid_enqueuer, *tid_dequeuer; void *tret; unsigned long long *count_enqueuer, *count_dequeuer; unsigned long long tot_enqueues = 0, tot_dequeues = 0; unsigned long long tot_successful_enqueues = 0, tot_successful_dequeues = 0; unsigned long long end_dequeues = 0; int i, a; if (argc < 4) { show_usage(argc, argv); return -1; } err = sscanf(argv[1], "%u", &nr_dequeuers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[2], "%u", &nr_enqueuers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[3], "%lu", &duration); if (err != 1) { show_usage(argc, argv); return -1; } for (i = 4; i < argc; i++) { if (argv[i][0] != '-') continue; switch (argv[i][1]) { case 'a': if (argc < i + 2) { show_usage(argc, argv); return -1; } a = atoi(argv[++i]); cpu_affinities[next_aff++] = a; use_affinity = 1; printf_verbose("Adding CPU %d affinity\n", a); break; case 'c': if (argc < i + 2) { show_usage(argc, argv); return -1; } rduration = atol(argv[++i]); break; case 'd': if (argc < i + 2) { show_usage(argc, argv); return -1; } wdelay = atol(argv[++i]); break; case 'v': verbose_mode = 1; break; } } printf_verbose("running test for %lu seconds, %u enqueuers, " "%u dequeuers.\n", duration, nr_enqueuers, nr_dequeuers); printf_verbose("Writer delay : %lu loops.\n", rduration); printf_verbose("Reader duration : %lu loops.\n", wdelay); printf_verbose("thread %-6s, tid %lu\n", "main", urcu_get_thread_id()); tid_enqueuer = calloc(nr_enqueuers, sizeof(*tid_enqueuer)); tid_dequeuer = calloc(nr_dequeuers, sizeof(*tid_dequeuer)); count_enqueuer = calloc(nr_enqueuers, 2 * sizeof(*count_enqueuer)); count_dequeuer = calloc(nr_dequeuers, 2 * sizeof(*count_dequeuer)); cds_lfq_init_rcu(&q, call_rcu); err = create_all_cpu_call_rcu_data(0); if (err) { printf("Per-CPU call_rcu() worker threads unavailable. Using default global worker thread.\n"); } next_aff = 0; for (i = 0; i < nr_enqueuers; i++) { err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer, &count_enqueuer[2 * i]); if (err != 0) exit(1); } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, &count_dequeuer[2 * i]); if (err != 0) exit(1); } cmm_smp_mb(); test_go = 1; for (i = 0; i < duration; i++) { sleep(1); if (verbose_mode) { fwrite(".", sizeof(char), 1, stdout); fflush(stdout); } } test_stop = 1; for (i = 0; i < nr_enqueuers; i++) { err = pthread_join(tid_enqueuer[i], &tret); if (err != 0) exit(1); tot_enqueues += count_enqueuer[2 * i]; tot_successful_enqueues += count_enqueuer[2 * i + 1]; } for (i = 0; i < nr_dequeuers; i++) { err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); tot_dequeues += count_dequeuer[2 * i]; tot_successful_dequeues += count_dequeuer[2 * i + 1]; } test_end(&q, &end_dequeues); err = cds_lfq_destroy_rcu(&q); assert(!err); printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " "successful dequeues %llu\n", tot_successful_enqueues, tot_successful_dequeues); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " "successful enqueues %12llu successful dequeues %12llu " "end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, tot_successful_dequeues, end_dequeues, tot_enqueues + tot_dequeues); if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " "succ. dequeues + end dequeues %llu.\n", tot_successful_enqueues, tot_successful_dequeues + end_dequeues); free_all_cpu_call_rcu_data(); free(count_enqueuer); free(count_dequeuer); free(tid_enqueuer); free(tid_dequeuer); return 0; }
int main(int argc, char **argv) { int err; pthread_t *tid_enqueuer, *tid_dequeuer; void *tret; unsigned long long *count_enqueuer, *count_dequeuer; unsigned long long tot_enqueues = 0, tot_dequeues = 0; unsigned long long tot_successful_enqueues = 0, tot_successful_dequeues = 0; unsigned long long end_dequeues = 0; int i, a; if (argc < 4) { show_usage(argc, argv); return -1; } err = sscanf(argv[1], "%u", &nr_dequeuers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[2], "%u", &nr_enqueuers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[3], "%lu", &duration); if (err != 1) { show_usage(argc, argv); return -1; } for (i = 4; i < argc; i++) { if (argv[i][0] != '-') continue; switch (argv[i][1]) { case 'a': if (argc < i + 2) { show_usage(argc, argv); return -1; } a = atoi(argv[++i]); cpu_affinities[next_aff++] = a; use_affinity = 1; printf_verbose("Adding CPU %d affinity\n", a); break; case 'c': if (argc < i + 2) { show_usage(argc, argv); return -1; } rduration = atol(argv[++i]); break; case 'd': if (argc < i + 2) { show_usage(argc, argv); return -1; } wdelay = atol(argv[++i]); break; case 'v': verbose_mode = 1; break; } } printf_verbose("running test for %lu seconds, %u enqueuers, " "%u dequeuers.\n", duration, nr_enqueuers, nr_dequeuers); printf_verbose("Writer delay : %lu loops.\n", rduration); printf_verbose("Reader duration : %lu loops.\n", wdelay); printf_verbose("thread %-6s, thread id : %lx, tid %lu\n", "main", pthread_self(), (unsigned long)gettid()); tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); count_enqueuer = malloc(2 * sizeof(*count_enqueuer) * nr_enqueuers); count_dequeuer = malloc(2 * sizeof(*count_dequeuer) * nr_dequeuers); cds_wfq_init(&q); next_aff = 0; for (i = 0; i < nr_enqueuers; i++) { err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer, &count_enqueuer[2 * i]); if (err != 0) exit(1); } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, &count_dequeuer[2 * i]); if (err != 0) exit(1); } cmm_smp_mb(); test_go = 1; for (i = 0; i < duration; i++) { sleep(1); if (verbose_mode) write (1, ".", 1); } test_stop = 1; for (i = 0; i < nr_enqueuers; i++) { err = pthread_join(tid_enqueuer[i], &tret); if (err != 0) exit(1); tot_enqueues += count_enqueuer[2 * i]; tot_successful_enqueues += count_enqueuer[2 * i + 1]; } for (i = 0; i < nr_dequeuers; i++) { err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); tot_dequeues += count_dequeuer[2 * i]; tot_successful_dequeues += count_dequeuer[2 * i + 1]; } test_end(&q, &end_dequeues); printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " "successful dequeues %llu\n", tot_successful_enqueues, tot_successful_dequeues); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " "successful enqueues %12llu successful dequeues %12llu " "end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, tot_successful_dequeues, end_dequeues, tot_enqueues + tot_dequeues); if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " "succ. dequeues + end dequeues %llu.\n", tot_successful_enqueues, tot_successful_dequeues + end_dequeues); free(count_enqueuer); free(count_dequeuer); free(tid_enqueuer); free(tid_dequeuer); return 0; }
int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path) { struct lttng_viewer_cmd cmd; struct lttng_viewer_list_sessions list; struct lttng_viewer_session lsession; int i, ret, sessions_count, print_list = 0; ssize_t ret_len; uint64_t session_id; GPtrArray *session_list = NULL; if (lttng_live_should_quit()) { ret = -1; goto end; } if (strlen(ctx->session_name) == 0) { print_list = 1; session_list = g_ptr_array_new(); } cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); cmd.data_size = htobe64((uint64_t) 0); cmd.cmd_version = htobe32(0); ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd)); if (ret_len < 0) { perror("[error] Error sending cmd"); goto error; } assert(ret_len == sizeof(cmd)); ret_len = lttng_live_recv(ctx->control_sock, &list, sizeof(list)); if (ret_len == 0) { fprintf(stderr, "[error] Remote side has closed connection\n"); goto error; } if (ret_len < 0) { perror("[error] Error receiving session list"); goto error; } assert(ret_len == sizeof(list)); sessions_count = be32toh(list.sessions_count); for (i = 0; i < sessions_count; i++) { ret_len = lttng_live_recv(ctx->control_sock, &lsession, sizeof(lsession)); if (ret_len == 0) { fprintf(stderr, "[error] Remote side has closed connection\n"); goto error; } if (ret_len < 0) { perror("[error] Error receiving session"); goto error; } assert(ret_len == sizeof(lsession)); lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; session_id = be64toh(lsession.id); if (print_list) { update_session_list(session_list, lsession.hostname, lsession.session_name, be32toh(lsession.streams), be32toh(lsession.clients), be32toh(lsession.live_timer)); } else { if ((strncmp(lsession.session_name, ctx->session_name, MAXNAMLEN) == 0) && (strncmp(lsession.hostname, ctx->traced_hostname, MAXNAMLEN) == 0)) { printf_verbose("Reading from session %" PRIu64 "\n", session_id); g_array_append_val(ctx->session_ids, session_id); } } } if (print_list) { print_session_list(session_list, path); free_session_list(session_list); } ret = 0; end: return ret; error: fprintf(stderr, "[error] Unable to list sessions\n"); return -1; }
int lttng_live_establish_connection(struct lttng_live_ctx *ctx) { struct lttng_viewer_cmd cmd; struct lttng_viewer_connect connect; int ret; ssize_t ret_len; if (lttng_live_should_quit()) { ret = -1; goto end; } cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT); cmd.data_size = htobe64((uint64_t) sizeof(connect)); cmd.cmd_version = htobe32(0); connect.viewer_session_id = -1ULL; /* will be set on recv */ connect.major = htobe32(LTTNG_LIVE_MAJOR); connect.minor = htobe32(LTTNG_LIVE_MINOR); connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND); ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd)); if (ret_len < 0) { perror("[error] Error sending cmd"); goto error; } assert(ret_len == sizeof(cmd)); ret_len = lttng_live_send(ctx->control_sock, &connect, sizeof(connect)); if (ret_len < 0) { perror("[error] Error sending version"); goto error; } assert(ret_len == sizeof(connect)); ret_len = lttng_live_recv(ctx->control_sock, &connect, sizeof(connect)); if (ret_len == 0) { fprintf(stderr, "[error] Remote side has closed connection\n"); goto error; } if (ret_len < 0) { perror("[error] Error receiving version"); goto error; } assert(ret_len == sizeof(connect)); printf_verbose("Received viewer session ID : %" PRIu64 "\n", be64toh(connect.viewer_session_id)); printf_verbose("Relayd version : %u.%u\n", be32toh(connect.major), be32toh(connect.minor)); if (LTTNG_LIVE_MAJOR != be32toh(connect.major)) { fprintf(stderr, "[error] Incompatible lttng-relayd protocol\n"); goto error; } /* Use the smallest protocol version implemented. */ if (LTTNG_LIVE_MINOR > be32toh(connect.minor)) { ctx->minor = be32toh(connect.minor); } else { ctx->minor = LTTNG_LIVE_MINOR; } ctx->major = LTTNG_LIVE_MAJOR; ret = 0; end: return ret; error: fprintf(stderr, "[error] Unable to establish connection\n"); return -1; }
int open_buffer_file(char *filename, char *path_channel, char *path_trace, struct channel_trace_fd *fd_pairs) { int open_ret = 0; int ret = 0; struct stat stat_buf; if(strncmp(filename, "flight-", sizeof("flight-")-1) != 0) { if(dump_flight_only) { printf_verbose("Skipping normal channel %s\n", path_channel); return 0; } } else { if(dump_normal_only) { printf_verbose("Skipping flight channel %s\n", path_channel); return 0; } } printf_verbose("Opening file.\n"); fd_pairs->pair = realloc(fd_pairs->pair, ++fd_pairs->num_pairs * sizeof(struct fd_pair)); /* Open the channel in read mode */ fd_pairs->pair[fd_pairs->num_pairs-1].channel = open(path_channel, O_RDONLY | O_NONBLOCK); if(fd_pairs->pair[fd_pairs->num_pairs-1].channel == -1) { perror(path_channel); fd_pairs->num_pairs--; return 0; /* continue */ } /* Open the trace in write mode, only append if append_mode */ ret = stat(path_trace, &stat_buf); if(ret == 0) { if(append_mode) { printf_verbose("Appending to file %s as requested\n", path_trace); fd_pairs->pair[fd_pairs->num_pairs-1].trace = open(path_trace, O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO); if(fd_pairs->pair[fd_pairs->num_pairs-1].trace == -1) { perror(path_trace); open_ret = -1; close(fd_pairs->pair[fd_pairs->num_pairs-1].channel); fd_pairs->num_pairs--; goto end; } ret = lseek(fd_pairs->pair[fd_pairs->num_pairs-1].trace, 0, SEEK_END); if (ret < 0) { perror(path_trace); open_ret = -1; close(fd_pairs->pair[fd_pairs->num_pairs-1].channel); close(fd_pairs->pair[fd_pairs->num_pairs-1].trace); fd_pairs->num_pairs--; goto end; } } else { printf("File %s exists, cannot open. Try append mode.\n", path_trace); open_ret = -1; close(fd_pairs->pair[fd_pairs->num_pairs-1].channel); fd_pairs->num_pairs--; goto end; } } else { if(errno == ENOENT) { fd_pairs->pair[fd_pairs->num_pairs-1].trace = open(path_trace, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO); if(fd_pairs->pair[fd_pairs->num_pairs-1].trace == -1) { perror(path_trace); open_ret = -1; close(fd_pairs->pair[fd_pairs->num_pairs-1].channel); fd_pairs->num_pairs--; goto end; } } } end: return open_ret; }
int open_channel_trace_pairs(char *subchannel_name, char *subtrace_name, struct channel_trace_fd *fd_pairs, int *inotify_fd, struct inotify_watch_array *iwatch_array) { DIR *channel_dir = opendir(subchannel_name); struct dirent *entry; struct stat stat_buf; int ret; char path_channel[PATH_MAX]; int path_channel_len; char *path_channel_ptr; char path_trace[PATH_MAX]; int path_trace_len; char *path_trace_ptr; int open_ret = 0; if(channel_dir == NULL) { perror(subchannel_name); open_ret = ENOENT; goto end; } printf_verbose("Creating trace subdirectory %s\n", subtrace_name); ret = mkdir(subtrace_name, S_IRWXU|S_IRWXG|S_IRWXO); if(ret == -1) { if(errno != EEXIST) { perror(subtrace_name); open_ret = -1; goto end; } } strncpy(path_channel, subchannel_name, PATH_MAX-1); path_channel_len = strlen(path_channel); path_channel[path_channel_len] = '/'; path_channel_len++; path_channel_ptr = path_channel + path_channel_len; strncpy(path_trace, subtrace_name, PATH_MAX-1); path_trace_len = strlen(path_trace); path_trace[path_trace_len] = '/'; path_trace_len++; path_trace_ptr = path_trace + path_trace_len; #ifdef HAS_INOTIFY iwatch_array->elem = realloc(iwatch_array->elem, ++iwatch_array->num * sizeof(struct inotify_watch)); printf_verbose("Adding inotify for channel %s\n", path_channel); iwatch_array->elem[iwatch_array->num-1].wd = inotify_add_watch(*inotify_fd, path_channel, IN_CREATE); strcpy(iwatch_array->elem[iwatch_array->num-1].path_channel, path_channel); strcpy(iwatch_array->elem[iwatch_array->num-1].path_trace, path_trace); printf_verbose("Added inotify for channel %s, wd %u\n", iwatch_array->elem[iwatch_array->num-1].path_channel, iwatch_array->elem[iwatch_array->num-1].wd); #endif while((entry = readdir(channel_dir)) != NULL) { if(entry->d_name[0] == '.') continue; strncpy(path_channel_ptr, entry->d_name, PATH_MAX - path_channel_len); strncpy(path_trace_ptr, entry->d_name, PATH_MAX - path_trace_len); ret = stat(path_channel, &stat_buf); if(ret == -1) { perror(path_channel); continue; } printf_verbose("Channel file : %s\n", path_channel); if(S_ISDIR(stat_buf.st_mode)) { printf_verbose("Entering channel subdirectory...\n"); ret = open_channel_trace_pairs(path_channel, path_trace, fd_pairs, inotify_fd, iwatch_array); if(ret < 0) continue; } else if(S_ISREG(stat_buf.st_mode)) { open_ret = open_buffer_file(entry->d_name, path_channel, path_trace, fd_pairs); if(open_ret) goto end; } } end: closedir(channel_dir); return open_ret; }
int main(int argc, char *argv[]) { char c; int ret = 1; const struct sysdef *s; const struct targetdef *t; uint8_t tn, listmsrs = 0, listknown = 0, input = 0; uint32_t addr = 0; const char *streamfn = NULL, *difffn = NULL; struct msr msrval = MSR2(-1, -1); while ((c = getopt(argc, argv, "hqvrklc:m:t:a:i:s:d:")) != -1) switch (c) { case 'h': syntax(argv); return 0; case 'q': quiet = 1; break; case 'v': ++verbose; break; case 'r': reserved = 1; break; case 'k': listknown = 1; break; case 'l': listmsrs = 1; break; case 'c': cpu = atoi(optarg); break; case 'm': for (s = allsystems; !SYSTEM_ISEOT(*s); s++) if (!strcmp(s->name, optarg)) { sys = s; break; } break; case 't': for (t = alltargets; !TARGET_ISEOT(*t); t++) if (!strcmp(t->name, optarg)) { add_target(t); break; } break; case 'i': input = 1; addr = msraddrbyname(optarg); optarg = strchr(optarg, '='); if (NULL == optarg) { fprintf(stderr, "missing value in -i argument!\n"); break; } if (!str2msr(++optarg, &msrval, NULL)) fprintf(stderr, "invalid value in -i argument!\n"); break; case 's': streamfn = optarg; break; case 'd': difffn = optarg; break; default: break; } printf_quiet("msrtool %s\n", VERSION); pacc = pci_alloc(); if (NULL == pacc) { fprintf(stderr, "Could not initialize PCI library! pci_alloc() failed.\n"); return 1; } pci_init(pacc); pci_scan_bus(pacc); if (!sys && !input && !listknown) for (sys = allsystems; !SYSTEM_ISEOT(*sys); sys++) { printf_verbose("Probing for system %s: %s\n", sys->name, sys->prettyname); if (!sys->probe(sys)) continue; printf_quiet("Detected system %s: %s\n", sys->name, sys->prettyname); break; } if (targets) for (tn = 0; tn < targets_found; tn++) printf_quiet("Forced target %s: %s\n", targets[tn]->name, targets[tn]->prettyname); else for (t = alltargets; !TARGET_ISEOT(*t); t++) { printf_verbose("Probing for target %s: %s\n", t->name, t->prettyname); if (!t->probe(t)) continue; printf_quiet("Detected target %s: %s\n", t->name, t->prettyname); add_target(t); } printf_quiet("\n"); fflush(stdout); if (listknown) { printf("Known systems:\n"); for (s = allsystems; s->name; s++) printf("%s: %s\n", s->name, s->prettyname); printf("\nKnown targets:\n"); for (t = alltargets; t->name; t++) { if (listmsrs && alltargets != t) printf("\n"); printf("%s: %s\n", t->name, t->prettyname); if (listmsrs) dumpmsrdefs(t); } printf("\n"); return 0; } if (!targets_found || !targets) { fprintf(stderr, "Unable to detect a known target; can not decode any MSRs! (Use -t to force)\n"); fprintf(stderr, "Please send a report or patch to [email protected]. Thanks for your help!\n"); fprintf(stderr, "\n"); return 1; } if (input) { decodemsr(cpu, addr, msrval); return 0; } if (listmsrs) { if (streamfn) return do_stream(streamfn, 1); for (tn = 0; tn < targets_found; tn++) { if (tn) printf("\n"); dumpmsrdefs(targets[tn]); } printf("\n"); return 0; } if (streamfn) return do_stream(streamfn, 0); if (difffn) { ret = do_diff(difffn); goto done; } if (optind == argc) { syntax(argv); printf("\nNo mode or address(es) specified!\n"); goto done; } if (!found_system()) return 1; if (!sys->open(cpu, SYS_RDONLY)) return 1; for (; optind < argc; optind++) { addr = msraddrbyname(argv[optind]); if (!sys->rdmsr(cpu, addr, &msrval)) break; decodemsr(cpu, addr, msrval); } ret = 0; done: sys->close(cpu); return ret; }
int read_channels(unsigned long thread_num, struct channel_trace_fd *fd_pairs, int inotify_fd, struct inotify_watch_array *iwatch_array) { struct pollfd *pollfd = NULL; int num_pollfd; int i,j; int num_rdy, num_hup; int high_prio; int ret = 0; int inotify_fds; unsigned int old_num; #ifdef HAS_INOTIFY inotify_fds = 1; #else inotify_fds = 0; #endif pthread_rwlock_rdlock(&fd_pairs_lock); /* Start polling the FD. Keep one fd for inotify */ pollfd = malloc((inotify_fds + fd_pairs->num_pairs) * sizeof(struct pollfd)); #ifdef HAS_INOTIFY pollfd[0].fd = inotify_fd; pollfd[0].events = POLLIN|POLLPRI; #endif for(i=0;i<fd_pairs->num_pairs;i++) { pollfd[inotify_fds+i].fd = fd_pairs->pair[i].channel; pollfd[inotify_fds+i].events = POLLIN|POLLPRI; } num_pollfd = inotify_fds + fd_pairs->num_pairs; pthread_rwlock_unlock(&fd_pairs_lock); while(1) { high_prio = 0; num_hup = 0; #ifdef DEBUG printf("Press a key for next poll...\n"); char buf[1]; read(STDIN_FILENO, &buf, 1); printf("Next poll (polling %d fd) :\n", num_pollfd); #endif //DEBUG /* Have we received a signal ? */ if(quit_program) break; num_rdy = poll(pollfd, num_pollfd, -1); if(num_rdy == -1) { perror("Poll error"); goto free_fd; } printf_verbose("Data received\n"); #ifdef HAS_INOTIFY switch(pollfd[0].revents) { case POLLERR: printf_verbose( "Error returned in polling inotify fd %d.\n", pollfd[0].fd); break; case POLLHUP: printf_verbose( "Polling inotify fd %d tells it has hung up.\n", pollfd[0].fd); break; case POLLNVAL: printf_verbose( "Polling inotify fd %d tells fd is not open.\n", pollfd[0].fd); break; case POLLPRI: case POLLIN: printf_verbose( "Polling inotify fd %d : data ready.\n", pollfd[0].fd); pthread_rwlock_wrlock(&fd_pairs_lock); read_inotify(inotify_fd, fd_pairs, iwatch_array); pthread_rwlock_unlock(&fd_pairs_lock); break; } #endif for(i=inotify_fds;i<num_pollfd;i++) { switch(pollfd[i].revents) { case POLLERR: printf_verbose( "Error returned in polling fd %d.\n", pollfd[i].fd); num_hup++; break; case POLLHUP: printf_verbose( "Polling fd %d tells it has hung up.\n", pollfd[i].fd); num_hup++; break; case POLLNVAL: printf_verbose( "Polling fd %d tells fd is not open.\n", pollfd[i].fd); num_hup++; break; case POLLPRI: pthread_rwlock_rdlock(&fd_pairs_lock); if(pthread_mutex_trylock(&fd_pairs->pair[i-inotify_fds].mutex) == 0) { printf_verbose( "Urgent read on fd %d\n", pollfd[i].fd); /* Take care of high priority channels first. */ high_prio = 1; /* it's ok to have an unavailable sub-buffer */ ret = read_subbuffer(&fd_pairs->pair[i-inotify_fds]); if(ret == EAGAIN) ret = 0; ret = pthread_mutex_unlock(&fd_pairs->pair[i-inotify_fds].mutex); if(ret) printf("Error in mutex unlock : %s\n", strerror(ret)); } pthread_rwlock_unlock(&fd_pairs_lock); break; } } /* If every buffer FD has hung up, we end the read loop here */ if(num_hup == num_pollfd - inotify_fds) break; if(!high_prio) { for(i=inotify_fds;i<num_pollfd;i++) { switch(pollfd[i].revents) { case POLLIN: pthread_rwlock_rdlock(&fd_pairs_lock); if(pthread_mutex_trylock(&fd_pairs->pair[i-inotify_fds].mutex) == 0) { /* Take care of low priority channels. */ printf_verbose( "Normal read on fd %d\n", pollfd[i].fd); /* it's ok to have an unavailable subbuffer */ ret = read_subbuffer(&fd_pairs->pair[i-inotify_fds]); if(ret == EAGAIN) ret = 0; ret = pthread_mutex_unlock(&fd_pairs->pair[i-inotify_fds].mutex); if(ret) printf("Error in mutex unlock : %s\n", strerror(ret)); } pthread_rwlock_unlock(&fd_pairs_lock); break; } } } /* Update pollfd array if an entry was added to fd_pairs */ pthread_rwlock_rdlock(&fd_pairs_lock); if((inotify_fds + fd_pairs->num_pairs) != num_pollfd) { pollfd = realloc(pollfd, (inotify_fds + fd_pairs->num_pairs) * sizeof(struct pollfd)); for(i=num_pollfd-inotify_fds;i<fd_pairs->num_pairs;i++) { pollfd[inotify_fds+i].fd = fd_pairs->pair[i].channel; pollfd[inotify_fds+i].events = POLLIN|POLLPRI; } num_pollfd = fd_pairs->num_pairs + inotify_fds; } pthread_rwlock_unlock(&fd_pairs_lock); /* NB: If the fd_pairs structure is updated by another thread from this * point forward, the current thread will wait in the poll without * monitoring the new channel. However, this thread will add the * new channel on next poll (and this should not take too much time * on a loaded system). * * This event is quite unlikely and can only occur if a CPU is * hot-plugged while multple lttd threads are running. */ } free_fd: free(pollfd); end: return ret; }
int read_subbuffer(struct fd_pair *pair) { unsigned int consumed_old, len; int err; long ret; off_t offset; err = ioctl(pair->channel, RELAY_GET_SB, &consumed_old); printf_verbose("cookie : %u\n", consumed_old); if(err != 0) { ret = errno; perror("Reserving sub buffer failed (everything is normal, it is due to concurrency)"); goto get_error; } #if 0 err = TEMP_FAILURE_RETRY(write(pair->trace, pair->mmap + (consumed_old & ((pair->n_subbufs * pair->subbuf_size)-1)), pair->subbuf_size)); if(err < 0) { ret = errno; perror("Error in writing to file"); goto write_error; } #endif //0 err = ioctl(pair->channel, RELAY_GET_SB_SIZE, &len); if(err != 0) { ret = errno; perror("Getting sub-buffer len failed."); goto get_error; } offset = 0; while (len > 0) { printf_verbose("splice chan to pipe offset %lu\n", (unsigned long)offset); ret = splice(pair->channel, &offset, thread_pipe[1], NULL, len, SPLICE_F_MOVE | SPLICE_F_MORE); printf_verbose("splice chan to pipe ret %ld\n", ret); if (ret < 0) { perror("Error in relay splice"); goto write_error; } ret = splice(thread_pipe[0], NULL, pair->trace, NULL, ret, SPLICE_F_MOVE | SPLICE_F_MORE); printf_verbose("splice pipe to file %ld\n", ret); if (ret < 0) { perror("Error in file splice"); goto write_error; } len -= ret; } #if 0 err = fsync(pair->trace); if(err < 0) { ret = errno; perror("Error in writing to file"); goto write_error; } #endif //0 write_error: ret = 0; err = ioctl(pair->channel, RELAY_PUT_SB, &consumed_old); if(err != 0) { ret = errno; if(errno == EFAULT) { perror("Error in unreserving sub buffer\n"); } else if(errno == EIO) { /* Should never happen with newer LTTng versions */ perror("Reader has been pushed by the writer, last sub-buffer corrupted."); } goto get_error; } get_error: return ret; }
int main(int argc, char **argv) { int err; pthread_t *tid_reader, *tid_writer; void *tret; unsigned long long *count_reader, *count_writer; unsigned long long tot_reads = 0, tot_writes = 0; int i, a; if (argc < 4) { show_usage(argc, argv); return -1; } cmm_smp_mb(); err = sscanf(argv[1], "%u", &nr_readers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[2], "%u", &nr_writers); if (err != 1) { show_usage(argc, argv); return -1; } err = sscanf(argv[3], "%lu", &duration); if (err != 1) { show_usage(argc, argv); return -1; } for (i = 4; i < argc; i++) { if (argv[i][0] != '-') continue; switch (argv[i][1]) { #ifdef DEBUG_YIELD case 'r': yield_active |= YIELD_READ; break; case 'w': yield_active |= YIELD_WRITE; break; #endif case 'a': if (argc < i + 2) { show_usage(argc, argv); return -1; } a = atoi(argv[++i]); cpu_affinities[next_aff++] = a; use_affinity = 1; printf_verbose("Adding CPU %d affinity\n", a); break; case 'c': if (argc < i + 2) { show_usage(argc, argv); return -1; } rduration = atol(argv[++i]); break; case 'd': if (argc < i + 2) { show_usage(argc, argv); return -1; } wdelay = atol(argv[++i]); break; case 'e': if (argc < i + 2) { show_usage(argc, argv); return -1; } wduration = atol(argv[++i]); break; case 'v': verbose_mode = 1; break; } } printf_verbose("running test for %lu seconds, %u readers, %u writers.\n", duration, nr_readers, nr_writers); printf_verbose("Writer delay : %lu loops.\n", wdelay); printf_verbose("Reader duration : %lu loops.\n", rduration); printf_verbose("thread %-6s, thread id : %lx, tid %lu\n", "main", (unsigned long) pthread_self(), (unsigned long) gettid()); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); count_writer = malloc(sizeof(*count_writer) * nr_writers); next_aff = 0; for (i = 0; i < nr_readers; i++) { err = pthread_create(&tid_reader[i], NULL, thr_reader, &count_reader[i]); if (err != 0) exit(1); } for (i = 0; i < nr_writers; i++) { err = pthread_create(&tid_writer[i], NULL, thr_writer, &count_writer[i]); if (err != 0) exit(1); } cmm_smp_mb(); test_go = 1; sleep(duration); test_stop = 1; for (i = 0; i < nr_readers; i++) { err = pthread_join(tid_reader[i], &tret); if (err != 0) exit(1); tot_reads += count_reader[i]; } for (i = 0; i < nr_writers; i++) { err = pthread_join(tid_writer[i], &tret); if (err != 0) exit(1); tot_writes += count_writer[i]; } printf_verbose("total number of reads : %llu, writes %llu\n", tot_reads, tot_writes); printf("SUMMARY %-25s testdur %4lu nr_readers %3u rdur %6lu wdur %6lu " "nr_writers %3u " "wdelay %6lu nr_reads %12llu nr_writes %12llu nr_ops %12llu\n", argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); free(tid_reader); free(tid_writer); free(count_reader); free(count_writer); return 0; }
int main(int argc, char **argv) { int ret, partial_error = 0, open_success = 0; struct bt_format *fmt_write; struct bt_trace_descriptor *td_write; struct bt_context *ctx; int i; opt_input_paths = g_ptr_array_new(); ret = parse_options(argc, argv); if (ret < 0) { fprintf(stderr, "Error parsing options.\n\n"); usage(stderr); g_ptr_array_free(opt_input_paths, TRUE); exit(EXIT_FAILURE); } else if (ret > 0) { g_ptr_array_free(opt_input_paths, TRUE); exit(EXIT_SUCCESS); } printf_verbose("Verbose mode active.\n"); printf_debug("Debug mode active.\n"); if (opt_input_format) strlower(opt_input_format); if (opt_output_format) strlower(opt_output_format); printf_verbose("Converting from directory(ies):\n"); for (i = 0; i < opt_input_paths->len; i++) { const char *ipath = g_ptr_array_index(opt_input_paths, i); printf_verbose(" %s\n", ipath); } printf_verbose("Converting from format: %s\n", opt_input_format ? : "ctf <default>"); printf_verbose("Converting to target: %s\n", opt_output_path ? : "<stdout>"); printf_verbose("Converting to format: %s\n", opt_output_format ? : "text <default>"); if (!opt_input_format) { opt_input_format = strdup("ctf"); if (!opt_input_format) { partial_error = 1; goto end; } } if (!opt_output_format) { opt_output_format = strdup("text"); if (!opt_output_format) { partial_error = 1; goto end; } } fmt_read = bt_lookup_format(g_quark_from_static_string(opt_input_format)); if (!fmt_read) { fprintf(stderr, "[error] Format \"%s\" is not supported.\n\n", opt_input_format); partial_error = 1; goto end; } fmt_write = bt_lookup_format(g_quark_from_static_string(opt_output_format)); if (!fmt_write) { fprintf(stderr, "[error] format \"%s\" is not supported.\n\n", opt_output_format); partial_error = 1; goto end; } ctx = bt_context_create(); if (!ctx) { goto error_td_read; } for (i = 0; i < opt_input_paths->len; i++) { const char *ipath = g_ptr_array_index(opt_input_paths, i); ret = bt_context_add_traces_recursive(ctx, ipath, opt_input_format, NULL); if (ret < 0) { fprintf(stderr, "[error] opening trace \"%s\" for reading.\n\n", ipath); } else if (ret > 0) { fprintf(stderr, "[warning] errors occurred when opening trace \"%s\" for reading, continuing anyway.\n\n", ipath); open_success = 1; /* some traces were OK */ partial_error = 1; } else { open_success = 1; /* all traces were OK */ } } if (!open_success) { fprintf(stderr, "[error] none of the specified trace paths could be opened.\n\n"); goto error_td_read; } td_write = fmt_write->open_trace(opt_output_path, O_RDWR, NULL, NULL); if (!td_write) { fprintf(stderr, "Error opening trace \"%s\" for writing.\n\n", opt_output_path ? : "<none>"); goto error_td_write; }