Revision: 23471 http://trac.macosforge.org/projects/launchd/changeset/23471 Author: zarzycki@apple.com Date: 2007-12-19 11:48:57 -0800 (Wed, 19 Dec 2007) Log Message: ----------- Both Mach and Unix time concepts are weird. We now use an 'int64_t' instead of 'struct timeval' for wall clock code. We now wrap the 'timebase info' logic required by Mach absolute time. Modified Paths: -------------- trunk/launchd/src/launchd.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/launchd_runtime.c trunk/launchd/src/launchd_runtime.h trunk/launchd/src/libvproc_internal.h Modified: trunk/launchd/src/launchd.c =================================================================== --- trunk/launchd/src/launchd.c 2007-12-19 18:13:19 UTC (rev 23470) +++ trunk/launchd/src/launchd.c 2007-12-19 19:48:57 UTC (rev 23471) @@ -245,7 +245,7 @@ void launchd_shutdown(void) { - struct timeval tvnow; + int64_t now; if (shutdown_in_progress) { return; @@ -264,10 +264,10 @@ runtime_log_push(); - if (launchd_assumes(gettimeofday(&tvnow, NULL) != -1)) { - runtime_syslog(LOG_NOTICE, "Shutdown began at: %lu.%06u", tvnow.tv_sec, tvnow.tv_usec); - } + now = runtime_get_wall_time(); + runtime_syslog(LOG_NOTICE, "Shutdown began at: %lld.%06llu", now / USEC_PER_SEC, now % USEC_PER_SEC); + launchd_assert(jobmgr_shutdown(root_jobmgr) != NULL); } Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2007-12-19 18:13:19 UTC (rev 23470) +++ trunk/launchd/src/launchd_core_logic.c 2007-12-19 19:48:57 UTC (rev 23471) @@ -23,7 +23,6 @@ #include <mach/mach.h> #include <mach/mach_error.h> -#include <mach/mach_time.h> #include <mach/boolean.h> #include <mach/message.h> #include <mach/notify.h> @@ -452,7 +451,6 @@ static size_t our_strhash(const char *s) __attribute__((pure)); static void extract_rcsid_substr(const char *i, char *o, size_t osz); static void do_first_per_user_launchd_hack(void); -static void do_file_init(void) __attribute__((constructor)); static void do_unmounts(void); /* file local globals */ @@ -463,7 +461,6 @@ #define JOB_BOOTCACHE_HACK_CHECK(j) (j->per_user && !did_first_per_user_launchd_BootCache_hack && (j->mach_uid >= 500) && (j->mach_uid != (uid_t)-2)) static jobmgr_t background_jobmgr; static job_t workaround_5477111; -static mach_timebase_info_data_t tbi; /* process wide globals */ mach_port_t inherited_bootstrap_port; @@ -539,7 +536,7 @@ } job_assumes(j, runtime_kill(j->p, SIGTERM) != -1); - j->sent_sigterm_time = mach_absolute_time(); + j->sent_sigterm_time = runtime_get_opaque_time(); if (j->exit_timeout) { job_assumes(j, kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, @@ -2150,7 +2147,7 @@ } if (j->sent_sigterm_time) { - uint64_t td_sec, td_usec, td = (mach_absolute_time() - j->sent_sigterm_time) * tbi.numer / tbi.denom; + uint64_t td_sec, td_usec, td = runtime_opaque_time_to_nano(runtime_get_opaque_time() - j->sent_sigterm_time); td_sec = td / NSEC_PER_SEC; td_usec = (td % NSEC_PER_SEC) / NSEC_PER_USEC; @@ -2432,7 +2429,7 @@ job_dispatch(j, false); } else if (&j->exit_timeout == ident) { if (j->sent_sigkill) { - uint64_t td = (mach_absolute_time() - j->sent_sigterm_time) * tbi.numer / tbi.denom; + uint64_t td = runtime_opaque_time_to_nano(runtime_get_opaque_time() - j->sent_sigterm_time); td /= NSEC_PER_SEC; td -= j->exit_timeout; @@ -2481,7 +2478,6 @@ void jobmgr_callback(void *obj, struct kevent *kev) { - struct timeval tvnow; jobmgr_t jm = obj; job_t ji; @@ -2504,8 +2500,11 @@ runtime_closelog(); /* HACK -- force 'start' time to be set */ - if (getpid() == 1 && jobmgr_assumes(jm, gettimeofday(&tvnow, NULL) != -1)) { - jobmgr_log(jm, LOG_NOTICE, "Anticipatory shutdown began at: %lu.%06u", tvnow.tv_sec, tvnow.tv_usec); + if (getpid() == 1) { + int64_t now = runtime_get_wall_time(); + + jobmgr_log(jm, LOG_NOTICE, "Anticipatory shutdown began at: %lld.%06llu", now / USEC_PER_SEC, now % USEC_PER_SEC); + LIST_FOREACH(ji, &root_jobmgr->jobs, sle) { if (ji->per_user && ji->p) { job_assumes(ji, runtime_kill(ji->p, SIGUSR2) != -1); @@ -2562,7 +2561,7 @@ void job_start(job_t j) { - uint64_t td, tnow = mach_absolute_time(); + uint64_t td, tnow = runtime_get_opaque_time(); int spair[2]; int execspair[2]; int oepair[2]; @@ -2584,10 +2583,10 @@ /* * Some users adjust the wall-clock and then expect software to not notice. - * Therefore, launchd must use an absolute clock instead of gettimeofday() - * or time() wherever possible. + * Therefore, launchd must use an absolute clock instead of the wall clock + * wherever possible. */ - td = (tnow - j->start_time) * tbi.numer / tbi.denom; + td = runtime_opaque_time_to_nano(tnow - j->start_time); td /= NSEC_PER_SEC; if (j->start_time && (td < j->min_run_time) && !j->legacy_mach_job && !j->inetcompat) { @@ -6737,13 +6736,6 @@ } void -do_file_init(void) -{ - launchd_assert(mach_timebase_info(&tbi) == 0); - -} - -void do_unmounts(void) { struct statfs buf[250]; Modified: trunk/launchd/src/launchd_runtime.c =================================================================== --- trunk/launchd/src/launchd_runtime.c 2007-12-19 18:13:19 UTC (rev 23470) +++ trunk/launchd/src/launchd_runtime.c 2007-12-19 19:48:57 UTC (rev 23471) @@ -33,6 +33,7 @@ #include <mach/mach_interface.h> #include <mach/host_info.h> #include <mach/mach_host.h> +#include <mach/mach_time.h> #include <mach/exception.h> #include <sys/types.h> #include <sys/stat.h> @@ -109,6 +110,8 @@ static bool logmsg_add(struct runtime_syslog_attr *attr, int err_num, const char *msg); static void logmsg_remove(struct logmsg_s *lm); +static void do_file_init(void) __attribute__((constructor)); +static mach_timebase_info_data_t tbi; static const int sigigns[] = { SIGHUP, SIGINT, SIGPIPE, SIGALRM, SIGTERM, SIGURG, SIGTSTP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, @@ -1209,7 +1212,7 @@ data_off = lm->data; - launchd_assumes(gettimeofday(&lm->when, NULL) != -1); + lm->when = runtime_get_wall_time(); lm->from_pid = attr->from_pid; lm->about_pid = attr->about_pid; lm->err_num = err_num; @@ -1307,8 +1310,7 @@ runtime_log_push(void) { static pthread_mutex_t ourlock = PTHREAD_MUTEX_INITIALIZER; - static struct timeval shutdown_start; - struct timeval tvd; + static int64_t shutdown_start, log_delta; mach_msg_type_number_t outvalCnt; struct logmsg_s *lm; vm_offset_t outval; @@ -1329,8 +1331,8 @@ return; } - if (shutdown_start.tv_sec == 0) { - gettimeofday(&shutdown_start, NULL); + if (shutdown_start == 0) { + shutdown_start = runtime_get_wall_time(); launchd_log_vm_stats(); } @@ -1349,15 +1351,9 @@ } while ((lm = STAILQ_FIRST(&logmsg_queue))) { - timersub(&lm->when, &shutdown_start, &tvd); + log_delta = lm->when - shutdown_start; - /* don't ask */ - if (tvd.tv_sec < 0) { - tvd.tv_sec = 0; - tvd.tv_usec = 0; - } - - fprintf(ourlogfile, "%3ld.%06d%6u %-40s%6u %-40s %s\n", tvd.tv_sec, tvd.tv_usec, + fprintf(ourlogfile, "%8lld%6u %-40s%6u %-40s %s\n", log_delta, lm->from_pid, lm->from_name, lm->about_pid, lm->about_name, lm->msg); logmsg_remove(lm); @@ -1550,3 +1546,55 @@ return (apple_internal_logging == 0); } + +int64_t +runtime_get_wall_time(void) +{ + struct timeval tv; + int64_t r; + + launchd_assumes(gettimeofday(&tv, NULL) != -1); + + r = tv.tv_sec; + r *= USEC_PER_SEC; + r += tv.tv_usec; + + return r; +} + +uint64_t +runtime_get_opaque_time(void) +{ + return mach_absolute_time(); +} + +uint64_t +runtime_opaque_time_to_nano(uint64_t o) +{ +#if defined(__i386__) + if (unlikely(tbi.numer != tbi.denom)) { +#elif defined(__ppc__) + if (likely(tbi.numer != tbi.denom)) { +#else + if (tbi.numer != tbi.denom) { +#endif + if (o < INT32_MAX) { + o *= tbi.numer; + o /= tbi.denom; + } else { + double d = o; + d *= tbi.numer; + d /= tbi.denom; + o = d; + } + } + + return o; +} + +void +do_file_init(void) +{ + launchd_assert(mach_timebase_info(&tbi) == 0); +} + Modified: trunk/launchd/src/launchd_runtime.h =================================================================== --- trunk/launchd/src/launchd_runtime.h 2007-12-19 18:13:19 UTC (rev 23470) +++ trunk/launchd/src/launchd_runtime.h 2007-12-19 19:48:57 UTC (rev 23471) @@ -70,6 +70,8 @@ #endif +#define likely(x) __builtin_expect((bool)(x), true) +#define unlikely(x) __builtin_expect((bool)(x), false) struct ldcred { uid_t euid; @@ -151,7 +153,11 @@ void runtime_vsyslog(struct runtime_syslog_attr *attr, const char *message, va_list args) __attribute__((format(printf, 2, 0))); void runtime_log_push(void); +int64_t runtime_get_wall_time(void); +uint64_t runtime_get_opaque_time(void); +uint64_t runtime_opaque_time_to_nano(uint64_t o); + kern_return_t launchd_set_bport(mach_port_t name); kern_return_t launchd_get_bport(mach_port_t *name); kern_return_t launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which); Modified: trunk/launchd/src/libvproc_internal.h =================================================================== --- trunk/launchd/src/libvproc_internal.h 2007-12-19 18:13:19 UTC (rev 23470) +++ trunk/launchd/src/libvproc_internal.h 2007-12-19 19:48:57 UTC (rev 23471) @@ -59,7 +59,7 @@ struct logmsg_s { STAILQ_ENTRY(logmsg_s) sqe; - struct timeval when; + int64_t when; pid_t from_pid; pid_t about_pid; uid_t sender_uid;