aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/Makefile.am3
-rw-r--r--src/cxx_linuxlist.h133
-rw-r--r--tests/Makefile.am13
-rw-r--r--tests/llist/LListTest.cpp87
-rw-r--r--tests/llist/LListTest.err0
-rw-r--r--tests/llist/LListTest.ok10
-rw-r--r--tests/ms/MsTest.cpp1
-rw-r--r--tests/testsuite.at7
9 files changed, 251 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 4ae71dae..b0936920 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ tests/rlcmac/RLCMACTest
tests/tbf/TbfTest
tests/types/TypesTest
tests/ms/MsTest
+tests/llist/LListTest
tests/emu/pcu_emu
tests/testsuite
tests/testsuite.log
diff --git a/src/Makefile.am b/src/Makefile.am
index 8a422f64..0398028c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,7 +95,8 @@ noinst_HEADERS = \
rlc.h \
decoding.h \
llc.h \
- pcu_utils.h
+ pcu_utils.h \
+ cxx_linuxlist.h
osmo_pcu_SOURCES = pcu_main.cpp
diff --git a/src/cxx_linuxlist.h b/src/cxx_linuxlist.h
new file mode 100644
index 00000000..d9b28c44
--- /dev/null
+++ b/src/cxx_linuxlist.h
@@ -0,0 +1,133 @@
+/* cxx_linuxlist.h
+ *
+ * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
+ * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+extern "C" {
+ #include <osmocom/core/linuxlist.h>
+}
+
+template <typename T>
+struct LListHead {
+ typedef T entry_t;
+
+ /* This must match the declaration of struct llist_head */
+ LListHead<T> *next;
+ LListHead<T> *prev;
+
+ LListHead() : m_back(0) { INIT_LLIST_HEAD(this); }
+ LListHead(T* entry) : m_back(entry) {
+ next = (LListHead<T> *)LLIST_POISON1;
+ prev = (LListHead<T> *)LLIST_POISON2;
+ }
+
+ T *entry() {return m_back;}
+ const T *entry() const {return m_back;}
+
+ llist_head &llist() {
+ return *static_cast<llist_head *>(static_cast<void *>(this));
+ }
+ const llist_head &llist() const {
+ return *static_cast<llist_head *>(static_cast<void *>(this));
+ }
+
+private:
+ T *const m_back;
+};
+
+/* Define a family of casting functions */
+template <typename T>
+llist_head &llist(LListHead<T> &l)
+{
+ return l->llist();
+}
+
+template <typename T>
+const llist_head &llist(const LListHead<T> &l)
+{
+ return l->llist();
+}
+
+template <typename T>
+llist_head *llptr(LListHead<T> *l)
+{
+ return &(l->llist());
+}
+
+template <typename T>
+const llist_head *llptr(const LListHead<T> *l)
+{
+ return &(l->llist());
+}
+
+/* Define type-safe wrapper for the existing linux_list.h functions */
+template <typename T>
+inline void llist_add(LListHead<T> *new_, LListHead<T> *head)
+{
+ llist_add(llptr(new_), llptr(head));
+}
+
+template <typename T>
+inline void llist_add_tail(LListHead<T> *new_, LListHead<T> *head)
+{
+ llist_add_tail(llptr(new_), llptr(head));
+}
+
+template <typename T>
+inline void llist_del(LListHead<T> *entry)
+{
+ llist_del(llptr(entry));
+}
+
+template <typename T>
+inline void llist_del_init(LListHead<T> *entry)
+{
+ llist_del_init(llptr(entry));
+}
+
+template <typename T>
+inline void llist_move(LListHead<T> *list, LListHead<T> *head)
+{
+ llist_move(llptr(list), llptr(head));
+}
+
+template <typename T>
+inline void llist_move_tail(LListHead<T> *list, LListHead<T> *head)
+{
+ llist_move_tail(llptr(list), llptr(head));
+}
+
+template <typename T>
+inline int llist_empty(const LListHead<T> *head)
+{
+ return llist_empty(llptr(head));
+}
+
+template <typename T>
+inline void llist_splice(LListHead<T> *list, LListHead<T> *head)
+{
+ llist_splice(llptr(list), llptr(head));
+}
+
+template <typename T>
+inline void llist_splice_init(LListHead<T> *list, LListHead<T> *head)
+{
+ llist_splice_init(llptr(list), llptr(head));
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7b2d32d4..b822e469 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOGSM_CFLAGS) -I$(top_srcdir)/src/
-check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest
+check_PROGRAMS = rlcmac/RLCMACTest alloc/AllocTest tbf/TbfTest types/TypesTest ms/MsTest llist/LListTest
noinst_PROGRAMS = emu/pcu_emu
rlcmac_RLCMACTest_SOURCES = rlcmac/RLCMACTest.cpp
@@ -54,6 +54,14 @@ ms_MsTest_LDADD = \
ms_MsTest_LDFLAGS = \
-Wl,-u,bssgp_prim_cb
+llist_LListTest_SOURCES = llist/LListTest.cpp
+llist_LListTest_LDADD = \
+ $(top_builddir)/src/libgprs.la \
+ $(LIBOSMOGB_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOCORE_LIBS) \
+ $(COMMON_LA)
+
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
:;{ \
@@ -78,7 +86,8 @@ EXTRA_DIST = \
alloc/AllocTest.ok alloc/AllocTest.err \
tbf/TbfTest.ok tbf/TbfTest.err \
types/TypesTest.ok types/TypesTest.err \
- ms/MsTest.ok ms/MsTest.err
+ ms/MsTest.ok ms/MsTest.err \
+ llist/LListTest.ok llist/LListTest.err
DISTCLEANFILES = atconfig
diff --git a/tests/llist/LListTest.cpp b/tests/llist/LListTest.cpp
new file mode 100644
index 00000000..04f741cf
--- /dev/null
+++ b/tests/llist/LListTest.cpp
@@ -0,0 +1,87 @@
+/*
+ * LListTest.cpp
+ *
+ * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "cxx_linuxlist.h"
+
+extern "C" {
+#include <osmocom/core/application.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+}
+
+#include <errno.h>
+
+
+struct TestElem {
+ const char *str;
+ LListHead<TestElem> list;
+
+ TestElem(const char *s) : str(s), list(this) {};
+};
+
+static void test_linux_list()
+{
+ LListHead<TestElem> elems, *pos, *tmp;
+ TestElem elem1("number one");
+ TestElem elem2("number two");
+ TestElem elem3("number three");
+ int count = 0;
+
+ printf("=== start %s ===\n", __func__);
+
+ llist_add_tail(&elem1.list, &elems);
+ llist_add_tail(&elem2.list, &elems);
+ llist_add_tail(&elem3.list, &elems);
+
+ llist_for_each(pos, &elems) {
+ count += 1;
+ printf(" %i -> %s\n", count, pos->entry()->str);
+ }
+ OSMO_ASSERT(count == 3);
+
+ count = 0;
+ llist_for_each_safe(pos, tmp, &elems) {
+ count += 1;
+ if (count == 2)
+ llist_del(pos);
+
+ printf(" %i -> %s\n", count, pos->entry()->str);
+ }
+ OSMO_ASSERT(count == 3);
+
+ count = 0;
+ llist_for_each(pos, &elems) {
+ count += 1;
+ OSMO_ASSERT(pos != &elem2.list);
+ printf(" %i -> %s\n", count, pos->entry()->str);
+ }
+ OSMO_ASSERT(count == 2);
+
+ printf("=== end %s ===\n", __func__);
+}
+
+int main(int argc, char **argv)
+{
+ test_linux_list();
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/llist/LListTest.err b/tests/llist/LListTest.err
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/llist/LListTest.err
diff --git a/tests/llist/LListTest.ok b/tests/llist/LListTest.ok
new file mode 100644
index 00000000..375e9a64
--- /dev/null
+++ b/tests/llist/LListTest.ok
@@ -0,0 +1,10 @@
+=== start test_linux_list ===
+ 1 -> number one
+ 2 -> number two
+ 3 -> number three
+ 1 -> number one
+ 2 -> number two
+ 3 -> number three
+ 1 -> number one
+ 2 -> number three
+=== end test_linux_list ===
diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp
index 59c92b38..03b1c18d 100644
--- a/tests/ms/MsTest.cpp
+++ b/tests/ms/MsTest.cpp
@@ -231,7 +231,6 @@ static void test_ms_replace_tbf()
printf("=== end %s ===\n", __func__);
}
-
static const struct log_info_cat default_categories[] = {
{"DPCU", "", "GPRS Packet Control Unit (PCU)", LOGL_INFO, 1},
};
diff --git a/tests/testsuite.at b/tests/testsuite.at
index f1f40320..1cadcd25 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -36,3 +36,10 @@ cat $abs_srcdir/ms/MsTest.ok > expout
cat $abs_srcdir/ms/MsTest.err > experr
AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/ms/MsTest], [0], [expout], [experr])
AT_CLEANUP
+
+AT_SETUP([llist])
+AT_KEYWORDS([llist])
+cat $abs_srcdir/llist/LListTest.ok > expout
+cat $abs_srcdir/llist/LListTest.err > experr
+AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/llist/LListTest], [0], [expout], [experr])
+AT_CLEANUP