X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Feal%2Ffreebsd%2Feal_thread.c;h=3b18030d735bf5df340d6ddc01494b3ffd01a8be;hb=4042dc2037a1509596f7eb48370185434bad39cc;hp=bbc3a8e985730846b5bdd77044f08365e2621ad2;hpb=33969e9c61385fc397f1934324e231ece9750404;p=dpdk.git diff --git a/lib/eal/freebsd/eal_thread.c b/lib/eal/freebsd/eal_thread.c index bbc3a8e985..3b18030d73 100644 --- a/lib/eal/freebsd/eal_thread.c +++ b/lib/eal/freebsd/eal_thread.c @@ -28,7 +28,7 @@ /* * Send a message to a worker lcore identified by worker_id to call a * function f with argument arg. Once the execution is done, the - * remote lcore switch in FINISHED state. + * remote lcore switches to WAIT state. */ int rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned worker_id) @@ -39,11 +39,19 @@ rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned worker_id) int w2m = lcore_config[worker_id].pipe_worker2main[0]; int rc = -EBUSY; - if (lcore_config[worker_id].state != WAIT) + /* Check if the worker is in 'WAIT' state. Use acquire order + * since 'state' variable is used as the guard variable. + */ + if (__atomic_load_n(&lcore_config[worker_id].state, + __ATOMIC_ACQUIRE) != WAIT) goto finish; - lcore_config[worker_id].f = f; lcore_config[worker_id].arg = arg; + /* Ensure that all the memory operations are completed + * before the worker thread starts running the function. + * Use worker thread function as the guard variable. + */ + __atomic_store_n(&lcore_config[worker_id].f, f, __ATOMIC_RELEASE); /* send message */ n = 0; @@ -100,6 +108,7 @@ eal_thread_loop(__rte_unused void *arg) /* read on our pipe to get commands */ while (1) { + lcore_function_t *f; void *fct_arg; /* wait command */ @@ -110,7 +119,11 @@ eal_thread_loop(__rte_unused void *arg) if (n <= 0) rte_panic("cannot read on configuration pipe\n"); - lcore_config[lcore_id].state = RUNNING; + /* Set the state to 'RUNNING'. Use release order + * since 'state' variable is used as the guard variable. + */ + __atomic_store_n(&lcore_config[lcore_id].state, RUNNING, + __ATOMIC_RELEASE); /* send ack */ n = 0; @@ -119,17 +132,29 @@ eal_thread_loop(__rte_unused void *arg) if (n < 0) rte_panic("cannot write on configuration pipe\n"); - if (lcore_config[lcore_id].f == NULL) - rte_panic("NULL function pointer\n"); + /* Load 'f' with acquire order to ensure that + * the memory operations from the main thread + * are accessed only after update to 'f' is visible. + * Wait till the update to 'f' is visible to the worker. + */ + while ((f = __atomic_load_n(&lcore_config[lcore_id].f, + __ATOMIC_ACQUIRE)) == NULL) + rte_pause(); /* call the function and store the return value */ fct_arg = lcore_config[lcore_id].arg; - ret = lcore_config[lcore_id].f(fct_arg); + ret = f(fct_arg); lcore_config[lcore_id].ret = ret; lcore_config[lcore_id].f = NULL; lcore_config[lcore_id].arg = NULL; - rte_wmb(); - lcore_config[lcore_id].state = FINISHED; + + /* Store the state with release order to ensure that + * the memory operations from the worker thread + * are completed before the state is updated. + * Use 'state' as the guard variable. + */ + __atomic_store_n(&lcore_config[lcore_id].state, WAIT, + __ATOMIC_RELEASE); } /* never reached */