X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=c0bb031e9dc02f48d9cc5fdb425826fbe84907ba;hb=25683b5a7d8178d42cb33f9f060a5b9f2aa45d5c;hp=901ddb036771d77ff7ab1c2f723c98db7f895bbb;hpb=32bd4678460f5a6d724ca5f4470314bbe63c0429;p=lttng-tools.git diff --git a/src/common/utils.c b/src/common/utils.c index 901ddb036..c0bb031e9 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -41,6 +41,7 @@ #include "utils.h" #include "defaults.h" +#include "time.h" /* * Return a partial realpath(3) of the path even if the full path does not @@ -528,7 +529,7 @@ int utils_create_lock_file(const char *filepath) S_IRGRP | S_IWGRP); if (fd < 0) { PERROR("open lock file %s", filepath); - ret = -1; + fd = -1; goto error; } @@ -854,6 +855,7 @@ int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size, PERROR("Closing tracefile"); goto error; } + *stream_fd = -1; if (count > 0) { /* @@ -1016,6 +1018,59 @@ static inline unsigned int fls_u32(uint32_t x) #define HAS_FLS_U32 #endif +#if defined(__x86_64) +static inline +unsigned int fls_u64(uint64_t x) +{ + long r; + + asm("bsrq %1,%0\n\t" + "jnz 1f\n\t" + "movq $-1,%0\n\t" + "1:\n\t" + : "=r" (r) : "rm" (x)); + return r + 1; +} +#define HAS_FLS_U64 +#endif + +#ifndef HAS_FLS_U64 +static __attribute__((unused)) +unsigned int fls_u64(uint64_t x) +{ + unsigned int r = 64; + + if (!x) + return 0; + + if (!(x & 0xFFFFFFFF00000000ULL)) { + x <<= 32; + r -= 32; + } + if (!(x & 0xFFFF000000000000ULL)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xFF00000000000000ULL)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xF000000000000000ULL)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xC000000000000000ULL)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x8000000000000000ULL)) { + x <<= 1; + r -= 1; + } + return r; +} +#endif + #ifndef HAS_FLS_U32 static __attribute__((unused)) unsigned int fls_u32(uint32_t x) { @@ -1062,6 +1117,20 @@ int utils_get_count_order_u32(uint32_t x) return fls_u32(x - 1); } +/* + * Return the minimum order for which x <= (1UL << order). + * Return -1 if x is 0. + */ +LTTNG_HIDDEN +int utils_get_count_order_u64(uint64_t x) +{ + if (!x) { + return -1; + } + + return fls_u64(x - 1); +} + /** * Obtain the value of LTTNG_HOME environment variable, if exists. * Otherwise returns the value of HOME. @@ -1134,26 +1203,6 @@ end: return home_dir; } -/* - * Obtain the value of LTTNG_KMOD_PROBES environment variable, if exists. - * Otherwise returns NULL. - */ -LTTNG_HIDDEN -char *utils_get_kmod_probes_list(void) -{ - return lttng_secure_getenv(DEFAULT_LTTNG_KMOD_PROBES); -} - -/* - * Obtain the value of LTTNG_EXTRA_KMOD_PROBES environment variable, if - * exists. Otherwise returns NULL. - */ -LTTNG_HIDDEN -char *utils_get_extra_kmod_probes_list(void) -{ - return lttng_secure_getenv(DEFAULT_LTTNG_EXTRA_KMOD_PROBES); -} - /* * With the given format, fill dst with the time of len maximum siz. * @@ -1334,15 +1383,17 @@ LTTNG_HIDDEN int utils_truncate_stream_file(int fd, off_t length) { int ret; + off_t lseek_ret; ret = ftruncate(fd, length); if (ret < 0) { PERROR("ftruncate"); goto end; } - ret = lseek(fd, length, SEEK_SET); - if (ret < 0) { + lseek_ret = lseek(fd, length, SEEK_SET); + if (lseek_ret < 0) { PERROR("lseek"); + ret = -1; goto end; } end: @@ -1361,11 +1412,17 @@ static const char *get_man_bin_path(void) } LTTNG_HIDDEN -int utils_show_man_page(int section, const char *page_name) +int utils_show_help(int section, const char *page_name, + const char *help_msg) { char section_string[8]; const char *man_bin_path = get_man_bin_path(); - int ret; + int ret = 0; + + if (help_msg) { + printf("%s", help_msg); + goto end; + } /* Section integer -> section string */ ret = sprintf(section_string, "%d", section); @@ -1374,11 +1431,48 @@ int utils_show_man_page(int section, const char *page_name) /* * Execute man pager. * - * We provide --manpath to man here because LTTng-tools can + * We provide -M to man here because LTTng-tools can * be installed outside /usr, in which case its man pages are * not located in the default /usr/share/man directory. */ - ret = execlp(man_bin_path, "man", "--manpath", MANPATH, + ret = execlp(man_bin_path, "man", "-M", MANPATH, section_string, page_name, NULL); + +end: return ret; } + +LTTNG_HIDDEN +int timespec_to_ms(struct timespec ts, unsigned long *ms) +{ + unsigned long res, remain_ms; + + if (ts.tv_sec > ULONG_MAX / MSEC_PER_SEC) { + errno = EOVERFLOW; + return -1; /* multiplication overflow */ + } + res = ts.tv_sec * MSEC_PER_SEC; + remain_ms = ULONG_MAX - res; + if (ts.tv_nsec / NSEC_PER_MSEC > remain_ms) { + errno = EOVERFLOW; + return -1; /* addition overflow */ + } + res += ts.tv_nsec / NSEC_PER_MSEC; + *ms = res; + return 0; +} + +LTTNG_HIDDEN +struct timespec timespec_abs_diff(struct timespec t1, struct timespec t2) +{ + uint64_t ts1 = (uint64_t) t1.tv_sec * (uint64_t) NSEC_PER_SEC + + (uint64_t) t1.tv_nsec; + uint64_t ts2 = (uint64_t) t2.tv_sec * (uint64_t) NSEC_PER_SEC + + (uint64_t) t2.tv_nsec; + uint64_t diff = max(ts1, ts2) - min(ts1, ts2); + struct timespec res; + + res.tv_sec = diff / (uint64_t) NSEC_PER_SEC; + res.tv_nsec = diff % (uint64_t) NSEC_PER_SEC; + return res; +}