1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of Oracle nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * This source code is provided to illustrate the usage of a given feature
34 * or technique and has been deliberately simplified. Additional steps
35 * required for a production-quality application, such as security checks,
36 * input validation and proper error handling, might not be present in
37 * this sample code.
38 */
39
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44
45 #if !defined(LINUX) && !defined(_ALLBSD_SOURCE)
46 #include <procfs.h>
47 #endif
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <sys/socket.h>
53 #include <sys/errno.h>
54 #include <unistd.h>
55 #include <errno.h>
56 #include <dlfcn.h>
57 #include <sys/time.h>
58
59 #include <netdb.h>
60 #include <netinet/in.h>
61 #include <sys/param.h>
62 #include <time.h>
63
64 #include "jni.h"
65 #include "jvm_md.h"
66 #include "hprof.h"
67
68 int
69 md_getpid(void)
70 {
71 static int pid = -1;
72
73 if ( pid >= 0 ) {
74 return pid;
75 }
76 pid = getpid();
77 return pid;
78 }
79
80 void
81 md_sleep(unsigned seconds)
82 {
83 sleep(seconds);
84 }
85
86 void
87 md_init(void)
88 {
89 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
90 /* No Hi-Res timer option? */
91 #else
92 if ( gdata->micro_state_accounting ) {
93 char proc_ctl_fn[48];
94 int procfd;
95
96 /* Turn on micro state accounting, once per process */
97 (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
98 "/proc/%d/ctl", md_getpid());
99
100 procfd = open(proc_ctl_fn, O_WRONLY);
101 if (procfd >= 0) {
102 long ctl_op[2];
103
104 ctl_op[0] = PCSET;
105 ctl_op[1] = PR_MSACCT;
106 (void)write(procfd, ctl_op, sizeof(ctl_op));
107 (void)close(procfd);
108 }
109 }
236 return res;
237 }
238
239 /* Time of day in milli-seconds */
240 static jlong
241 md_timeofday(void)
242 {
243 struct timeval tv;
244
245 if ( gettimeofday(&tv, (void *)0) != 0 ) {
246 return (jlong)0; /* EOVERFLOW ? */
247 }
248 /*LINTED*/
249 return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
250 }
251
252 /* Hi-res timer in micro-seconds */
253 jlong
254 md_get_microsecs(void)
255 {
256 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
257 return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
258 #else
259 return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
260 #endif
261 }
262
263 /* Time of day in milli-seconds */
264 jlong
265 md_get_timemillis(void)
266 {
267 return md_timeofday();
268 }
269
270 /* Current CPU hi-res CPU time used */
271 jlong
272 md_get_thread_cpu_timemillis(void)
273 {
274 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
275 return md_timeofday();
276 #else
277 return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
278 #endif
279 }
280
281 void
282 md_get_prelude_path(char *path, int path_len, char *filename)
283 {
284 void *addr;
285 char libdir[FILENAME_MAX+1];
286 Dl_info dlinfo;
287
288 libdir[0] = 0;
289 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
290 addr = (void*)&Agent_OnLoad;
291 #else
292 /* Just using &Agent_OnLoad will get the first external symbol with
293 * this name in the first .so, which may not be libhprof.so.
294 * On Solaris we can actually ask for the address of our Agent_OnLoad.
295 */
296 addr = dlsym(RTLD_SELF, "Agent_OnLoad");
297 /* Just in case the above didn't work (missing linker patch?). */
298 if ( addr == NULL ) {
299 addr = (void*)&Agent_OnLoad;
300 }
301 #endif
302
303 /* Use dladdr() to get the full path to libhprof.so, which we use to find
304 * the prelude file.
305 */
306 dlinfo.dli_fname = NULL;
307 (void)dladdr(addr, &dlinfo);
308 if ( dlinfo.dli_fname != NULL ) {
309 char * lastSlash;
440 }
441 return result;
442 }
443
444 /* Unload this library */
445 void
446 md_unload_library(void *handle)
447 {
448 (void)dlclose(handle);
449 }
450
451 /* Find an entry point inside this library (return NULL if not found) */
452 void *
453 md_find_library_entry(void *handle, const char *name)
454 {
455 void * sym;
456
457 sym = dlsym(handle, name);
458 return sym;
459 }
|
1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of Oracle nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * This source code is provided to illustrate the usage of a given feature
34 * or technique and has been deliberately simplified. Additional steps
35 * required for a production-quality application, such as security checks,
36 * input validation and proper error handling, might not be present in
37 * this sample code.
38 */
39
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44
45 #if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX)
46 #include <procfs.h>
47 #endif
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <sys/socket.h>
53 #include <sys/errno.h>
54 #include <unistd.h>
55 #include <errno.h>
56 #include <dlfcn.h>
57 #include <sys/time.h>
58
59 #include <netdb.h>
60 #include <netinet/in.h>
61 #include <sys/param.h>
62 #include <time.h>
63
64 #include "jni.h"
65 #include "jvm_md.h"
66 #include "hprof.h"
67
68 #ifdef AIX
69 #include "porting_aix.h" /* For the 'dladdr' function. */
70 #endif
71
72 int
73 md_getpid(void)
74 {
75 static int pid = -1;
76
77 if ( pid >= 0 ) {
78 return pid;
79 }
80 pid = getpid();
81 return pid;
82 }
83
84 void
85 md_sleep(unsigned seconds)
86 {
87 sleep(seconds);
88 }
89
90 void
91 md_init(void)
92 {
93 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
94 /* No Hi-Res timer option? */
95 #else
96 if ( gdata->micro_state_accounting ) {
97 char proc_ctl_fn[48];
98 int procfd;
99
100 /* Turn on micro state accounting, once per process */
101 (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
102 "/proc/%d/ctl", md_getpid());
103
104 procfd = open(proc_ctl_fn, O_WRONLY);
105 if (procfd >= 0) {
106 long ctl_op[2];
107
108 ctl_op[0] = PCSET;
109 ctl_op[1] = PR_MSACCT;
110 (void)write(procfd, ctl_op, sizeof(ctl_op));
111 (void)close(procfd);
112 }
113 }
240 return res;
241 }
242
243 /* Time of day in milli-seconds */
244 static jlong
245 md_timeofday(void)
246 {
247 struct timeval tv;
248
249 if ( gettimeofday(&tv, (void *)0) != 0 ) {
250 return (jlong)0; /* EOVERFLOW ? */
251 }
252 /*LINTED*/
253 return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
254 }
255
256 /* Hi-res timer in micro-seconds */
257 jlong
258 md_get_microsecs(void)
259 {
260 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
261 return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
262 #else
263 return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
264 #endif
265 }
266
267 /* Time of day in milli-seconds */
268 jlong
269 md_get_timemillis(void)
270 {
271 return md_timeofday();
272 }
273
274 /* Current CPU hi-res CPU time used */
275 jlong
276 md_get_thread_cpu_timemillis(void)
277 {
278 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
279 return md_timeofday();
280 #else
281 return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
282 #endif
283 }
284
285 void
286 md_get_prelude_path(char *path, int path_len, char *filename)
287 {
288 void *addr;
289 char libdir[FILENAME_MAX+1];
290 Dl_info dlinfo;
291
292 libdir[0] = 0;
293 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
294 addr = (void*)&Agent_OnLoad;
295 #else
296 /* Just using &Agent_OnLoad will get the first external symbol with
297 * this name in the first .so, which may not be libhprof.so.
298 * On Solaris we can actually ask for the address of our Agent_OnLoad.
299 */
300 addr = dlsym(RTLD_SELF, "Agent_OnLoad");
301 /* Just in case the above didn't work (missing linker patch?). */
302 if ( addr == NULL ) {
303 addr = (void*)&Agent_OnLoad;
304 }
305 #endif
306
307 /* Use dladdr() to get the full path to libhprof.so, which we use to find
308 * the prelude file.
309 */
310 dlinfo.dli_fname = NULL;
311 (void)dladdr(addr, &dlinfo);
312 if ( dlinfo.dli_fname != NULL ) {
313 char * lastSlash;
444 }
445 return result;
446 }
447
448 /* Unload this library */
449 void
450 md_unload_library(void *handle)
451 {
452 (void)dlclose(handle);
453 }
454
455 /* Find an entry point inside this library (return NULL if not found) */
456 void *
457 md_find_library_entry(void *handle, const char *name)
458 {
459 void * sym;
460
461 sym = dlsym(handle, name);
462 return sym;
463 }
464
465
|