test/mem: disable ASan when accessing unallocated memory
[dpdk.git] / lib / eal / common / eal_common_launch.c
index 34f854a..992f8e4 100644 (file)
@@ -3,19 +3,15 @@
  */
 
 #include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/queue.h>
 
 #include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_eal.h>
+#include <rte_eal_trace.h>
 #include <rte_atomic.h>
 #include <rte_pause.h>
-#include <rte_per_lcore.h>
 #include <rte_lcore.h>
 
 #include "eal_private.h"
+#include "eal_thread.h"
 
 /*
  * Wait until a lcore finished its job.
 int
 rte_eal_wait_lcore(unsigned worker_id)
 {
-       if (lcore_config[worker_id].state == WAIT)
-               return 0;
-
-       while (lcore_config[worker_id].state != WAIT &&
-              lcore_config[worker_id].state != FINISHED)
+       while (__atomic_load_n(&lcore_config[worker_id].state,
+                       __ATOMIC_ACQUIRE) != WAIT)
                rte_pause();
 
-       rte_rmb();
-
-       /* we are in finished state, go to wait state */
-       lcore_config[worker_id].state = WAIT;
        return lcore_config[worker_id].ret;
 }
 
+/*
+ * 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 switches to WAIT state.
+ */
+int
+rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned int worker_id)
+{
+       int rc = -EBUSY;
+
+       /* 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].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);
+
+       eal_thread_wake_worker(worker_id);
+       rc = 0;
+
+finish:
+       rte_eal_trace_thread_remote_launch(f, arg, worker_id, rc);
+       return rc;
+}
+
 /*
  * Check that every WORKER lcores are in WAIT state, then call
  * rte_eal_remote_launch() for all of them. If call_main is true
@@ -62,7 +83,7 @@ rte_eal_mp_remote_launch(int (*f)(void *), void *arg,
 
        if (call_main == CALL_MAIN) {
                lcore_config[main_lcore].ret = f(arg);
-               lcore_config[main_lcore].state = FINISHED;
+               lcore_config[main_lcore].state = WAIT;
        }
 
        return 0;