diff --git a/include/qb/qbutil.h b/include/qb/qbutil.h index 87102e8..bfce349 100644 --- a/include/qb/qbutil.h +++ b/include/qb/qbutil.h @@ -1,298 +1,298 @@ /* * Copyright (C) 2010 Red Hat, Inc. * * Author: Angus Salkeld * * libqb is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * libqb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libqb. If not, see . */ #ifndef QB_UTIL_H_DEFINED #define QB_UTIL_H_DEFINED /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif /* *INDENT-ON* */ #include #include #ifndef S_SPLINT_S #include #endif /* S_SPLINT_S */ #include /** * @file qbutil.h - * @author Angus Salkeld - * * These are some convience functions used throughout libqb. * + * @author Angus Salkeld + * * @par Locking * - qb_thread_lock_create() * - qb_thread_lock() * - qb_thread_trylock() * - qb_thread_unlock() * - qb_thread_lock_destroy() * * @par Time functions * - qb_timespec_add_ms() * - qb_util_nano_current_get() * - qb_util_nano_monotonic_hz() * - qb_util_nano_from_epoch_get() * - qb_util_timespec_from_epoch_get() * * @par Basic Stopwatch * @code * uint64_t elapsed1; * uint64_t elapsed2; * qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); * * qb_util_stopwatch_start(sw); * * usleep(sometime); * qb_util_stopwatch_stop(sw); * elapsed1 = qb_util_stopwatch_us_elapsed_get(sw); * * usleep(somemoretime); * qb_util_stopwatch_stop(sw); * elapsed2 = qb_util_stopwatch_us_elapsed_get(sw); * * qb_util_stopwatch_free(sw); * @endcode * * @par Stopwatch with splits * Setup a stopwatch with space for 3 splits. * * @code * uint64_t split; * qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); * * qb_util_stopwatch_split_ctl(sw, 3, 0); * qb_util_stopwatch_start(sw); * * usleep(sometime); * qb_util_stopwatch_split(sw); * * usleep(somemoretime); * qb_util_stopwatch_split(sw); * * usleep(somemoretime); * qb_util_stopwatch_split(sw); * * idx = qb_util_stopwatch_split_last(sw); * do { * split = qb_util_stopwatch_time_split_get(sw, idx, idx); * qb_log(LOG_INFO, "split %d is %"PRIu64"", last, split); * idx--; * } while (split > 0); * * split = qb_util_stopwatch_time_split_get(sw, 2, 1); * qb_log(LOG_INFO, "time between second and third split is %"PRIu64"", split); * * qb_util_stopwatch_free(sw); * @endcode * */ /** * @typedef qb_thread_lock_type_t * QB_THREAD_LOCK_SHORT is a short term lock (spinlock if available on your system) * QB_THREAD_LOCK_LONG is a mutex */ typedef enum { QB_THREAD_LOCK_SHORT, QB_THREAD_LOCK_LONG, } qb_thread_lock_type_t; struct qb_thread_lock_s; typedef struct qb_thread_lock_s qb_thread_lock_t; /** * Create a new lock of the given type. * @param type QB_THREAD_LOCK_SHORT == spinlock (where available, else mutex) * QB_THREAD_LOCK_LONG == mutex * @return pointer to qb_thread_lock_type_t or NULL on error. */ qb_thread_lock_t *qb_thread_lock_create(qb_thread_lock_type_t type); /** * Calls either pthread_mutex_lock() or pthread_spin_lock(). */ int32_t qb_thread_lock(qb_thread_lock_t * tl); /** * Calls either pthread_mutex_trylock() or pthread_spin_trylock(). */ int32_t qb_thread_trylock(qb_thread_lock_t * tl); /** * Calls either pthread_mutex_unlock() or pthread_spin_unlock. */ int32_t qb_thread_unlock(qb_thread_lock_t * tl); /** * Calls either pthread_mutex_destro() or pthread_spin_destroy(). */ int32_t qb_thread_lock_destroy(qb_thread_lock_t * tl); typedef void (*qb_util_log_fn_t) (const char *file_name, int32_t file_line, int32_t severity, const char *msg); /** * Use this function to output libqb internal log message as you wish. */ void qb_util_set_log_function(qb_util_log_fn_t fn) QB_GNUC_DEPRECATED; /** * Add milliseconds onto the timespec. * @param ts the ts to add to * @param ms the amount of milliseconds to increment ts */ void qb_timespec_add_ms(struct timespec *ts, int32_t ms); /** * Get the current number of nano secounds produced * by the systems incrementing clock (CLOCK_MONOTOMIC * if available). */ uint64_t qb_util_nano_current_get(void); /** * Get the frequence of the clock used in * qb_util_nano_current_get(). */ uint64_t qb_util_nano_monotonic_hz(void); /** * Get the time in nano seconds since epoch. */ uint64_t qb_util_nano_from_epoch_get(void); /** * Get the time in timespec since epoch. * @param ts (out) the timespec * @return status (0 == ok, -errno on error) */ void qb_util_timespec_from_epoch_get(struct timespec *ts); /** * strerror_r replacement. */ char *qb_strerror_r(int errnum, char *buf, size_t buflen); typedef struct qb_util_stopwatch qb_util_stopwatch_t; #define QB_UTIL_SW_OVERWRITE 0x01 /** * Create a Stopwatch (to time operations) */ qb_util_stopwatch_t * qb_util_stopwatch_create(void); /** * Free the stopwatch */ void qb_util_stopwatch_free(qb_util_stopwatch_t *sw); /** * Start the stopwatch * * This also acts as a reset. Essentially it sets the * starting time and clears the splits. */ void qb_util_stopwatch_start(qb_util_stopwatch_t *sw); /** * Stop the stopwatch * * This just allows you to get the elapsed time. So * you can call this multiple times. Do not call qb_util_stopwatch_start() * unless you want to reset the stopwatch. */ void qb_util_stopwatch_stop(qb_util_stopwatch_t *sw); /** * Get the elapsed time in micro seconds. * * (it must have been started and stopped). */ uint64_t qb_util_stopwatch_us_elapsed_get(qb_util_stopwatch_t *sw); /** * Get the elapsed time in seconds. * * (it must have been started and stopped). */ float qb_util_stopwatch_sec_elapsed_get(qb_util_stopwatch_t *sw); /** * * @param sw the stopwatch * @param max_splits maximum number of time splits * @param options (0 or QB_UTIL_SW_OVERWRITE ) * @retval 0 on success * @retval -errno on failure */ int32_t qb_util_stopwatch_split_ctl(qb_util_stopwatch_t *sw, uint32_t max_splits, uint32_t options); /** * Create a new time split (or lap time) * * @param sw the stopwatch * @retval the relative split time in micro seconds * @retval 0 if no more splits available */ uint64_t qb_util_stopwatch_split(qb_util_stopwatch_t *sw); /** * Get the last split index to be used by * qb_util_stopwatch_time_split_get() * * @note this is zero based * * @param sw the stopwatch * @return the last entry index */ uint32_t qb_util_stopwatch_split_last(qb_util_stopwatch_t *sw); /** * Read the time split (in us) from "receint" to "older". * * If older == receint then the cumulated split will be * returned (from the stopwatch start). * * @param sw the stopwatch * @param receint split * @param older split * @retval the split time in micro seconds * @retval 0 if not a valid split */ uint64_t qb_util_stopwatch_time_split_get(qb_util_stopwatch_t *sw, uint32_t receint, uint32_t older); /* *INDENT-OFF* */ #ifdef __cplusplus } #endif /* __cplusplus */ /* *INDENT-ON* */ #endif /* QB_UTIL_H_DEFINED */