int main(void) { #ifndef _POSIX_REALTIME_SIGNALS printf("_POSIX_REALTIME_SIGNALS is not defined\n"); return PTS_UNTESTED; #endif sigset_t set; struct sigevent ev; timer_t tid; struct itimerspec its; struct timespec tssleep, tsres; int overruns; int valuensec, intervalnsec, expectedoverruns; int fudge; if (sigemptyset(&set) != 0) { perror("sigemptyset() did not return success\n"); return PTS_UNRESOLVED; } if (sigaddset(&set, SIGCONT) != 0) { perror("sigaddset() did not return success\n"); return PTS_UNRESOLVED; } if (sigprocmask(SIG_SETMASK, &set, NULL) != 0) { perror("sigprocmask() did not return success\n"); return PTS_UNRESOLVED; } ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = SIGCONT; /* * create first timer */ if (timer_create(CLOCK_REALTIME, &ev, &tid) != 0) { perror("timer_create() did not return success\n"); return PTS_UNRESOLVED; } if (clock_getres(CLOCK_REALTIME, &tsres) != 0) { perror("clock_gettime() did not return success\n"); return PTS_UNRESOLVED; } if (tsres.tv_sec != 0) { printf("Clock resolution in seconds, not nsecs. Exiting.\n"); return PTS_UNRESOLVED; } valuensec = tsres.tv_nsec; intervalnsec = 2 * valuensec; //expectedoverruns = (1000000000 - valuensec) / intervalnsec; expectedoverruns = 1000000000 / intervalnsec - 1; printf("value = %d sec, interval = %d nsec, " "expected overruns = %d\n", 1, intervalnsec, expectedoverruns); its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = intervalnsec; its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; //its.it_value.tv_sec = 0; //its.it_value.tv_nsec = valuensec; if (timer_settime(tid, 0, &its, NULL) != 0) { perror("timer_settime() did not return success\n"); return PTS_UNRESOLVED; } //tssleep.tv_nsec = valuensec + (expectedoverruns*intervalnsec); tssleep.tv_nsec = 0; tssleep.tv_sec = 2; if (nanosleep(&tssleep, NULL) != 0) { perror("nanosleep() did not return success\n"); return PTS_UNRESOLVED; } /* * Since the overrun count is only meaningful with respect * to a particular timer expiry disable the timer before * un-blocking the signal. This ensures that there is only * one expiry and it should have a meaningful overrun count. */ //its.it_interval.tv_sec = 0; //its.it_interval.tv_nsec = 0; //its.it_value.tv_sec = 0; //its.it_value.tv_nsec = 0; //if (timer_settime(tid, 0, &its, NULL) != 0) { // perror("timer_settime() did not return success\n"); // return PTS_UNRESOLVED; //} if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) { perror("sigprocmask() did not return success\n"); return PTS_UNRESOLVED; } overruns = timer_getoverrun(tid); printf("%d overruns occurred\n", overruns); /* * Depending on the clock resolution we may have a few * extra expiries after the nanosleep completes so do * a range check. */ fudge = expectedoverruns / 100; if (overruns >= expectedoverruns && overruns < expectedoverruns + fudge) { printf("Test PASSED\n"); return PTS_PASS; } printf("FAIL: %d overruns sent; expected %d\n", overruns, expectedoverruns); return PTS_FAIL; }
/* * Opens the specified RS-485 device (i.e. /dev/ttyUSB0), initializes it for * DMX operation, and returns its file descriptor. Returns -1 on error. * Displays no device open error messages if quiet is nonzero (other errors and * warnings will still be displayed). */ dmx_state *dmx_open_ex(char *filename, int quiet, dmx_state *status) { struct serial_struct serinfo; // Linux-specific serial port settings struct termios terminfo; // Terminal settings int actual_rate; // Actual baud rate achieved int mctrl; // Modem control lines int fd; // File descriptor struct timespec res; // Monotonic clock resolution // Open device if((fd = open(filename, O_WRONLY)) < 0) { if(!quiet) { fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno)); } return NULL; } // Set the custom baud rate if(ioctl(fd, TIOCGSERIAL, &serinfo)) { perror("Error getting serial port settings"); close(fd); return NULL; } serinfo.flags &= ~ASYNC_SPD_MASK; serinfo.flags |= ASYNC_SPD_CUST; serinfo.custom_divisor = serinfo.baud_base / 250000; actual_rate = serinfo.baud_base / serinfo.custom_divisor; if(actual_rate != 250000) { // Rate is inexact, but within DMX specs if(actual_rate > 248756 && actual_rate < 255102) { fprintf(stderr, "Warning: actual baud rate is not exactly 250000 (%d)\n", actual_rate); } else { fprintf(stderr, "Error: actual baud rate is too far from 250000 (%d)\n", actual_rate); close(fd); return NULL; } } if(ioctl(fd, TIOCSSERIAL, &serinfo)) { perror("Error setting serial port settings"); close(fd); return NULL; } // Set terminal and line settings (echo, stop bits, etc.) if(tcgetattr(fd, &terminfo)) { perror("Error getting terminal settings"); close(fd); return NULL; } cfmakeraw(&terminfo); terminfo.c_cflag = CS8 | CSTOPB; cfsetspeed(&terminfo, B38400); // custom speed will be used instead of 38400 if(tcsetattr(fd, TCSAFLUSH, &terminfo)) { perror("Error setting terminal settings"); close(fd); return NULL; } // Set control lines low mctrl = 0; if(ioctl(fd, TIOCMSET, &mctrl)) { perror("Error setting handshaking lines"); close(fd); return NULL; } status->fd = fd; status->channels_to_send = DEFAULT_CHANNELS_TO_SEND; status->break_time = DEFAULT_BRK; status->mark_time = DEFAULT_MAB; status->frame_period = DEFAULT_PERIOD; status->actual_rate = actual_rate; // Initialize rate control if(clock_getres(CLOCK_MONOTONIC, &res)) { perror("Error: no monotonic clock?"); close(fd); return NULL; } if(res.tv_sec != 0 || res.tv_nsec > 100000) { fprintf(stderr, "Warning: monotonic clock resolution is worse than 100us (%ld.%09lds)\n", (long)res.tv_sec, res.tv_nsec); } status->next_time = malloc(sizeof(struct timespec)); if(status->next_time == NULL) { perror("Error allocating timer memory"); close(fd); return NULL; } // Make sure the first frame gets sent immediately clock_gettime(CLOCK_MONOTONIC, status->next_time); return status; }
void Timer::InitFreq() { clock_getres(CLOCK_MONOTONIC, &gFreq); }
/*! * Default constructor. * * \post elapsed() == 0 */ Timer() { clock_getres(CLOCK_REALTIME, &start_time); freq = (long)(1.0 / (start_time.tv_sec + 0.001*0.001*0.001*start_time.tv_nsec)); }
static gboolean initialize_caps(struct mcap_mcl *mcl) { struct timespec t1, t2; int latencies[SAMPLE_COUNT]; int latency, avg, dev; uint32_t btclock; uint16_t btaccuracy; int i; int retries; clock_getres(CLK, &t1); _caps.ts_res = time_us(&t1); if (_caps.ts_res < 1) _caps.ts_res = 1; _caps.ts_acc = 20; /* ppm, estimated */ /* A little exercise before measuing latency */ clock_gettime(CLK, &t1); read_btclock_retry(mcl, &btclock, &btaccuracy); /* Read clock a number of times and measure latency */ avg = 0; i = 0; retries = MAX_RETRIES; while (i < SAMPLE_COUNT && retries > 0) { clock_gettime(CLK, &t1); if (!read_btclock(mcl, &btclock, &btaccuracy)) { retries--; continue; } clock_gettime(CLK, &t2); latency = time_us(&t2) - time_us(&t1); latencies[i] = latency; avg += latency; i++; } if (retries <= 0) return FALSE; /* Calculate average and deviation */ avg /= SAMPLE_COUNT; dev = 0; for (i = 0; i < SAMPLE_COUNT; ++i) dev += abs(latencies[i] - avg); dev /= SAMPLE_COUNT; /* Calculate corrected average, without 'freak' latencies */ latency = 0; for (i = 0; i < SAMPLE_COUNT; ++i) { if (latencies[i] > (avg + dev * 6)) latency += avg; else latency += latencies[i]; } latency /= SAMPLE_COUNT; _caps.latency = latency; _caps.preempt_thresh = latency * 4; _caps.syncleadtime_ms = latency * 50 / 1000; csp_caps_initialized = TRUE; return TRUE; }
/* * Calculate a second-aligned starting time for the packet stream. Busy * wait between our calculated interval and dropping the provided packet * into the socket. If we hit our duration limit, bail. * We sweep the ports from a->port to a->port_max included. * If the two ports are the same we connect() the socket upfront, which * almost halves the cost of the sendto() call. */ static int timing_loop(struct _a *a) { struct timespec nexttime, starttime, tmptime; long long waited; u_int32_t counter; long finishtime; long send_errors, send_calls; /* do not call gettimeofday more than every 20us */ long minres_ns = 200000; int ic, gettimeofday_cycles; int cur_port; uint64_t n, ns; if (clock_getres(CLOCK_REALTIME, &tmptime) == -1) { perror("clock_getres"); return (-1); } ns = a->interval.tv_nsec; if (timespec_ge(&tmptime, &a->interval)) fprintf(stderr, "warning: interval (%jd.%09ld) less than resolution (%jd.%09ld)\n", (intmax_t)a->interval.tv_sec, a->interval.tv_nsec, (intmax_t)tmptime.tv_sec, tmptime.tv_nsec); /* interval too short, limit the number of gettimeofday() * calls, but also make sure there is at least one every * some 100 packets. */ if ((long)ns < minres_ns/100) gettimeofday_cycles = 100; else gettimeofday_cycles = minres_ns/ns; fprintf(stderr, "calling time every %d cycles\n", gettimeofday_cycles); if (clock_gettime(CLOCK_REALTIME, &starttime) == -1) { perror("clock_gettime"); return (-1); } tmptime.tv_sec = 2; tmptime.tv_nsec = 0; timespec_add(&starttime, &tmptime); starttime.tv_nsec = 0; if (wait_time(starttime, NULL, NULL) == -1) return (-1); nexttime = starttime; finishtime = starttime.tv_sec + a->duration; send_errors = send_calls = 0; counter = 0; waited = 0; ic = gettimeofday_cycles; cur_port = a->port; if (a->port == a->port_max) { if (a->ipv6) { if (connect(a->s, (struct sockaddr *)&a->sin6, sizeof(a->sin6))) { perror("connect (ipv6)"); return (-1); } } else { if (connect(a->s, (struct sockaddr *)&a->sin, sizeof(a->sin))) { perror("connect (ipv4)"); return (-1); } } } while (1) { int ret; timespec_add(&nexttime, &a->interval); if (--ic <= 0) { ic = gettimeofday_cycles; if (wait_time(nexttime, &tmptime, &waited) == -1) return (-1); } /* * We maintain and, if there's room, send a counter. Note * that even if the error is purely local, we still increment * the counter, so missing sequence numbers on the receive * side should not be assumed to be packets lost in transit. * For example, if the UDP socket gets back an ICMP from a * previous send, the error will turn up the current send * operation, causing the current sequence number also to be * skipped. * The counter is incremented only on the initial port number, * so all destinations will see the same set of packets. */ if (cur_port == a->port && a->packet_len >= 4) { be32enc(a->packet, counter); counter++; } if (a->port == a->port_max) { /* socket already bound */ ret = send(a->s, a->packet, a->packet_len, 0); } else { a->sin.sin_port = htons(cur_port++); if (cur_port > a->port_max) cur_port = a->port; if (a->ipv6) { ret = sendto(a->s, a->packet, a->packet_len, 0, (struct sockaddr *)&a->sin6, sizeof(a->sin6)); } else { ret = sendto(a->s, a->packet, a->packet_len, 0, (struct sockaddr *)&a->sin, sizeof(a->sin)); } } if (ret < 0) send_errors++; send_calls++; if (a->duration != 0 && tmptime.tv_sec >= finishtime) goto done; } done: if (clock_gettime(CLOCK_REALTIME, &tmptime) == -1) { perror("clock_gettime"); return (-1); } printf("\n"); printf("start: %jd.%09ld\n", (intmax_t)starttime.tv_sec, starttime.tv_nsec); printf("finish: %jd.%09ld\n", (intmax_t)tmptime.tv_sec, tmptime.tv_nsec); printf("send calls: %ld\n", send_calls); printf("send errors: %ld\n", send_errors); printf("approx send rate: %ld pps\n", (send_calls - send_errors) / a->duration); n = send_calls - send_errors; if (n > 0) { ns = (tmptime.tv_sec - starttime.tv_sec) * 1000000000UL + (tmptime.tv_nsec - starttime.tv_nsec); n = ns / n; } printf("time/packet: %u ns\n", (u_int)n); printf("approx error rate: %ld\n", (send_errors / send_calls)); printf("waited: %lld\n", waited); printf("approx waits/sec: %lld\n", (long long)(waited / a->duration)); printf("approx wait rate: %lld\n", (long long)(waited / send_calls)); return (0); }
main() { struct timespec tp1, tp2; long timp1, timp2, timp3; int i1,i2,x,y; int count; int s1; long double s2; long double accum; long double accum1; struct timespec clock_resolution; int stat; wiringPiSetup () ; pinMode (7, INPUT) ; printf("Start\n"); stat = clock_getres(CLOCK_REALTIME, &clock_resolution); printf("Clock resolution is %d seconds, %ld nanoseconds\n", clock_resolution.tv_sec, clock_resolution.tv_nsec); clock_gettime(CLOCK_REALTIME, &tp1); count=0; while ( count < 200000 ) { while ( digitalRead(7) == LOW ) { } count++; while ( digitalRead(7) == HIGH ) { } count++; } clock_gettime(CLOCK_REALTIME, &tp2); s1 = tp2.tv_sec-tp1.tv_sec; clock_gettime(CLOCK_REALTIME, &tp1); count=0; while ( count < 200000 ) { while ( digitalRead(7) == LOW ) { } count++; while ( digitalRead(7) == HIGH ) { } count++; } clock_gettime(CLOCK_REALTIME, &tp2); s1 = tp2.tv_sec-tp1.tv_sec; s2 = tp2.tv_nsec-tp1.tv_nsec; accum = ( tp2.tv_nsec - tp1.tv_nsec ); accum1= accum; if ( accum<0 ) { accum=accum+1000000000; printf(" acumulator atenuat \n"); } accum1=accum1+s1*1000000000; printf( "ACCUM %lf \n", accum ); printf( "!! ACCUM1 %lf !! \n", accum1); printf(" dif1 calcul scadere secunde %ld \n",s1); printf(" dif2 calcul scadere nanosec %ld \n",s2); printf(" Rez citit secunde %d %d \n",tp1.tv_sec, tp1.tv_nsec); printf(" Rez citit nanosec %ld %lld \n",tp2.tv_sec, tp2.tv_nsec); printf(" Rez calc sec %ld \n",tp2.tv_sec-tp1.tv_sec); printf(" Rez calc nanosec %ld \n",tp2.tv_nsec-tp1.tv_nsec); printf("Stop\n"); }
int main(void) { pid_t childPid = -1; int pipeArr[2]; int retval = -1; struct timespec real_time_res, parentNow, childNow; sigset_t mask, oldmask, zeromask; struct sigaction sigact; union sigval value; // Get clock resolution clock_getres(CLOCK_REALTIME, &real_time_res); printf("Real time clock resolution is: %ld s %ld ns\n", real_time_res.tv_sec, real_time_res.tv_nsec); // Create a pipe for parent-child communication if (pipe(pipeArr) < 0) { perror("pipe"); exit(EXIT_FAILURE); } // Install signal handler sigemptyset(&sigact.sa_mask); sigact.sa_flags = SA_SIGINFO; // use real-time signal handler sigact.sa_sigaction = sigactionHandler; sigaction(SIGRTMAX, &sigact, NULL); // Block SIGRTMAX signal to prevent race condition sigemptyset(&mask); sigemptyset(&zeromask); sigaddset(&mask, SIGRTMAX); sigprocmask(SIG_BLOCK, &mask, &oldmask); // Initialize variables to zero memset(&childTimeNow, 0, sizeof(struct timespec)); memset(&parentNow, 0, sizeof(struct timespec)); memset(&childNow, 0, sizeof(struct timespec)); value.sival_int = 0; // Fork a child childPid = fork(); if (childPid < 0) { perror("fork"); exit(EXIT_FAILURE); } else if (childPid > 0) { clock_gettime(CLOCK_REALTIME, &parentNow); if (sigqueue(childPid, SIGRTMAX, value) < 0) { perror("sigqueue"); exit(EXIT_FAILURE); } close(pipeArr[0]); if (write(pipeArr[1], &parentNow, sizeof(struct timespec)) < 0) { perror("write"); exit(EXIT_FAILURE); } close(pipeArr[1]); wait(NULL); printf("Child terminated\n"); exit(EXIT_SUCCESS); } else { sigprocmask(SIG_SETMASK, &oldmask, NULL); while(n < 1) sigsuspend(&zeromask); retval = read(pipeArr[0], &childNow, sizeof(struct timespec)); if (retval < 0) { perror("read"); exit(EXIT_FAILURE); } else { // Calculate real-time signal delivery delay and display the delay in microsecond printf("Real time signal delivery delay: %ld s %ld us\n", (childTimeNow.tv_sec - childNow.tv_sec), (childTimeNow.tv_nsec - childNow.tv_nsec)/1000); } exit(EXIT_SUCCESS); } return EXIT_SUCCESS; }
void main(int argc, char* argv[]) { // struct timespec tp1, tp2; long timp1, timp2, timp3; int i1,i2,x,y; int s1; long double s2; long double accum; long double accum1; float rb; float ra; struct timespec clock_resolution; int stat; unsigned int cycle1; wiringPiSetup () ; pinMode (tsl_pin, INPUT) ; // cycle1=100; // printf("COnversie %d ",atoi(argv[0])); printf("COnversie parametru %d \n",atoi(argv[1])); // printf("COnversie %d ",atoi(argv[3])); cycle1=atoi(argv[1]); printf("Start\n"); printf(" Cycles = %d \n",cycle1); stat = clock_getres(CLOCK_REALTIME, &clock_resolution); printf("Clock resolution is %d seconds, %ld nanoseconds\n", clock_resolution.tv_sec, clock_resolution.tv_nsec); //actual readout - gettime/ loop untill "cycles" counts are met / gettime again and make diff clock_gettime(CLOCK_REALTIME, &tp1); count_wait_tsl(cycle1); clock_gettime(CLOCK_REALTIME, &tp2); // here frequency should be computed and converted to uW/cm2 . 1khz = 1 uW/m2 ra=time_diff(tp1,tp2)/1000; rb=cycle1*500000/ra; printf("Frequency is : %f \n",ra); printf("Power is : %f uW/cm2\n",rb); //Just verification prints printf(" Rezultat %ld \n",time_diff(tp1,tp2)); printf("Sec2 %d \n",tp2.tv_sec); printf("Sec1 %d \n",tp1.tv_sec); printf("NANO Sec2 %ld \n",tp2.tv_nsec); printf("NANO Sec1 %ld \n",tp1.tv_nsec); printf(" REZ %ld \n",tp2.tv_nsec-tp1.tv_nsec+1000000000*(tp2.tv_sec-tp1.tv_sec)); //---------------------------- //actual readout - gettime/ loop untill "cycles" counts are met / gettime again and make diff cycle1=cycle1*2; clock_gettime(CLOCK_REALTIME, &tp1); count_wait_tsl(cycle1); clock_gettime(CLOCK_REALTIME, &tp2); // here frequency should be computed and converted to uW/cm2 . 1khz = 1 uW/m2 ra=time_diff(tp1,tp2)/1000; rb=cycle1*500000/ra; printf("Frequency is : %f \n",ra); printf("Power is : %f uW/cm2\n",rb); //Just verification prints printf(" Rezultat %ld \n",time_diff(tp1,tp2)); printf("Sec2 %d \n",tp2.tv_sec); printf("Sec1 %d \n",tp1.tv_sec); printf("NANO Sec2 %ld \n",tp2.tv_nsec); printf("NANO Sec1 %ld \n",tp1.tv_nsec); printf(" REZ %ld \n",tp2.tv_nsec-tp1.tv_nsec+1000000000*(tp2.tv_sec-tp1.tv_sec)); printf("Stop\n"); }
void sys_init_time(ErtsSysInitTimeResult *init_resp) { #if defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) int major, minor, build, vsn; #endif #if defined(ERTS_MACH_CLOCKS) mach_clocks_init(); #endif #if !defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) init_resp->have_os_monotonic_time = 0; #else /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */ #ifdef ERTS_HAVE_CORRECTED_OS_MONOTONIC_TIME init_resp->have_corrected_os_monotonic_time = 1; #else init_resp->have_corrected_os_monotonic_time = 0; #endif init_resp->os_monotonic_time_info.resolution = (Uint64) 1000*1000*1000; #if defined(HAVE_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID) { struct timespec ts; if (clock_getres(MONOTONIC_CLOCK_ID, &ts) == 0) { if (ts.tv_sec == 0 && ts.tv_nsec != 0) init_resp->os_monotonic_time_info.resolution /= ts.tv_nsec; else if (ts.tv_sec >= 1) init_resp->os_monotonic_time_info.resolution = 1; } } #elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID) init_resp->os_monotonic_time_info.resolution = mach_clock_getres(&internal_state.r.o.mach.clock.monotonic); #endif #ifdef MONOTONIC_CLOCK_ID_STR init_resp->os_monotonic_time_info.clock_id = MONOTONIC_CLOCK_ID_STR; #else init_resp->os_monotonic_time_info.clock_id = NULL; #endif init_resp->os_monotonic_time_info.locked_use = 0; #if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) init_resp->os_monotonic_time_info.func = "clock_gettime"; #elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) init_resp->os_monotonic_time_info.func = "clock_get_time"; #elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME) init_resp->os_monotonic_time_info.func = "gethrtime"; #elif defined(OS_MONOTONIC_TIME_USING_TIMES) init_resp->os_monotonic_time_info.func = "times"; #else # error Unknown erts_os_monotonic_time() implementation #endif init_resp->have_os_monotonic_time = 1; os_version(&major, &minor, &build); vsn = ERTS_MK_VSN_INT(major, minor, build); #if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) if (vsn >= ERTS_MK_VSN_INT(2, 6, 33)) { erts_sys_time_data__.r.o.os_monotonic_time = clock_gettime_monotonic; #if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) erts_sys_time_data__.r.o.os_times = clock_gettime_times; #endif } else { /* * Linux versions prior to 2.6.33 have a * known bug that sometimes cause the NTP * adjusted monotonic clock to take small * steps backwards. Use raw monotonic clock * if it is present; otherwise, fall back * on locked verification of values. */ init_resp->have_corrected_os_monotonic_time = 0; #if defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) /* We know that CLOCK_MONOTONIC_RAW is defined, but we don't know if we got a kernel that supports it. Support for CLOCK_MONOTONIC_RAW appeared in kernel 2.6.28... */ if (vsn >= ERTS_MK_VSN_INT(2, 6, 28)) { erts_sys_time_data__.r.o.os_monotonic_time = clock_gettime_monotonic_raw; #if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) erts_sys_time_data__.r.o.os_times = clock_gettime_times_raw; #endif init_resp->os_monotonic_time_info.clock_id = "CLOCK_MONOTONIC_RAW"; } else #endif /* defined(HAVE_CLOCK_GETTIME_MONOTONIC_RAW) */ { erts_sys_time_data__.r.o.os_monotonic_time = clock_gettime_monotonic_verified; #if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) erts_sys_time_data__.r.o.os_times = clock_gettime_times_verified; #endif erts_smp_mtx_init(&internal_state.w.f.mtx, "os_monotonic_time"); internal_state.w.f.last_delivered = clock_gettime_monotonic(); init_resp->os_monotonic_time_info.locked_use = 1; } } #else /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */ { char flavor[1024]; os_flavor(flavor, sizeof(flavor)); if (sys_strcmp(flavor, "sunos") == 0) { /* * Don't trust hrtime on multi processors * on SunOS prior to SunOS 5.8 */ if (vsn < ERTS_MK_VSN_INT(5, 8, 0)) { #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) if (sysconf(_SC_NPROCESSORS_CONF) > 1) #endif init_resp->have_os_monotonic_time = 0; } } } #endif /* !(defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)) */ #endif /* defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT) */ #ifdef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT init_resp->os_monotonic_time_unit = ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT; #endif init_resp->sys_clock_resolution = SYS_CLOCK_RESOLUTION; /* * This (erts_sys_time_data__.r.o.ticks_per_sec) is only for * times() (CLK_TCK), the resolution is always one millisecond.. */ if ((erts_sys_time_data__.r.o.ticks_per_sec = TICKS_PER_SEC()) < 0) erl_exit(ERTS_ABORT_EXIT, "Can't get clock ticks/sec\n"); #if defined(OS_MONOTONIC_TIME_USING_TIMES) #if ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT # error Time unit is supposed to be determined at runtime... #endif { ErtsMonotonicTime resolution = erts_sys_time_data__.r.o.ticks_per_sec; ErtsMonotonicTime time_unit = resolution; int shift = 0; while (time_unit < 1000*1000) { time_unit <<= 1; shift++; } init_resp->os_monotonic_time_info.resolution = resolution; init_resp->os_monotonic_time_unit = time_unit; init_resp->os_monotonic_time_info.extended = 1; internal_state.r.o.times_shift = shift; erts_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd, get_tick_count, (1 << 29) / resolution); } #endif /* defined(OS_MONOTONIC_TIME_USING_TIMES) */ #ifdef WALL_CLOCK_ID_STR init_resp->os_system_time_info.clock_id = WALL_CLOCK_ID_STR; #else init_resp->os_system_time_info.clock_id = NULL; #endif init_resp->os_system_time_info.locked_use = 0; init_resp->os_system_time_info.resolution = (Uint64) 1000*1000*1000; #if defined(HAVE_CLOCK_GETRES) && defined(WALL_CLOCK_ID) { struct timespec ts; if (clock_getres(WALL_CLOCK_ID, &ts) == 0) { if (ts.tv_sec == 0 && ts.tv_nsec != 0) init_resp->os_system_time_info.resolution /= ts.tv_nsec; else if (ts.tv_sec >= 1) init_resp->os_system_time_info.resolution = 1; } } #elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(WALL_CLOCK_ID) init_resp->os_system_time_info.resolution = mach_clock_getres(&internal_state.r.o.mach.clock.wall); #endif #if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) init_resp->os_system_time_info.func = "clock_gettime"; #elif defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) init_resp->os_system_time_info.func = "clock_get_time"; #elif defined(OS_SYSTEM_TIME_GETTIMEOFDAY) init_resp->os_system_time_info.func = "gettimeofday"; init_resp->os_system_time_info.resolution = 1000*1000; init_resp->os_system_time_info.clock_id = NULL; #else # error Missing erts_os_system_time() implementation #endif }
int main (void) { struct timespec ts; timer_t timer_sig, timer_thr1, timer_thr2; int retval; struct sigevent sigev1 = { .sigev_notify = SIGEV_SIGNAL, .sigev_signo = ZSIGALRM }; struct sigevent sigev2 = { .sigev_notify = SIGEV_THREAD, ._sigev_un = { ._sigev_thread = { ._function = notify_func } } }; struct itimerspec itimer1 = { { 0, 200000000 }, { 0, 200000000 } }; struct itimerspec itimer2 = { { 0, 100000000 }, { 0, 500000000 } }; struct itimerspec itimer3 = { { 0, 150000000 }, { 0, 300000000 } }; struct itimerspec old; retval = clock_gettime (CLOCK_REALTIME, &ts); setvbuf (stdout, 0, _IOLBF, 0); printf ("clock_gettime returned %d, timespec = { %ld, %ld }\n", retval, ts.tv_sec, ts.tv_nsec); retval = clock_getres (CLOCK_REALTIME, &ts); printf ("clock_getres returned %d, timespec = { %ld, %ld }\n", retval, ts.tv_sec, ts.tv_nsec); timer_create (CLOCK_REALTIME, &sigev1, &timer_sig); timer_create (CLOCK_REALTIME, &sigev2, &timer_thr1); timer_create (CLOCK_REALTIME, &sigev2, &timer_thr2); timer_settime (timer_thr1, 0, &itimer2, &old); timer_settime (timer_thr2, 0, &itimer3, &old); signal (ZSIGALRM, signal_func); timer_settime (timer_sig, 0, &itimer1, &old); timer_delete (-1); intr_sleep (3); timer_delete (timer_sig); timer_delete (timer_thr1); intr_sleep (3); timer_delete (timer_thr2); return 0; }