diff mbox

[RFC,3/4] example showing scheduler bug

Message ID 1418723669-10161-4-git-send-email-ciprian.barbu@linaro.org
State New
Headers show

Commit Message

Ciprian Barbu Dec. 16, 2014, 9:54 a.m. UTC
Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org>
---
 configure.ac                  |   1 +
 example/Makefile.am           |   2 +-
 example/sched_bug/Makefile.am |   7 ++
 example/sched_bug/sched_bug.c | 189 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 198 insertions(+), 1 deletion(-)
 create mode 100644 example/sched_bug/Makefile.am
 create mode 100644 example/sched_bug/sched_bug.c
diff mbox

Patch

diff --git a/configure.ac b/configure.ac
index bc97f1a..2dd1c33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -199,6 +199,7 @@  AC_CONFIG_FILES([Makefile
 		 example/odp_example/Makefile
 		 example/packet/Makefile
 		 example/timer/Makefile
+		 example/sched_bug/Makefile
 		 test/Makefile
 		 test/api_test/Makefile
 		 test/validation/Makefile
diff --git a/example/Makefile.am b/example/Makefile.am
index b2a22a3..d3d7cb9 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -1 +1 @@ 
-SUBDIRS = generator ipsec l2fwd odp_example packet timer
+SUBDIRS = generator ipsec l2fwd odp_example packet timer sched_bug
diff --git a/example/sched_bug/Makefile.am b/example/sched_bug/Makefile.am
new file mode 100644
index 0000000..3e9caa3
--- /dev/null
+++ b/example/sched_bug/Makefile.am
@@ -0,0 +1,7 @@ 
+include $(top_srcdir)/example/Makefile.inc
+
+bin_PROGRAMS = sched_bug
+sched_bug_LDFLAGS = $(AM_LDFLAGS) -static
+sched_bug_CFLAGS = $(AM_CFLAGS) -I../
+
+dist_sched_bug_SOURCES = sched_bug.c
diff --git a/example/sched_bug/sched_bug.c b/example/sched_bug/sched_bug.c
new file mode 100644
index 0000000..37e60eb
--- /dev/null
+++ b/example/sched_bug/sched_bug.c
@@ -0,0 +1,189 @@ 
+#include <stdio.h>
+#include <odp.h>
+#include <example_debug.h>
+#include <assert.h>
+
+#define QUEUES_PER_PRIO		4  /* Must match the value in
+				      platform/linux-generic/odp_schedule.c */
+
+#define MAX_DEQ			4 /* Must match the value in
+				     platform/linux-generic/odp_schedule.c */
+
+#define MSG_POOL_SIZE		(4*1024*1024) /**< Message pool size */
+#define NUM_QUEUES		(2 * QUEUES_PER_PRIO)
+
+/** Dummy message */
+typedef struct {
+	int msg_id; /**< Message ID */
+	int seq;    /**< Sequence number */
+} test_message_t;
+
+#define MSG_HELLO 1  /**< Hello */
+#define MSG_ACK   2  /**< Ack */
+
+odp_buffer_pool_t pool;
+
+static odp_queue_t create_prio_queue(odp_schedule_prio_t prio, int num)
+{
+	odp_queue_param_t param;
+	odp_queue_t queue;
+	char name[64];
+
+	snprintf(name, sizeof(name), "sched_%d_%d", prio, num);
+	param.sched.prio = prio;
+	param.sched.sync =  ODP_SCHED_SYNC_NONE;
+	param.sched.group = ODP_SCHED_GROUP_DEFAULT;
+	queue = odp_queue_create(name, ODP_QUEUE_TYPE_SCHED, &param);
+
+	printf("Created q=0x%x prio=%d name=%s\n",
+	       queue, odp_queue_sched_prio(queue), name);
+
+	return queue;
+}
+
+static int create_queues(void)
+{
+	int i;
+	odp_queue_t queue;
+
+	for (i = 0; i < NUM_QUEUES; i++) {
+
+		queue = create_prio_queue(0, i);
+		if (queue == ODP_QUEUE_INVALID)
+			return -1;
+	}
+
+	for (i = 0; i < NUM_QUEUES; i++) {
+		queue = create_prio_queue(1, i);
+		if (queue == ODP_QUEUE_INVALID)
+			return -1;
+	}
+
+	return 0;
+}
+
+static void fill_queue_prio(odp_schedule_prio_t prio, int qnum, int buf_num)
+{
+	odp_queue_t queue;
+	char name[64];
+	int i;
+
+	snprintf(name, sizeof(name), "sched_%d_%d", prio, qnum);
+	queue = odp_queue_lookup(name);
+
+	for (i = 0; i < buf_num; i++) {
+		odp_buffer_t buf;
+		buf = odp_buffer_alloc(pool);
+		odp_queue_enq(queue, buf);
+	}
+}
+
+static void fill_queues(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_QUEUES; i++) {
+		fill_queue_prio(0, i, MAX_DEQ);
+		fill_queue_prio(1, i, MAX_DEQ);
+	}
+}
+
+static void fill_queues_error_case(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_QUEUES; i++) {
+		fill_queue_prio(1, i, MAX_DEQ);
+	}
+
+	fill_queue_prio(0, 0, MAX_DEQ);
+	fill_queue_prio(0, QUEUES_PER_PRIO, 2 * MAX_DEQ);
+}
+
+static void test_prio(int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++) {
+		odp_buffer_t buf;
+		odp_queue_t from;
+		odp_schedule_prio_t prio;
+
+		buf = odp_schedule(&from, ODP_SCHED_WAIT);
+
+		if (buf == ODP_BUFFER_INVALID)
+			return;
+
+		odp_buffer_free(buf);
+
+		prio = odp_queue_sched_prio(from);
+
+		printf("Got buffer q=0x%x prio=%d\n", from, prio);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	odp_shm_t shm;
+	void *pool_base;
+	odp_buffer_pool_param_t params;
+
+	(void)argc;
+	(void)argv;
+
+	/* ODP global init */
+	if (odp_init_global(NULL, NULL)) {
+		EXAMPLE_ERR("ODP global init failed.\n");
+		return -1;
+	}
+
+	/*
+	 * Init this thread. It makes also ODP calls when
+	 * setting up resources for worker threads.
+	 */
+	if (odp_init_local()) {
+		EXAMPLE_ERR("ODP global init failed.\n");
+		return -1;
+	}
+
+	shm = odp_shm_reserve("msg_pool",
+			      MSG_POOL_SIZE, ODP_CACHE_LINE_SIZE, 0);
+
+	pool_base = odp_shm_addr(shm);
+
+	if (pool_base == NULL) {
+		EXAMPLE_ERR("Shared memory reserve failed.\n");
+		return -1;
+	}
+
+	/*
+	 * Create message pool
+	 */
+
+	params.buf_size  = sizeof(test_message_t);
+	params.buf_align = 0;
+	params.num_bufs  = MSG_POOL_SIZE/sizeof(test_message_t);
+	params.buf_type  = ODP_BUFFER_TYPE_RAW;
+
+	pool = odp_buffer_pool_create("msg_pool_", ODP_SHM_NULL, &params);
+
+	if (pool == ODP_BUFFER_POOL_INVALID) {
+		EXAMPLE_ERR("Pool create failed.\n");
+		return -1;
+	}
+
+	if (create_queues())
+		return -1;
+
+	printf("\nRound 1\n");
+
+	fill_queues();
+	test_prio(2 * NUM_QUEUES * MAX_DEQ);
+
+	printf("\nRound 2\n");
+
+	fill_queues_error_case();
+	test_prio(2 * NUM_QUEUES + 3 * MAX_DEQ);
+
+	return 0;
+}