📄 erl_time_sup.c
字号:
return CLOCK_RESOLUTION;} /* info functions */void elapsed_time_both(unsigned long *ms_user, unsigned long *ms_sys, unsigned long *ms_user_diff, unsigned long *ms_sys_diff){ unsigned long prev_total_user, prev_total_sys; unsigned long total_user, total_sys; SysTimes now; sys_times(&now); total_user = (now.tms_utime * 1000) / SYS_CLK_TCK; total_sys = (now.tms_stime * 1000) / SYS_CLK_TCK; if (ms_user != NULL) *ms_user = total_user; if (ms_sys != NULL) *ms_sys = total_sys; erts_smp_mtx_lock(&erts_timeofday_mtx); prev_total_user = (t_start.tms_utime * 1000) / SYS_CLK_TCK; prev_total_sys = (t_start.tms_stime * 1000) / SYS_CLK_TCK; t_start = now; erts_smp_mtx_unlock(&erts_timeofday_mtx); if (ms_user_diff != NULL) *ms_user_diff = total_user - prev_total_user; if (ms_sys_diff != NULL) *ms_sys_diff = total_sys - prev_total_sys;}/* wall clock routines */void wall_clock_elapsed_time_both(unsigned long *ms_total, unsigned long *ms_diff){ unsigned long prev_total; SysTimeval tv; erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(&tv); *ms_total = 1000 * (tv.tv_sec - inittv.tv_sec) + (tv.tv_usec - inittv.tv_usec) / 1000; prev_total = 1000 * (gtv.tv_sec - inittv.tv_sec) + (gtv.tv_usec - inittv.tv_usec) / 1000; *ms_diff = *ms_total - prev_total; gtv = tv; /* must sync the machine's idea of time here */ do_erts_deliver_time(&tv); erts_smp_mtx_unlock(&erts_timeofday_mtx);}/* get current time */void get_time(int *hour, int *minute, int *second){ time_t the_clock; struct tm *tm;#ifdef HAVE_LOCALTIME_R struct tm tmbuf;#endif the_clock = time((time_t *)0);#ifdef HAVE_LOCALTIME_R localtime_r(&the_clock, (tm = &tmbuf));#else tm = localtime(&the_clock);#endif *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec;}/* get current date */void get_date(int *year, int *month, int *day){ time_t the_clock; struct tm *tm;#ifdef HAVE_LOCALTIME_R struct tm tmbuf;#endif the_clock = time((time_t *)0);#ifdef HAVE_LOCALTIME_R localtime_r(&the_clock, (tm = &tmbuf));#else tm = localtime(&the_clock);#endif *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday;}/* get localtime */void get_localtime(int *year, int *month, int *day, int *hour, int *minute, int *second){ time_t the_clock; struct tm *tm;#ifdef HAVE_LOCALTIME_R struct tm tmbuf;#endif the_clock = time((time_t *)0);#ifdef HAVE_LOCALTIME_R localtime_r(&the_clock, (tm = &tmbuf));#else tm = localtime(&the_clock);#endif *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec;}/* get universaltime */void get_universaltime(int *year, int *month, int *day, int *hour, int *minute, int *second){ time_t the_clock; struct tm *tm;#ifdef HAVE_GMTIME_R struct tm tmbuf;#endif the_clock = time((time_t *)0);#ifdef HAVE_GMTIME_R gmtime_r(&the_clock, (tm = &tmbuf));#else tm = gmtime(&the_clock);#endif *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec;}/* days in month = 1, 2, ..., 12 */static const int mdays[14] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};#define IN_RANGE(a,x,b) (((a) <= (x)) && ((x) <= (b)))#define is_leap_year(y) (((((y) % 4) == 0) && \ (((y) % 100) != 0)) || \ (((y) % 400) == 0))#define BASEYEAR 1970/* * gregday * * Returns the number of days since Jan 1, 1600, if year is * greater of equal to 1600 , and month [1-12] and day [1-31] * are within range. Otherwise it returns -1. */static int long gregday(int year, int month, int day){ int long ndays = 0; int gyear, pyear, m; /* number of days in previous years */ gyear = year - 1600; if (gyear > 0) { pyear = gyear - 1; ndays = (pyear/4) - (pyear/100) + (pyear/400) + pyear*365 + 366; } /* number of days in all months preceeding month */ for (m = 1; m < month; m++) ndays += mdays[m]; /* Extra day if leap year and March or later */ if (is_leap_year(year) && (month > 2)) ndays++; ndays += day - 1; return ndays - 135140; /* 135140 = Jan 1, 1970 */}int local_to_univ(Sint *year, Sint *month, Sint *day, Sint *hour, Sint *minute, Sint *second, int isdst){ time_t the_clock; struct tm *tm, t;#ifdef HAVE_GMTIME_R struct tm tmbuf;#endif if (!(IN_RANGE(BASEYEAR, *year, INT_MAX - 1) && IN_RANGE(1, *month, 12) && IN_RANGE(1, *day, (mdays[*month] + (*month == 2 && (*year % 4 == 0) && (*year % 100 != 0 || *year % 400 == 0)))) && IN_RANGE(0, *hour, 23) && IN_RANGE(0, *minute, 59) && IN_RANGE(0, *second, 59))) { return 0; } t.tm_year = *year - 1900; t.tm_mon = *month - 1; t.tm_mday = *day; t.tm_hour = *hour; t.tm_min = *minute; t.tm_sec = *second; t.tm_isdst = isdst; the_clock = mktime(&t);#ifdef HAVE_GMTIME_R gmtime_r(&the_clock, (tm = &tmbuf));#else tm = gmtime(&the_clock);#endif *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec; return 1;}int univ_to_local(Sint *year, Sint *month, Sint *day, Sint *hour, Sint *minute, Sint *second){ time_t the_clock; struct tm *tm;#ifdef HAVE_LOCALTIME_R struct tm tmbuf;#endif if (!(IN_RANGE(BASEYEAR, *year, INT_MAX - 1) && IN_RANGE(1, *month, 12) && IN_RANGE(1, *day, (mdays[*month] + (*month == 2 && (*year % 4 == 0) && (*year % 100 != 0 || *year % 400 == 0)))) && IN_RANGE(0, *hour, 23) && IN_RANGE(0, *minute, 59) && IN_RANGE(0, *second, 59))) { return 0; } the_clock = *second + 60 * (*minute + 60 * (*hour + 24 * gregday(*year, *month, *day)));#ifdef HAVE_LOCALTIME_R localtime_r(&the_clock, (tm = &tmbuf));#else tm = localtime(&the_clock);#endif *year = tm->tm_year + 1900; *month = tm->tm_mon +1; *day = tm->tm_mday; *hour = tm->tm_hour; *minute = tm->tm_min; *second = tm->tm_sec; return 1;}/* get a timestamp */voidget_now(Uint* megasec, Uint* sec, Uint* microsec){ SysTimeval now; erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(&now); do_erts_deliver_time(&now); /* Make sure time is later than last */ if (then.tv_sec > now.tv_sec || (then.tv_sec == now.tv_sec && then.tv_usec >= now.tv_usec)) { now = then; now.tv_usec++; } /* Check for carry from above + general reasonability */ if (now.tv_usec >= 1000000) { now.tv_usec = 0; now.tv_sec++; } then = now; erts_smp_mtx_unlock(&erts_timeofday_mtx); *megasec = (Uint) (now.tv_sec / 1000000); *sec = (Uint) (now.tv_sec % 1000000); *microsec = (Uint) (now.tv_usec);}/* deliver elapsed *ticks* to the machine - takes a pointer to a struct timeval representing current time (to save a gettimeofday() where possible) or NULL */#if !defined(ERTS_TIMER_THREAD)void erts_deliver_time(void) { SysTimeval now; erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(&now); do_erts_deliver_time(&now); erts_smp_mtx_unlock(&erts_timeofday_mtx);}#endif/* get *real* time (not ticks) remaining until next timeout - if there isn't one, give a "long" time, that is guaranteed to not cause overflow when we report elapsed time later on */void erts_time_remaining(SysTimeval *rem_time){ int ticks;#if !defined(ERTS_TIMER_THREAD) SysTimeval cur_time;#endif long elapsed; /* next_time() returns no of ticks to next timeout or -1 if none */ if ((ticks = next_time()) == -1) { /* timer queue empty */ /* this will cause at most 100000000 ticks */ rem_time->tv_sec = 100000; rem_time->tv_usec = 0; } else { /* next timeout after ticks ticks */ ticks *= CLOCK_RESOLUTION; #if defined(ERTS_TIMER_THREAD) elapsed = 0;#else erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(&cur_time); cur_time.tv_usec = 1000 * (cur_time.tv_usec / 1000);/* ms resolution*/ elapsed = 1000 * (cur_time.tv_sec - last_delivered.tv_sec) + (cur_time.tv_usec - last_delivered.tv_usec) / 1000; erts_smp_mtx_unlock(&erts_timeofday_mtx); if (ticks <= elapsed) { /* Ooops, better hurry */ rem_time->tv_sec = rem_time->tv_usec = 0; return; }#endif rem_time->tv_sec = (ticks - elapsed) / 1000; rem_time->tv_usec = 1000 * ((ticks - elapsed) % 1000); }}#if defined(ERTS_TIMER_THREAD)void erts_get_timeval(SysTimeval *tv){ erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(tv); erts_smp_mtx_unlock(&erts_timeofday_mtx);}#endiflongerts_get_time(void){ SysTimeval sys_tv; erts_smp_mtx_lock(&erts_timeofday_mtx); get_tolerant_timeofday(&sys_tv); erts_smp_mtx_unlock(&erts_timeofday_mtx); return sys_tv.tv_sec;}#ifdef HAVE_ERTS_NOW_CPUvoid erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec) { SysCpuTime t; SysTimespec tp; sys_get_proc_cputime(t, tp); *microsec = (Uint)(tp.tv_nsec / 1000); t = (tp.tv_sec / 1000000); *megasec = (Uint)(t % 1000000); *sec = (Uint)(tp.tv_sec % 1000000);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -