/* map of services IDs are run on this core */
uint64_t service_mask;
uint8_t runstate; /* running or stopped */
+ uint8_t thread_active; /* indicates when thread is in service_run() */
uint8_t is_service_core; /* set if core is currently a service core */
uint8_t service_active_on_lcore[RTE_SERVICE_NUM_MAX];
uint64_t loops;
const int lcore = rte_lcore_id();
struct core_state *cs = &lcore_states[lcore];
+ __atomic_store_n(&cs->thread_active, 1, __ATOMIC_SEQ_CST);
+
/* runstate act as the guard variable. Use load-acquire
* memory order here to synchronize with store-release
* in runstate update functions.
cs->loops++;
}
+ /* Use SEQ CST memory ordering to avoid any re-ordering around
+ * this store, ensuring that once this store is visible, the service
+ * lcore thread really is done in service cores code.
+ */
+ __atomic_store_n(&cs->thread_active, 0, __ATOMIC_SEQ_CST);
return 0;
}
+int32_t
+rte_service_lcore_may_be_active(uint32_t lcore)
+{
+ if (lcore >= RTE_MAX_LCORE || !lcore_states[lcore].is_service_core)
+ return -EINVAL;
+
+ /* Load thread_active using ACQUIRE to avoid instructions dependent on
+ * the result being re-ordered before this load completes.
+ */
+ return __atomic_load_n(&lcore_states[lcore].thread_active,
+ __ATOMIC_ACQUIRE);
+}
+
int32_t
rte_service_lcore_count(void)
{
* Stop a service core.
*
* Stopping a core makes the core become idle, but remains assigned as a
- * service core.
+ * service core. Note that the service lcore thread may not have returned from
+ * the service it is running when this API returns.
+ *
+ * The *rte_service_lcore_may_be_active* API can be used to check if the
+ * service lcore is * still active.
*
* @retval 0 Success
* @retval -EINVAL Invalid *lcore_id* provided
*/
int32_t rte_service_lcore_stop(uint32_t lcore_id);
+/**
+ * Reports if a service lcore is currently running.
+ *
+ * This function returns if the core has finished service cores code, and has
+ * returned to EAL control. If *rte_service_lcore_stop* has been called but
+ * the lcore has not returned to EAL yet, it might be required to wait and call
+ * this function again. The amount of time to wait before the core returns
+ * depends on the duration of the services being run.
+ *
+ * @retval 0 Service thread is not active, and lcore has been returned to EAL.
+ * @retval 1 Service thread is in the service core polling loop.
+ * @retval -EINVAL Invalid *lcore_id* provided.
+ */
+__rte_experimental
+int32_t rte_service_lcore_may_be_active(uint32_t lcore_id);
+
/**
* Adds lcore to the list of service cores.
*