tools/time.c
changeset 16 33aaaec59991
parent 6 20f80c019d73
child 998 3f6ed23e8aae
equal deleted inserted replaced
15:21f7a7ab78ba 16:33aaaec59991
    21  * Copyright (c) 2010, Oracle and/or it's affiliates.  All rights reserved.
    21  * Copyright (c) 2010, Oracle and/or it's affiliates.  All rights reserved.
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * This compiles to a module that can be preloaded during a build.  If this
    25  * This compiles to a module that can be preloaded during a build.  If this
    26  * is preloaded, it interposes on time(2) and returns a constant value when
    26  * is preloaded, it interposes on time(2), gettimeofday(3C), and
    27  * the execname matches one of the desired "programs" and TIME_CONSTANT
    27  * clock_gethrtime(3C) and returns a constant number of seconds since epoch
       
    28  * when the execname matches one of the desired "programs" and TIME_CONSTANT
    28  * contains an integer value to be returned.
    29  * contains an integer value to be returned.
    29  */
    30  */
    30 
    31 
    31 #include <stdlib.h>
    32 #include <stdlib.h>
    32 #include <ucontext.h>
    33 #include <ucontext.h>
    33 #include <dlfcn.h>
    34 #include <dlfcn.h>
    34 #include <strings.h>
    35 #include <strings.h>
       
    36 #include <time.h>
    35 
    37 
    36 /* The list of programs that we want to use a constant time. */
    38 /* The list of programs that we want to use a constant time. */
    37 static char *programs[] = { "date", "cpp", "cc1", "perl", NULL };
    39 static char *programs[] = { "autogen", "bash", "cpp", "cc1", "date", "doxygen",
       
    40 	"erl", "javadoc", "ksh", "ksh93", "ld", "perl", "perl5.8.4", "perl5.10",
       
    41 	"ruby", "sh", NULL };
    38 
    42 
    39 static int
    43 static int
    40 stack_info(uintptr_t pc, int signo, void *arg)
    44 stack_info(uintptr_t pc, int signo, void *arg)
    41 {
    45 {
    42 	Dl_info info;
    46 	Dl_info info;
    43 	void *sym;
    47 	void *sym;
    44 
    48 
    45 	if (dladdr1((void *)pc, &info, &sym, RTLD_DL_SYMENT) != NULL) {
    49 	if (dladdr1((void *)pc, &info, &sym, RTLD_DL_SYMENT) != NULL) {
    46 		*(char **)arg = (char *)info.dli_fname;
    50 		if (strstr(info.dli_fname, ".so") == NULL)
       
    51 			*(char **)arg = (char *)info.dli_fname;
    47 	}
    52 	}
    48 
    53 
    49 	return (0);
    54 	return (0);
    50 }
    55 }
    51 
    56 
    70 
    75 
    71 	return (execname);
    76 	return (execname);
    72 }
    77 }
    73 
    78 
    74 static time_t
    79 static time_t
    75 intercept()
    80 time_constant()
    76 {
    81 {
    77 	char *execname = my_execname();
    82 	char *execname = my_execname();
    78 	time_t result = -1;
    83 	time_t result = -1;
    79 
    84 
    80 	if (execname != NULL) {
    85 	if (execname != NULL) {
    81 		int i;
    86 		int i;
    82 
    87 
    83 		for (i = 0; programs[i] != NULL; i++)
    88 		for (i = 0; programs[i] != NULL; i++)
    84 			if (strcmp(execname, programs[i]) == 0) {
    89 			if (strcmp(execname, programs[i]) == 0) {
    85 				static char *time_constant;
    90 				static char *time_string;
    86 
    91 
    87 				if (time_constant == NULL)
    92 				if (time_string == NULL)
    88 					time_constant = getenv("TIME_CONSTANT");
    93 					time_string = getenv("TIME_CONSTANT");
    89 
    94 
    90 				if (time_constant != NULL)
    95 				if (time_string != NULL)
    91 					result = atoll(time_constant);
    96 					result = atoll(time_string);
    92 
    97 
    93 				break;
    98 				break;
    94 			}
    99 			}
    95 	}
   100 	}
    96 
   101 
    98 }
   103 }
    99 
   104 
   100 time_t
   105 time_t
   101 time(time_t *ptr)
   106 time(time_t *ptr)
   102 {
   107 {
   103 	time_t result = intercept();
   108 	time_t result = time_constant();
   104 
   109 
   105 	if (result == (time_t)-1) {
   110 	if (result == (time_t)-1) {
   106 		static time_t (*fptr)(time_t *);
   111 		static time_t (*fptr)(time_t *);
   107 
   112 
   108 		if (fptr == NULL)
   113 		if (fptr == NULL)
   112 	} else if (ptr != NULL)
   117 	} else if (ptr != NULL)
   113 			*ptr = result;
   118 			*ptr = result;
   114 
   119 
   115 	return (result);
   120 	return (result);
   116 }
   121 }
       
   122 
       
   123 int
       
   124 gettimeofday(struct timeval *tp, void *tzp)
       
   125 {
       
   126 	static int (*fptr)(struct timeval *, void *);
       
   127 	int result = -1;
       
   128 
       
   129 	if (fptr == NULL)
       
   130 		fptr = (int (*)(struct timeval *, void *))dlsym(RTLD_NEXT,
       
   131 				"gettimeofday");
       
   132 
       
   133 	if ((result = (fptr)(tp, tzp)) == 0) {
       
   134 		time_t curtime = time_constant();
       
   135 
       
   136 		if (curtime != (time_t)-1)
       
   137 			tp->tv_sec = curtime;
       
   138 	}
       
   139 
       
   140 	return (result);
       
   141 }
       
   142 
       
   143 int
       
   144 clock_gettime(clockid_t clock_id, struct timespec *tp)
       
   145 {
       
   146 	static int (*fptr)(clockid_t, struct timespec *);
       
   147 	int result = -1;
       
   148 
       
   149 	if (fptr == NULL)
       
   150 		fptr = (int (*)(clockid_t, struct timespec *))dlsym(RTLD_NEXT,
       
   151 				"clock_gettime");
       
   152 
       
   153 	if ((result = (fptr)(clock_id, tp)) == 0) {
       
   154 		time_t curtime = time_constant();
       
   155 
       
   156 		if (curtime != (time_t)-1)
       
   157 			tp->tv_sec = curtime;
       
   158 	}
       
   159 
       
   160 	return (result);
       
   161 }