[MERGED] libosmocore[master]: Add osmo_timerfd_* functions for osmo_fd-wrapped timerfd

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.org
Thu May 10 10:03:57 UTC 2018


Harald Welte has submitted this change and it was merged.

Change subject: Add osmo_timerfd_* functions for osmo_fd-wrapped timerfd
......................................................................


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(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/configure.ac b/configure.ac
index 6f56176..6b9c66f 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_DLOPEN="$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: merged
Gerrit-Change-Id: Ibeffba7c997252c003723bcd5d14122c4ded2fe7
Gerrit-PatchSet: 2
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list