This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Harald Welte gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/5185 Add osmo_timerfd_ functions for osmo_fd-wrapped timerfd Linux offers file descriptor based periodic (interval) timers, which can achieve a higher precision than our userspace based timers and which can be slave'd to CLOCK_MONOTINIC or other clock sources. Let's add some code for osmo_fd wrapped versions that integrate well with our select() abstraction. The code has been used in osmo-bts-trx since June 2017 (change-id I51b19adde14ebb7ef3bb863d45e06243c323e22e), and I'm just renaming and moving it to libosmocore here. After a merge, the osmo-bts implementations can be removed in favor if this one. Change-Id: Ibeffba7c997252c003723bcd5d14122c4ded2fe7 --- M configure.ac M include/osmocom/core/select.h M src/select.c 3 files changed, 74 insertions(+), 1 deletion(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/85/5185/1 diff --git a/configure.ac b/configure.ac index f7acf05..e2b225e 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,7 @@ dnl checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h syslog.h ctype.h netinet/tcp.h) +AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h sys/timerfd.h syslog.h ctype.h netinet/tcp.h) # for src/conv.c AC_FUNC_ALLOCA AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""]) diff --git a/include/osmocom/core/select.h b/include/osmocom/core/select.h index b6fed3c..1ba6b83 100644 --- a/include/osmocom/core/select.h +++ b/include/osmocom/core/select.h @@ -6,6 +6,7 @@ #include <osmocom/core/linuxlist.h> #include <stdbool.h> +#include <time.h> /*! \defgroup select Select loop abstraction * @{ @@ -54,4 +55,10 @@ int osmo_fd_fill_fds(void *readset, void *writeset, void *exceptset); int osmo_fd_disp_fds(void *readset, void *writeset, void *exceptset); +/* timerfd integration */ +int osmo_timerfd_disable(struct osmo_fd *ofd); +int osmo_timerfd_schedule(struct osmo_fd *ofd, const struct timespec *first, + const struct timespec *interval); +int osmo_timerfd_setup(struct osmo_fd *ofd, int (*cb)(struct osmo_fd *, unsigned int), void *data); + /*! @} */ diff --git a/src/select.c b/src/select.c index 1c62e01..0b115c6 100644 --- a/src/select.c +++ b/src/select.c @@ -30,6 +30,7 @@ #include <unistd.h> #include <string.h> #include <stdbool.h> +#include <errno.h> #include <osmocom/core/select.h> #include <osmocom/core/linuxlist.h> @@ -270,6 +271,71 @@ return NULL; } +#ifdef HAVE_SYS_TIMERFD_H +#include <sys/timerfd.h> + +/*! disable the osmocom-wrapped timerfd */ +int osmo_timerfd_disable(struct osmo_fd *ofd) +{ + const struct itimerspec its_null = { + .it_value = { 0, 0 }, + .it_interval = { 0, 0 }, + }; + return timerfd_settime(ofd->fd, 0, &its_null, NULL); +} + +/*! schedule the osmcoom-wrapped timerfd to occur first at \a first, then periodically at \a interval + * \param[in] ofd Osmocom wrapped timerfd + * \param[in] first Relative time at which the timer should first execute (NULL = \a interval) + * \param[in] interval Time interval at which subsequent timer shall fire + * \returns 0 on success; negative on error */ +int osmo_timerfd_schedule(struct osmo_fd *ofd, const struct timespec *first, + const struct timespec *interval) +{ + struct itimerspec its; + + if (ofd->fd < 0) + return -EINVAL; + + /* first expiration */ + if (first) + its.it_value = *first; + else + its.it_value = *interval; + /* repeating interval */ + its.it_interval = *interval; + + return timerfd_settime(ofd->fd, 0, &its, NULL); +} + +/*! setup osmocom-wrapped timerfd + * \param[inout] ofd Osmocom-wrapped timerfd on which to operate + * \param[in] cb Call-back function called when timerfd becomes readable + * \param[in] data Opaque data to be passed on to call-back + * \returns 0 on success; negative on error + * + * We simply initialize the data structures here, but do not yet + * schedule the timer. + */ +int osmo_timerfd_setup(struct osmo_fd *ofd, int (*cb)(struct osmo_fd *, unsigned int), void *data) +{ + ofd->cb = cb; + ofd->data = data; + ofd->when = BSC_FD_READ; + + if (ofd->fd < 0) { + ofd->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (ofd->fd < 0) + return ofd->fd; + + osmo_fd_register(ofd); + } + return 0; +} + +#endif /* HAVE_SYS_TIMERFD_H */ + + /*! @} */ #endif /* _HAVE_SYS_SELECT_H */ -- To view, visit https://gerrit.osmocom.org/5185 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibeffba7c997252c003723bcd5d14122c4ded2fe7 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Harald Welte <laforge at gnumonks.org>