@@ -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
@@ -1 +1 @@
-SUBDIRS = generator ipsec l2fwd odp_example packet timer
+SUBDIRS = generator ipsec l2fwd odp_example packet timer sched_bug
new file mode 100644
@@ -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
new file mode 100644
@@ -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, ¶m);
+
+ 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, ¶ms);
+
+ 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;
+}
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