diff mbox

[BUG] wrong thread_id entry in thread_tbl[hereee!!!] for few odp applications

Message ID CA+iXiiMBuvXZEeg6D5r8x6xYc4KnRODFhesCphBr9A03qUxRZQ@mail.gmail.com
State New
Headers show

Commit Message

Santosh Shukla July 30, 2014, 11:10 a.m. UTC
Hi,

I noticed that few example odp application (l2fwd, generator, pktio
and odp_timer_ping) likely to store wrong thread_id because of the way
they were using odp_linux_pthread_create() api.

Example:

Refer  file example/l2fwd/odp_l2fwd.c, odp_generator.c and odp_time_ping.c

code snippet look like this

        for (i = 0; i < num_workers; ++i) {

                ...............
                .............
                odp_linux_pthread_create(thread_tbl, 1, core, thr_run_func,
                                         &gbl_args->thread[i]);
        }
The above will overwrite thread_tbl[0] for each iteration.

So if you print thread_tbl[] array, you will find only thread_tbl[0]
with valid value and rest with zero.

Problem is inner for loop of odp_linux_pthread_create() refills entry
in thread_tbl starting from index 0 till max number (arg3 above)

In my isolation case as well other cases like generator, l2fwd app,
don't want odp_linux_pthread_create to fill thread_tbl entry starting
from 0 everytime.


Specific to my isolation use -case I want to create two isolated
thread affine to any-many core provided by isolation application..

ie.. ./odp_isolation cpu_isolist = 4,6,10.

where cpu_isolist = create the thread and affine to cpus

Therefore I am proposing one more api set for odp_linux_pthread_craete
where I am explicitly bypassing inner for loop and avoiding thread_tbl
flush, I have tested this api for existing application like
odp_timer_ping, it works fine and Should work fine for other
application ie.. generator, l2fwd application.

Pasting a snap here before sending out formal patch in list.
----------------

---------------
diff mbox

Patch

diff --git a/include/helper/odp_linux.h b/include/helper/odp_linux.h
index 3076c22..f59819c 100644
--- a/include/helper/odp_linux.h
+++ b/include/helper/odp_linux.h
@@ -48,6 +48,11 @@  void odp_linux_pthread_create(odp_linux_pthread_t
*thread_tbl,
                              int num, int first_core,
                              void *(*start_routine) (void *), void *arg);

+void odp_linux_pthread_create_single(odp_linux_pthread_t *thread_tbl,
+                                       int thd_tbl_idx,
+                                       int first_core,
+                                       void *(*start_routine) (void
*), void *arg);
+

 /**
  * Waits pthreads to exit
diff --git a/platform/linux-generic/odp_linux.c
b/platform/linux-generic/odp_linux.c
index 6e2b448..f10dfa1 100644
--- a/platform/linux-generic/odp_linux.c
+++ b/platform/linux-generic/odp_linux.c
@@ -85,6 +85,53 @@  void odp_linux_pthread_create(odp_linux_pthread_t
*thread_tbl, int num,
 }


+void odp_linux_pthread_create_single(odp_linux_pthread_t *thread_tbl,
int thd_tbl_idx,
+               int first_core, void *(*start_routine) (void *), void *arg)
+{
+        int i;
+        cpu_set_t cpu_set;
+        odp_start_args_t *start_args;
+        int core_count;
+        int cpu;
+
+        core_count = odp_sys_core_count();
+
+        assert((first_core >= 0) && (first_core < core_count));
+        int core_count;
+        int cpu;
+
+        core_count = odp_sys_core_count();
+
+        assert((first_core >= 0) && (first_core < core_count));
+        assert((thd_tbl_idx >= 0) && (thd_tbl_idx <= core_count));
+
+       /* check thread_tbl idx is free for use? */
+       if(thread_tbl[thd_tbl_idx].thread != 0) {
+               //ODP_ERR("thread_tbl idx[%d] used\n", thd_tbl_idx);
+               printf("thread_tbl idx[%d] used\n", thd_tbl_idx);
+               return;
+       }
+
+       /* flush that tbl_idx only */
+        memset(thread_tbl+thd_tbl_idx, 0, sizeof(odp_linux_pthread_t));
+       i = thd_tbl_idx;
+       /* now create a thread,  affine to first_core */
+       pthread_attr_init(&thread_tbl[i].attr);
+
+       CPU_ZERO(&cpu_set);
+
+       cpu = first_core  % core_count;
+       CPU_SET(cpu, &cpu_set);
+
+       pthread_attr_setaffinity_np(&thread_tbl[i].attr,
+                                   sizeof(cpu_set_t), &cpu_set);
+
+       start_args = malloc(sizeof(odp_start_args_t));
+       memset(start_args, 0, sizeof(odp_start_args_t));
+       start_args->start_routine = start_routine;
+       start_args->arg           = arg;
+
+       start_args->thr_id        = odp_thread_create(cpu);
+
+       pthread_create(&thread_tbl[i].thread, &thread_tbl[i].attr,
+                      odp_run_start_routine, start_args);
+}
+