void update_multi_timeout_values(multi_timeout_handler* mth) { int interval = calc_multi_timeout_interval(mth); int next_timeout_msec = interval; struct timespec cur_time; clock_gettime(CLOCK_MONOTONIC, &cur_time); GSList* it = mth->timeout_list; struct timespec diff_time; while (it) { timeout* t = it->data; t->multi_timeout->count_to_expiration = t->interval_msec / interval; timespec_subtract(&diff_time, &t->timeout_expires, &cur_time); int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000; int count_left = msec_to_expiration / interval + (msec_to_expiration % interval != 0); t->multi_timeout->current_count = t->multi_timeout->count_to_expiration - count_left; if (msec_to_expiration < next_timeout_msec) next_timeout_msec = msec_to_expiration; it = it->next; } mth->parent_timeout->interval_msec = interval; timeout_list = g_slist_remove(timeout_list, mth->parent_timeout); add_timeout_intern(next_timeout_msec, interval, callback_multi_timeout, mth, mth->parent_timeout); }
int main(int argc, char* argv[]) { const int mb = 1024 * 1024; pid_t child_pid, wpid; int status = 0; for (int num_of_processes = 1; num_of_processes <= 16; num_of_processes *= 2) { for (int num_of_tries = 0; num_of_tries < 10; num_of_tries++) { printf("========START: num_of_processes : %d try: %d========\n", num_of_processes, num_of_tries); int curr_child_process = -1; for (int i = 0; i < num_of_processes; i++) { curr_child_process++; if ((child_pid = fork()) == 0) { int fd; int total_bytes_read = 0; int bytes_read = 0; static char block[4096] __attribute__ ((__aligned__ (4096))); const int block_size = 4096; const int size = 8 * mb; struct timespec start, end, time_diff; char filename[80]; snprintf(filename, sizeof (filename), "./random8M_%d", curr_child_process); printf("start reading child pid: %d, filename: %s\n", child_pid, filename); if ((fd = open(filename, O_RDONLY | O_DIRECT)) == -1) { perror("Error: read error"); exit(1); } if (lseek(fd, 0, SEEK_SET) == -1) { perror("Error: lseek()"); exit(1); } clock_gettime(CLOCK_MONOTONIC, &start); while (total_bytes_read < size) { if ((bytes_read = read(fd, block, block_size)) == -1) { perror("Error: read()"); exit(1); } total_bytes_read += bytes_read; } clock_gettime(CLOCK_MONOTONIC, &end); timespec_subtract(&start, &end, &time_diff); printf("INSTANT diff: %ld sec %lld ns, start time: %ld sec %lld ns, end time: %ld sec %lld ns\n", time_diff.tv_sec, (uint64_t)time_diff.tv_nsec, start.tv_sec, (uint64_t)start.tv_nsec, end.tv_sec, (uint64_t)end.tv_nsec); close(fd); exit(1); } } while ((wpid = wait(&status)) > 0) { printf("end reading child_pid: %d, status: %d\n", (int)wpid, status); } printf("========END: num_of_processes : %d try: %d========\n\n", num_of_processes, num_of_tries); } }
/* * Wait for an appropriate response packet for 'secs' seconds. * Appropriateness is checked by calling callback(), which must return * a non-zero value to cancel the select loop. * * Returns 0 on success, -1 on failure (timeout). */ int ts_packet_wait(struct tunsess *tun, int secs, int (*callback)(struct tunsess *)) { fd_set rfds; struct timespec ts_wait; struct timespec ts_end; struct timespec ts_current; int r; FD_ZERO(&rfds); FD_SET(tun->sockfd, &rfds); clock_gettime(CLOCK_MONOTONIC, &ts_end); ts_end.tv_sec += secs; do_select: clock_gettime(CLOCK_MONOTONIC, &ts_current); current = tun; if (timespec_subtract(&ts_wait, &ts_end, &ts_current) == 1) goto timed_out; r = pselect(tun->sockfd+1, &rfds, NULL, NULL, &ts_wait, NULL); if (r==1) { ts_recv_packet(tun); if (callback(tun) == 0) return 0; } if (!tun->close_flag) goto do_select; timed_out: return -1; }
void ts_keepalive(struct tunsess *tun) { struct timespec t; for (;;) { /* check MTU */ ts_compose_packet(tun, PACKET_KEEPALIVE, ""); tun->outlen = 2048; ts_send_packet(tun); if (ts_packet_wait(tun, KEEPALIVE_INTERVAL, keepalive_cb) == 0 || tun->close_flag) return; clock_gettime(CLOCK_MONOTONIC, &t); timespec_subtract(&t, &t, &tun->last_seen); debug("last seen: %d seconds ago.\n", t.tv_sec); if (t.tv_sec >= KEEPALIVE_TIMELIMIT) { error("tunnel timed out. shutting down.\n"); return; } ts_compose_packet(tun, PACKET_KEEPALIVE, ""); ts_send_packet(tun); debug("sent KEEPALIVE\n"); } }
int main (void) { void *context = zmq_init(1); void *consumer = zmq_socket(context, ZMQ_PULL); pthread_t emitter_thread; pthread_create(&emitter_thread, NULL, emit, context); zmq_bind(consumer, "inproc://example"); int count = 50000000; struct timespec start, end, duration; clock_gettime(CLOCK_MONOTONIC, &start); for (int i = 0; i < count; i++) { zmq_msg_t message; zmq_msg_init(&message); zmq_recv(consumer, &message, 0); zmq_msg_close(&message); } clock_gettime(CLOCK_MONOTONIC, &end); timespec_subtract(&duration, &end, &start); double rate = count / (duration.tv_sec + (duration.tv_nsec / 100000000.0)); printf("Rate: %lf (count: %d)\n", rate, count); return 0; }
void print_terminated_process(pid_t pid) { #if DEBUG struct timespec now; int r; #endif if (!waitproc_flags_test(WAITPROC_FLAG_QUIET)) { #if DEBUG if (!timespec_iszero(&waitproc_options.wait_start)) { r = clock_gettime(CLOCK_MONOTONIC, &now); assert(r == 0); } else { r = -1; } #endif printf( #if DEBUG "[%10.6g s] " #endif "%i\n", #if DEBUG !r ? timespec_subtract(&now, &waitproc_options.wait_start) : 0.0, #endif pid ); } }
void remove_from_multi_timeout(timeout* t) { multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t); g_hash_table_remove(multi_timeouts, t); mth->timeout_list = g_slist_remove(mth->timeout_list, t); free(t->multi_timeout); t->multi_timeout = 0; if (g_slist_length(mth->timeout_list) == 1) { timeout* last_timeout = mth->timeout_list->data; mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout); free(last_timeout->multi_timeout); last_timeout->multi_timeout = 0; g_hash_table_remove(multi_timeouts, last_timeout); g_hash_table_remove(multi_timeouts, mth->parent_timeout); mth->parent_timeout->multi_timeout = 0; stop_timeout(mth->parent_timeout); free(mth); struct timespec cur_time, diff_time; clock_gettime(CLOCK_MONOTONIC, &cur_time); timespec_subtract(&diff_time, &t->timeout_expires, &cur_time); int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000; add_timeout_intern(msec_to_expiration, last_timeout->interval_msec, last_timeout->_callback, last_timeout->arg, last_timeout); } else update_multi_timeout_values(mth); }
int main(void) { int err, conderr; long *input_set; int i, size = NUM_ITERATION; input_set = polynomial_dist(size, 4, 0, 10000000); pthread_condattr_t condattr; pthread_condattr_init(&condattr); #ifdef COND_SETCLOCK pthread_condattr_setclock(&condattr, CLOCK_ID); #endif pthread_cond_init(&cond, &condattr); for (i = 0; i < size; i++) { struct timespec ts_begin, ts_deadline, ts_end, ts_diff; err = pthread_mutex_lock(&mutex); if (err != 0) error(1, err, "pthread_mutex_lock() failed"); err = clock_gettime(CLOCK_ID, &ts_begin); if (err != 0) error(1, errno, "clock_gettime() failed"); ts_deadline = ts_begin; ts_deadline.tv_nsec += input_set[i]; timespec_normalize(&ts_deadline); conderr = pthread_cond_timedwait(&cond, &mutex, &ts_deadline); err = clock_gettime(CLOCK_ID, &ts_end); if (err != 0) error(1, errno, "clock_gettime() failed"); timespec_subtract(&ts_diff, &ts_deadline, &ts_end); if (conderr != 0) { if (conderr == ETIMEDOUT) { printf("TIMEOUT,%.9Lf,%ld.%09ld\n", (long double)input_set[i] / 1000000000, ts_diff.tv_sec, ts_diff.tv_nsec); } else error(1, conderr, "pthread_cond_timedwait() failed"); err = pthread_mutex_unlock(&mutex); if (err != 0) error(1, err, "pthread_mutex_unlock() failed"); } else { /* unlikely, except suprious wakeup */ printf("SUCCESS %Lf %ld.%09ld\n", (long double)input_set[i] / 1000000000, ts_diff.tv_sec, ts_diff.tv_nsec); } } return 0; }
static void stop_time_profile(struct time_profile* profile) { if (!profile->initialised) { profile->initialised = 1; clock_gettime(&profile->time_session); } if (!profile->running) return; profile->running = 0; struct timeval cur_time; clock_gettime(&cur_time); struct timeval cur_diff; timespec_subtract(&profile->time_session, &cur_time, &cur_diff); timespec_add(&profile->time_active, &cur_diff, &profile->time_active); }
static void handler(int sig, siginfo_t *si, void *uc) { static struct timespec prev; struct timespec curr, diff; /* Note: calling printf() from a signal handler is not strictly correct, since printf() is not async-signal-safe; see signal(7) */ clock_gettime( CLOCK_REALTIME, &curr ); timespec_subtract( &diff, &curr, &prev ); printf( "Diff: %lu.%09lu ", diff.tv_sec, diff.tv_nsec ); printf("Caught signal %d\n", sig); print_siginfo(si); prev = curr; /* signal(sig, SIG_IGN); */ }
void update_next_timeout() { if (timeout_list) { timeout* t = timeout_list->data; struct timespec cur_time; struct timespec next_timeout2 = {.tv_sec = next_timeout.tv_sec, .tv_nsec = next_timeout.tv_usec * 1000}; clock_gettime(CLOCK_MONOTONIC, &cur_time); if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) { next_timeout.tv_sec = 0; next_timeout.tv_usec = 0; } else { next_timeout.tv_sec = next_timeout2.tv_sec; next_timeout.tv_usec = next_timeout2.tv_nsec / 1000; } } else next_timeout.tv_sec = -1; }
int main(int argc, char** argv) { int class_n, data_n, iteration_n; float *centroids, *data; int* partitioned; FILE *io_file; struct timespec start, end, spent; // Check parameters if (argc < 4) { fprintf(stderr, "usage: %s <centroid file> <data file> <paritioned result> [<final centroids>] [<iteration number>]\n", argv[0]); exit(EXIT_FAILURE); } // Read initial centroid data io_file = fopen(argv[1], "rb"); if (io_file == NULL) { fprintf(stderr, "File open error %s\n", argv[1]); exit(EXIT_FAILURE); } class_n = read_data(io_file, ¢roids); fclose(io_file); // Read input data io_file = fopen(argv[2], "rb"); if (io_file == NULL) { fprintf(stderr, "File open error %s\n", argv[2]); exit(EXIT_FAILURE); } data_n = read_data(io_file, &data); fclose(io_file); iteration_n = argc > 5 ? atoi(argv[5]) : DEFAULT_ITERATION; partitioned = (int*)malloc(sizeof(int)*data_n); clock_gettime(CLOCK_MONOTONIC, &start); // Run Kmeans algorithm kmeans(iteration_n, class_n, data_n, (Point*)centroids, (Point*)data, partitioned); clock_gettime(CLOCK_MONOTONIC, &end); timespec_subtract(&spent, &end, &start); printf("Time spent: %ld.%09ld\n", spent.tv_sec, spent.tv_nsec); // Write classified result io_file = fopen(argv[3], "wb"); fwrite(&data_n, sizeof(data_n), 1, io_file); fwrite(partitioned, sizeof(int), data_n, io_file); fclose(io_file); // Write final centroid data if (argc > 4) { io_file = fopen(argv[4], "wb"); fwrite(&class_n, sizeof(class_n), 1, io_file); fwrite(centroids, sizeof(Point), class_n, io_file); fclose(io_file); } // Free allocated buffers free(centroids); free(data); free(partitioned); return 0; }
/** * time_read_samples() - Measure the time it takes to read the samples * @first_frame: First frame to read * @num_frames: Number of frames to read * @num_chans: Number of channels to read * * @note One frame is 32 samples which makes it 2 samples for each channel. * */ int time_read_samples(unsigned int first_frame, unsigned int num_frames, unsigned int num_chans) { int rc = 0; int i, j; double total_time = 0.0; double total_throughput; if (num_frames <= 0) return -1; /* Set readstart and readlen */ if ((rc = vd80_set_readstart(first_frame))) return rc; if ((rc = vd80_set_readlen(num_frames - 1))) return rc; /* Allocate memory for the buffers */ for (i = 0; i < num_chans; i++) { read_buf[i] = NULL; if (posix_memalign((void **)&read_buf[i], 4096, num_frames * 4)) { printf("Failed to allocate buffer for channel %d: %s\n", i+1, strerror(errno)); rc = 1; goto out_free; } } /* Read the samples for each channel */ printf("Starting samples readout\n"); for (i = 0; i < num_chans; i++) { /* Select the channel to read from */ if ((rc = vd80_cmd_read(i + 1))) goto out_free; /* Read the samples */ clock_gettime(CLOCK_MONOTONIC,&read_start_time[i]); for (j = 0; j < num_frames; j++) read_buf[i][j] = vd80_get_sample(); clock_gettime(CLOCK_MONOTONIC,&read_end_time[i]); } printf("Done reading %d samples on %d channels\n\n", num_frames * 2, num_chans); printf("Throughput: \n"); /* Display throughput */ for (i = 0; i < num_chans; i++) { unsigned long long delta_ns; double delta; double throughput; delta_ns = timespec_subtract(&read_start_time[i], &read_end_time[i]); delta = (double)delta_ns/(double)1000000000.0; throughput = (double)(num_frames * 2) / delta; printf(" Ch%-2d: %.6fs - %.6f MSPS\n", i+1, delta, throughput/(1024.0*1024.0)); total_time += delta; } total_throughput = (double)(num_frames * 2 * num_chans) / total_time; printf("\n"); printf("Total: %.6f s %.6f MSPS\n", total_time, total_throughput/(1024.0*1024.0)); printf("\n"); out_free: for (i = 0; i < num_chans; i++) { if (read_buf[i]) free(read_buf[i]); } return rc; }
static u32_t cond_wait(XaxMachinery *xm, ZCond *zcond, ZMutex *zmutex, u32_t timeout_ms, bool verbose) { int result; ZCondWaitRecord zcwr; zcondwaitrecord_init_auto(&zcwr, xm->zdt, zcond, zmutex); ZAS *zasses[2]; zasses[0] = &zcwr.zas; int zascount = 1; LegacyZTimer *ztimer; bool using_ztimer = false; struct timespec start_time; if (timeout_ms > 0) { (xm->zclock->methods->read)(xm->zclock, &start_time); struct timespec timeout_offset; ms_to_timespec(&timeout_offset, timeout_ms); struct timespec timeout_absolute; timespec_add(&timeout_absolute, &start_time, &timeout_offset); ztimer = (xm->zclock->methods->new_timer)(xm->zclock, &timeout_absolute); zasses[1] = (xm->zclock->methods->get_zas)(ztimer); zascount += 1; using_ztimer = true; } if (verbose) { fprintf(stderr, "xax_arch cond_wait zcond %08x START\n", (uint32_t) zcond); } int idx = zas_wait_any(xm->zdt, zasses, zascount); if (verbose && idx==0) { fprintf(stderr, "xax_arch cond_wait zcond %08x SUCCEED\n", (uint32_t) zcond); } if (idx==1) { result = SYS_ARCH_TIMEOUT; } else if (timeout_ms > 0) { /* Calculate for how long we waited for the cond. */ struct timespec end_time; (xm->zclock->methods->read)(xm->zclock, &end_time); struct timespec delay; timespec_subtract(&delay, &end_time, &start_time); result = timespec_to_ms(&delay); } else { result = SYS_ARCH_TIMEOUT; } if (using_ztimer) { (xm->zclock->methods->free_timer)(ztimer); } zcondwaitrecord_free(xm->zdt, &zcwr); return result; }
/** * pka_encoder_real_encode_samples: * @manifest: A #PkaManifest. * * Default encoder for samples. * * Returns: None. * Side effects: None. */ static gboolean pka_encoder_real_encode_samples (PkaManifest *manifest, /* IN */ PkaSample **samples, /* IN */ gint n_samples, /* IN */ guint8 **data, /* OUT */ gsize *data_len) /* OUT */ { EggBuffer *buf; struct timespec mts; struct timespec sts; struct timespec rel; guint64 rel_composed; PkaResolution res; const guint8 *tbuf; gsize tlen; gint i; g_return_val_if_fail(data != NULL, FALSE); g_return_val_if_fail(data_len != NULL, FALSE); ENTRY; buf = egg_buffer_new(); pka_manifest_get_timespec(manifest, &mts); res = pka_manifest_get_resolution(manifest); for (i = 0; i < n_samples; i++) { /* * Add the source identifier. */ egg_buffer_write_tag(buf, 1, EGG_BUFFER_UINT); egg_buffer_write_uint(buf, pka_sample_get_source_id(samples[i])); /* * Add the relative time since the manifest; loosing un-needed * precision to aide varint encoding. */ pka_sample_get_timespec(samples[i], &sts); timespec_subtract(&sts, &mts, &rel); rel_composed = pka_resolution_apply(res, &rel); egg_buffer_write_tag(buf, 2, EGG_BUFFER_UINT64); egg_buffer_write_uint64(buf, rel_composed); /* * The sample is a protobuf inspired blob but is not protobuf compat. * * This was so that we could save significant message and repeated type * overhead that is not needed for introspection since we have the * manifest to provide us that data. * * Therefore, we simply treat the sample as an opaque buffer for the * other side to unwrap. */ pka_sample_get_data(samples[i], &tbuf, &tlen); egg_buffer_write_tag(buf, 3, EGG_BUFFER_DATA); egg_buffer_write_data(buf, tbuf, tlen); } egg_buffer_get_buffer(buf, &tbuf, &tlen); *data = g_malloc(tlen); *data_len = tlen; memcpy(*data, tbuf, tlen); egg_buffer_unref(buf); RETURN(TRUE); }
int main(int argc, char **argv) { char* address = NULL; char* service = NULL; char opt; char buf[BUFFER_SIZE]; ssize_t bytes_read = 0; ssize_t data_size = 0; ssize_t data_alloced = BUFFER_SIZE; char* data = malloc(BUFFER_SIZE); int sock; struct iovec* vecs = NULL; int n_iovecs = 0; int vecs_written = 0; struct timespec send_time, stdin_time, connect_time; int return_status = 0; int rc; if (data == NULL) { fprintf(stderr, "could not malloc %u bytes for initial data\n", BUFFER_SIZE); return 1; } while ((opt = getopt(argc, argv, "hc:H:p:")) != -1) { switch(opt) { case 'h': print_help(); return_status = 0; goto end; case 'H': address = strdup(optarg); break; case 'p': service = strdup(optarg); break; default: print_help(); return_status = 1; goto end; } } if (address == NULL || service == NULL) { print_help(); return_status = 1; goto end; } clock_gettime(CLOCK_MONOTONIC, &stdin_start); /* Start by reading all of the data from stdin */ while(true) { bytes_read = read(STDIN_FILENO, buf, BUFFER_SIZE); if (bytes_read < 0) { perror("read"); return_status = 1; goto end; } else if (bytes_read == 0) { break; } else { if (data_size + bytes_read > data_alloced) { data_alloced *= 2; data = realloc(data, data_alloced); } memcpy(data + data_size, buf, bytes_read); data_size += bytes_read; } } clock_gettime(CLOCK_MONOTONIC, &stdin_end); if (data_size > IOBUF_SIZE * IOV_MAX) { fprintf(stderr, "data too large; got %zd bytes, max %d bytes\n", data_size, IOBUF_SIZE * IOV_MAX); return_status = 1; goto end; } timespec_subtract(&stdin_time, &stdin_end, &stdin_start); printf("took %lu.%09lus to read %zd bytes from stdin\n", stdin_time.tv_sec, stdin_time.tv_nsec, data_size); if ((sock = do_connect(address, service, &getaddr_start, &getaddr_end, &connect_start, &connect_end, false)) < 0) { perror("connect"); return_status = 1; goto end; } timespec_subtract(&connect_time, &connect_end, &getaddr_start); printf("took %lu.%09lus to connect to %s:%s; now going to send %zd bytes every 1s\n", connect_time.tv_sec, connect_time.tv_nsec, address, service, data_size); { if (data_size % IOBUF_SIZE == 0) { n_iovecs = (data_size / IOBUF_SIZE); } else { n_iovecs = (data_size / IOBUF_SIZE) + 1; } int n_iovecs_less_1 = n_iovecs - 1; int i; vecs = malloc(sizeof(struct iovec) * n_iovecs); Dprintf("Going to write %d iovecs\n", n_iovecs); for (i=0; i < n_iovecs; ++i) { vecs[i].iov_base = data + (i*IOBUF_SIZE); if (i < n_iovecs_less_1 ) { vecs[i].iov_len = IOBUF_SIZE; } else { vecs[i].iov_len = data_size - (n_iovecs_less_1 * IOBUF_SIZE); } Dprintf("vecs[%d].iov_len = %zd\n", i, vecs[i].iov_len); } } while (1) { struct timespec sleep_req, sleep_rem; vecs_written = 0; clock_gettime(CLOCK_MONOTONIC, &send_start); while (vecs_written < n_iovecs) { ssize_t written; Dprintf("going to try and write %d vecs starting at vec %d\n", n_iovecs - vecs_written, vecs_written); written = writev(sock, vecs + vecs_written, n_iovecs - vecs_written); if (written != data_size) { if (written < 0) { return_status = 1; DJperror(end, "writev"); } else if (written % IOBUF_SIZE != 0) { Dprintf(stderr, "wrote %zd bytes, IOBUF_SIZE=%d bytes. Ick!", written, IOBUF_SIZE); return_status = 1; goto end; } vecs_written += (written / IOBUF_SIZE); } else { vecs_written = n_iovecs; } Dprintf("wrote %zd bytes of %zd bytes this time; wrote %d/%d vecs\n", written, data_size, vecs_written, n_iovecs); } clock_gettime(CLOCK_MONOTONIC, &send_end); timespec_subtract(&send_time, &send_end, &send_start); if ((send_time.tv_sec >= 1) && (send_time.tv_nsec != 0)) { fprintf(stderr, "took more than 1 second to send %zd bytes!\n", data_size); } printf("took %lu.%09lus to send %zd bytes in %d vectors of ~%d bytes; \n", send_time.tv_sec, send_time.tv_nsec, data_size, n_iovecs, IOBUF_SIZE); sleep_req.tv_sec = 0; sleep_req.tv_nsec = (1000000000 - send_time.tv_nsec); rc = nanosleep(&sleep_req, &sleep_rem); while (rc != 0) { if (errno == EINTR) { rc = nanosleep(&sleep_rem, &sleep_rem); } else { perror("nanosleep"); } } } end: if (address != NULL) free(address); if (service != NULL) free(service); if (data != NULL) free(data); if (vecs != NULL) free(vecs); return return_status; }
int main(int argc, char *argv[]) { int i, j, k, err; unsigned long long delta; unsigned long long max, min; struct sched_param param; stats_container_t dat; stats_container_t hist; stats_quantiles_t quantiles; stats_record_t rec; struct timespec *start_data; struct timespec *stop_data; if (stats_cmdline(argc, argv) < 0) { printf("usage: %s help\n", argv[0]); exit(1); } if (iterations < MIN_ITERATION) { iterations = MIN_ITERATION; printf("user \"iterations\" value is too small (use: %d)\n", iterations); } stats_container_init(&dat, iterations); stats_container_init(&hist, HIST_BUCKETS); stats_quantiles_init(&quantiles, (int)log10(iterations)); setup(); mlockall(MCL_CURRENT | MCL_FUTURE); start_data = calloc(iterations, sizeof(struct timespec)); if (start_data == NULL) { printf("Memory allocation Failed (too many Iteration: %d)\n", iterations); exit(1); } stop_data = calloc(iterations, sizeof(struct timespec)); if (stop_data == NULL) { printf("Memory allocation Failed (too many Iteration: %d)\n", iterations); free(start_data); exit(1); } /* switch to SCHED_FIFO 99 */ param.sched_priority = sched_get_priority_max(SCHED_FIFO); err = sched_setscheduler(0, SCHED_FIFO, ¶m); /* Check that the user has the appropriate privileges */ if (err) { if (errno == EPERM) { fprintf(stderr, "This program runs with a scheduling policy of SCHED_FIFO at priority %d\n", param.sched_priority); fprintf(stderr, "You don't have the necessary privileges to create such a real-time process.\n"); } else { fprintf(stderr, "Failed to set scheduler, errno %d\n", errno); } exit(1); } printf("\n----------------------\n"); printf("Gettimeofday() Latency\n"); printf("----------------------\n"); printf("Iterations: %d\n\n", iterations); /* collect iterations pairs of gtod calls */ max = min = 0; if (latency_threshold) { latency_trace_enable(); latency_trace_start(); } /* This loop runs for a long time, hence can cause soft lockups. Calling sleep periodically avoids this. */ for (i = 0; i < (iterations / 10000); i++) { for (j = 0; j < 10000; j++) { k = (i * 10000) + j; clock_gettime(CLOCK_MONOTONIC, &start_data[k]); clock_gettime(CLOCK_MONOTONIC, &stop_data[k]); } usleep(1000); } for (i = 0; i < iterations; i++) { delta = timespec_subtract(&start_data[i], &stop_data[i]); rec.x = i; rec.y = delta; stats_container_append(&dat, rec); if (i == 0 || delta < min) min = delta; if (delta > max) max = delta; if (latency_threshold && delta > latency_threshold) break; } if (latency_threshold) { latency_trace_stop(); if (i != iterations) { printf ("Latency threshold (%lluus) exceeded at iteration %d\n", latency_threshold, i); latency_trace_print(); stats_container_resize(&dat, i + 1); } } stats_hist(&hist, &dat); stats_container_save(filenames[SCATTER_FILENAME], titles[SCATTER_TITLE], labels[SCATTER_LABELX], labels[SCATTER_LABELY], &dat, "points"); stats_container_save(filenames[HIST_FILENAME], titles[HIST_TITLE], labels[HIST_LABELX], labels[HIST_LABELY], &hist, "steps"); /* report on deltas */ printf("Min: %llu ns\n", min); printf("Max: %llu ns\n", max); printf("Avg: %.4f ns\n", stats_avg(&dat)); printf("StdDev: %.4f ns\n", stats_stddev(&dat)); printf("Quantiles:\n"); stats_quantiles_calc(&dat, &quantiles); stats_quantiles_print(&quantiles); stats_container_free(&dat); stats_container_free(&hist); stats_quantiles_free(&quantiles); return 0; }