rte_eal_hotplug_remove;
rte_service_component_register;
rte_service_component_unregister;
+ rte_service_component_runstate_set;
rte_service_dump;
rte_service_get_by_id;
rte_service_get_by_name;
*/
int32_t rte_service_start_with_defaults(void);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Set the backend runstate of a component.
+ *
+ * This function allows services to be registered at startup, but not yet
+ * enabled to run by default. When the service has been configured (via the
+ * usual method; eg rte_eventdev_configure, the service can mark itself as
+ * ready to run. The differentiation between backend runstate and
+ * service_runstate is that the backend runstate is set by the service
+ * component while the service runstate is reserved for application usage.
+ *
+ * @retval 0 Success
+ */
+int32_t rte_service_component_runstate_set(uint32_t id, uint32_t runstate);
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
rte_atomic32_t execute_lock;
/* API set/get-able variables */
- int32_t runstate;
+ int8_t app_runstate;
+ int8_t comp_runstate;
uint8_t internal_flags;
/* per service statistics */
return 0;
}
+int32_t
+rte_service_component_runstate_set(uint32_t id, uint32_t runstate)
+{
+ struct rte_service_spec_impl *s;
+ SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);
+
+ if (runstate)
+ s->comp_runstate = RUNSTATE_RUNNING;
+ else
+ s->comp_runstate = RUNSTATE_STOPPED;
+
+ rte_smp_wmb();
+ return 0;
+}
+
int32_t
rte_service_runstate_set(uint32_t id, uint32_t runstate)
{
SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);
if (runstate)
- s->runstate = RUNSTATE_RUNNING;
+ s->app_runstate = RUNSTATE_RUNNING;
else
- s->runstate = RUNSTATE_STOPPED;
+ s->app_runstate = RUNSTATE_STOPPED;
rte_smp_wmb();
return 0;
{
struct rte_service_spec_impl *s;
SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);
-
- return (s->runstate == RUNSTATE_RUNNING) && (s->num_mapped_cores > 0);
+ rte_smp_rmb();
+ return (s->app_runstate == RUNSTATE_RUNNING) &&
+ (s->comp_runstate == RUNSTATE_RUNNING) &&
+ (s->num_mapped_cores > 0);
}
static inline void
if (!service_valid(i))
continue;
struct rte_service_spec_impl *s = &rte_services[i];
- if (s->runstate != RUNSTATE_RUNNING ||
+ if (s->comp_runstate != RUNSTATE_RUNNING ||
+ s->app_runstate != RUNSTATE_RUNNING ||
!(service_mask & (UINT64_C(1) << i)))
continue;
for (i = 0; i < RTE_SERVICE_NUM_MAX; i++) {
int32_t enabled =
lcore_states[i].service_mask & (UINT64_C(1) << i);
- int32_t service_running = rte_services[i].runstate !=
- RUNSTATE_STOPPED;
+ int32_t service_running = rte_service_runstate_get(i);
int32_t only_core = rte_services[i].num_mapped_cores == 1;
/* if the core is mapped, and the service is running, and this
rte_eal_hotplug_remove;
rte_service_component_register;
rte_service_component_unregister;
+ rte_service_component_runstate_set;
rte_service_dump;
rte_service_get_by_id;
rte_service_get_by_name;
"Invalid name");
snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
- TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),
+ uint32_t id;
+ TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
"Failed to register valid service");
+ rte_service_component_runstate_set(id, 1);
+
return TEST_SUCCESS;
}
if (mt_safe) {
service.callback = dummy_mt_safe_cb;
service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
- } else {
- /* initialize to pass, see callback comment for details */
- test_params[1] = 1;
+ } else
service.callback = dummy_mt_unsafe_cb;
- }
- TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),
+ uint32_t id;
+ TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
"Register of MT SAFE service failed");
const uint32_t sid = 0;
rte_service_lcore_stop(slcore_1);
rte_service_lcore_stop(slcore_2);
+ TEST_ASSERT_EQUAL(0, test_params[1],
+ "Service run with component runstate = 0");
+
+ /* enable backend runstate: the service should run after this */
+ rte_service_component_runstate_set(id, 1);
+
+ /* initialize to pass, see callback comment for details */
+ if (!mt_safe)
+ test_params[1] = 1;
+
+ rte_service_lcore_start(slcore_1);
+ rte_service_lcore_start(slcore_2);
+
+ /* wait for the worker threads to run */
+ rte_delay_ms(500);
+ rte_service_lcore_stop(slcore_1);
+ rte_service_lcore_stop(slcore_2);
+
TEST_ASSERT_EQUAL(1, test_params[1],
"MT Safe service not run by two cores concurrently");
-
TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
"Failed to stop MT Safe service");