char *name;
halcc_version version;
halcc_transport_e transport;
- halcc_dependency_state_e dependency_state;
- GHashTable *dependencies;
GHashTable *interfaces;
} halcc_hal;
hashtable_foreach(manifest->hals, cb, user_data);
}
-static void reset_hal_dependency_state(void *data, void *user_data)
-{
- halcc_hal *hal = (halcc_hal *) data;
-
- assert(hal);
-
- halcc_hal_set_dependency_state(hal, HALCC_DEPENDENCY_STATE_NONE);
-}
-
-/**
- * Check whether the dependencies specified by hal->dependencies are satisfied.
- * It sets hal->dependency_state and returns the value.
- */
-static halcc_dependency_state_e
-__validate_hal_dependency_state(halcc_manifest *manifest, halcc_hal *hal)
-{
- halcc_hal *dependency;
- halcc_dependency_state_e state = HALCC_DEPENDENCY_STATE_FAIL;
- GHashTableIter iter;
-
- assert(manifest);
- assert(hal);
-
- halcc_hal_get_dependency_state(hal, &state);
-
- /* It has been checked already, return immediately. */
- if (state != HALCC_DEPENDENCY_STATE_NONE)
- return state;
-
- /**
- * Mark it as validating is underway.
- *
- * The dependency_state will eventually be changed into
- * HALCC_DEPENDENCY_STATE_SUCCESS or HALCC_DEPENDENCY_STATE_FAIL
- * before going out of this function.
- */
- halcc_hal_set_dependency_state(hal, HALCC_DEPENDENCY_STATE_VALIDATING);
-
- /**
- * As the hashtable_foreach() only accepts a single parameter, it is
- * annoying that passing multiple parameter to iteration callback.
- * So exceptionally iterate the hashtable directly instead of using
- * hashtable_foreach().
- *
- * Iterate over the dependencies of the given hal. Check if there is compatible
- * hal with that dependency in the manifest. It will success only when all of the given
- * dependencies is compatible with one of a hal from the manifest. Otherwise, resolution
- * fails, setting dependency_state to HALCC_DEPENDENCY_STATE_FAIL.
- */
- g_hash_table_iter_init(&iter, hal->dependencies);
- while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &dependency)) {
- const char *dependency_hal_name = NULL;
- int dependency_hal_major = 0;
- int dependency_hal_minor = 0;
- halcc_hal *found = NULL;
- int ret;
-
- halcc_hal_get_name(dependency, &dependency_hal_name);
- halcc_hal_get_version(dependency, &dependency_hal_major, &dependency_hal_minor);
-
- ret = halcc_manifest_find_hal_forward_compatible(manifest,
- dependency_hal_name, dependency_hal_major, dependency_hal_minor,
- &found);
- if (ret != 0) { /* There is no hal that meets dependency. */
- halcc_hal_set_dependency_state(hal, HALCC_DEPENDENCY_STATE_FAIL);
- return HALCC_DEPENDENCY_STATE_FAIL;
- }
-
- /* Recursively validate dependency of the found hal. */
- state = __validate_hal_dependency_state(manifest, found);
-
- assert(state != HALCC_DEPENDENCY_STATE_NONE);
-
- if (state == HALCC_DEPENDENCY_STATE_SUCCESS)
- continue;
-
- /**
- * The below two cases are possible and they are all regarded as failure.
- *
- * 1) state == HALCC_DEPENDENCY_STATE_FAIL
- * : The found hal has already failed to validate its dependency,
- * thus the current hal is also set to fail.
- *
- * 2) state == HALCC_DEPENDENCY_STATE_VALIDATING
- * : Cyclic dependency, fail.
- */
- halcc_hal_set_dependency_state(hal, HALCC_DEPENDENCY_STATE_FAIL);
-
- return HALCC_DEPENDENCY_STATE_FAIL;
- }
-
- halcc_hal_set_dependency_state(hal, HALCC_DEPENDENCY_STATE_SUCCESS);
-
- return HALCC_DEPENDENCY_STATE_SUCCESS;
-}
-
-static void validate_hal_dependency_state(void *data, void *user_data)
-{
- halcc_manifest *manifest;
- halcc_hal *hal;
-
- manifest = (halcc_manifest *) user_data;
- hal = (halcc_hal *) data;
-
- assert(manifest);
- assert(hal);
-
- __validate_hal_dependency_state(manifest, hal);
-}
-
-/**
- * Validate dependencies between hals within manifest.
- *
- * Let's say a manifest contains below specification about 4 hals
- * - AAA@1.5 : success
- * - BBB@2.3 : success
- * - CCC@3.3 : success
- * - DDD@1.0 : success
- * If there are no dependencies between each other, no problem.
- *
- * Case1] If AAA@1.5 depends on YYY@1.0.
- * - AAA@1.5 -> YYY@1.0 : fail, YYY@1.0 is not specified
- * - BBB@2.3 : success
- * - CCC@3.3 : success
- * - DDD@1.0 : success
- *
- * Case2] If AAA@1.5 depends on BBB@1.0.
- * - AAA@1.5 -> BBB@1.0 : fail, BBB@1.0 isn't compatible with
- * the specified BBB@2.3
- * - BBB@2.3 : success
- * - CCC@3.3 : success
- * - DDD@1.0 : success
- *
- * Caser3] If AAA@1.5 depends on BBB@2.0, CCC@4.0
- * - AAA@1.5 -> BBB@2.0, CCC@4.0 : fail, BBB@2.0 is backward compatible
- * with the specified BBB@2.3, but CCC@4.0 isn't
- * compatible with the specified CCC@3.3.
- * - BBB@2.3 : success
- * - CCC@3.3 : success
- * - DDD@1.0 : success
- * If multiple dependencies are specified, it success only when all the
- * dependencies are satisfied.
- *
- * Case4] If AAA@1.5 depends on BBB@2.0
- * and BBB@2.3 depends on CCC@3.0
- * and CCC@3.3 depends on DDD@1.5
- * - AAA@1.5 -> BBB@2.0 : fail, BBB@2.0 is backward compatible with the
- * specified BBB@2.3, but BBB@2.3 has failed to
- * validate dependency
- * - BBB@2.3 -> CCC@3.0 : fail, CCC@3.0 is backward compatible with the
- * specified CCC@3.3, but CCC@3.3 has failed to
- * validate dependency
- * - CCC@3.3 -> DDD@1.5 : fail, DDD@1.5 isn't compatible with the
- * specified DDD@1.0
- * - DDD@1.0 : success
- * The failure is propagated to all hals that have dependency on that
- * failed hal.
- *
- * Case5] If AAA@1.5 depends on BBB@2.1
- * and BBB@2.3 depends on CCC@3.0
- * and CCC@3.3 depends on AAA@1.0
- * - AAA@1.5 -> BBB@2.1 : fail, cyclic dependency
- * - BBB@2.3 -> CCC@3.0 : fail, cyclic dependency
- * - CCC@3.3 -> AAA@1.0 : fail, cyclic dependency
- * - DDD@1.0 : success
- * All hals that make dependency cycle are failure.
- *
- * Case6] If AAA@1.5 depends on BBB@2.0
- * and BBB@2.3 depends on CCC@3.0
- * - AAA@1.5 -> BBB@2.0 : success
- * - BBB@2.3 -> CCC@3.0 : success
- * - CCC@3.3 : success
- * - DDD@1.0 : success
- */
-void halcc_manifest_validate_hal_dependency(halcc_manifest *manifest)
-{
- if (!manifest) {
- printf("Invalid parameter\n");
- return;
- }
-
- /* Reset all */
- halcc_manifest_foreach_hal(manifest, reset_hal_dependency_state, NULL);
-
- /* Validate dependency */
- halcc_manifest_foreach_hal(manifest, validate_hal_dependency_state, manifest);
-}
-
int halcc_hal_new(halcc_hal **hal)
{
halcc_hal *h;
}
h->transport = HALCC_TRANSPORT_DEFAULT;
- h->dependency_state = HALCC_DEPENDENCY_STATE_NONE;
- h->dependencies = hashtable_hal_new();
h->interfaces = hashtable_interface_new();
*hal = g_steal_pointer(&h);
}
free(g_steal_pointer(&hal->name));
- g_hash_table_destroy(g_steal_pointer(&hal->dependencies));
g_hash_table_destroy(g_steal_pointer(&hal->interfaces));
free(hal);
}
return 0;
}
-int halcc_hal_add_dependency(halcc_hal *hal, halcc_hal *dependency)
-{
- if (!hal || !dependency) {
- printf("Invalid parameter\n");
- return -EINVAL;
- }
-
- return hashtable_hal_insert(hal->dependencies, dependency);
-}
-
-void halcc_hal_remove_dependency(halcc_hal *hal,
- const char *dependency_hal_name, int major, int minor)
-{
- if (!hal || !dependency_hal_name) {
- printf("Invalid parameter\n");
- return;
- }
-
- hashtable_hal_remove(hal->dependencies, dependency_hal_name, major, minor);
-}
-
-void halcc_hal_foreach_dependency(halcc_hal *hal, halcc_iter_cb cb, void *user_data)
-{
- if (!hal || !hal->dependencies || !cb) {
- printf("Invalid parameter\n");
- return;
- }
-
- hashtable_foreach(hal->dependencies, cb, user_data);
-}
-
int halcc_hal_add_interface(halcc_hal *hal, halcc_interface *interface)
{
if (!hal || !interface) {
hashtable_foreach(hal->interfaces, cb, user_data);
}
-int halcc_hal_set_dependency_state(halcc_hal *hal, halcc_dependency_state_e dependency_state)
-{
- if (!hal) {
- printf("Invalid parameter\n");
- return -EINVAL;
- }
-
- hal->dependency_state = dependency_state;
-
- return 0;
-}
-
-int halcc_hal_get_dependency_state(halcc_hal *hal, halcc_dependency_state_e *dependency_state)
-{
- if (!hal || !dependency_state) {
- printf("Invalid parameter\n");
- return -EINVAL;
- }
-
- *dependency_state = hal->dependency_state;
-
- return 0;
-}
-
int halcc_interface_new(halcc_interface **interface)
{
halcc_interface *iface;
HALCC_TRANSPORT_IPC,
} halcc_transport_e;
-typedef enum halcc_dependency_state_e {
- HALCC_DEPENDENCY_STATE_NONE = 0,
- HALCC_DEPENDENCY_STATE_VALIDATING,
- HALCC_DEPENDENCY_STATE_SUCCESS,
- HALCC_DEPENDENCY_STATE_FAIL,
-} halcc_dependency_state_e;
-
typedef struct halcc_manifest halcc_manifest;
typedef struct halcc_hal halcc_hal;
typedef struct halcc_interface halcc_interface;
const char *hal_name, int major, int minor);
void halcc_manifest_foreach_hal(halcc_manifest *manifest,
halcc_iter_cb cb, void *user_data);
-void halcc_manifest_validate_hal_dependency(halcc_manifest *manifest);
int halcc_hal_new(halcc_hal **hal);
void halcc_hal_free(halcc_hal *hal);
int halcc_hal_get_version(halcc_hal *hal, int *major, int *minor);
int halcc_hal_set_transport(halcc_hal *hal, halcc_transport_e transport);
int halcc_hal_get_transport(halcc_hal *hal, halcc_transport_e *transport);
-int halcc_hal_add_dependency(halcc_hal *hal, halcc_hal *dependency);
-void halcc_hal_remove_dependency(halcc_hal *hal,
- const char *dependency_hal_name, int major, int minor);
-void halcc_hal_foreach_dependency(halcc_hal *hal, halcc_iter_cb cb, void *user_data);
int halcc_hal_add_interface(halcc_hal *hal, halcc_interface *interface);
void halcc_hal_remove_interface(halcc_hal *hal,
const char *interface_name, const char *instance_id);
void halcc_hal_foreach_interface(halcc_hal *hal, halcc_iter_cb cb, void *user_data);
-int halcc_hal_set_dependency_state(halcc_hal *hal, halcc_dependency_state_e dependency_state);
-int halcc_hal_get_dependency_state(halcc_hal *hal, halcc_dependency_state_e *dependency_state);
int halcc_interface_new(halcc_interface **interface);
void halcc_interface_free(halcc_interface *interface);