diff options
Diffstat (limited to 'src/framework/init')
-rw-r--r-- | src/framework/init/CMakeLists.txt | 24 | ||||
-rw-r--r-- | src/framework/init/fw_init.c | 320 | ||||
-rw-r--r-- | src/framework/init/fw_module.c | 331 | ||||
-rw-r--r-- | src/framework/init/fw_module.h | 85 |
4 files changed, 760 insertions, 0 deletions
diff --git a/src/framework/init/CMakeLists.txt b/src/framework/init/CMakeLists.txt new file mode 100644 index 0000000..ff8d4d2 --- /dev/null +++ b/src/framework/init/CMakeLists.txt @@ -0,0 +1,24 @@ +######################################################################### +# +# Copyright (c) 2018 Huawei Technologies Co.,Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +######################################################################### + +SET(LIBSBR_SRC fw_init.c fw_module.c) + +SET(COMM_CONFIG ${PROJECT_SOURCE_DIR}/src/framework/common/base/include/common_sys_config.h) +ADD_DEFINITIONS(-fPIC -mssse3) +ADD_DEFINITIONS(-include ${COMM_CONFIG}) + +ADD_LIBRARY(nStackfwinit static ${LIBSBR_SRC}) + diff --git a/src/framework/init/fw_init.c b/src/framework/init/fw_init.c new file mode 100644 index 0000000..6337b67 --- /dev/null +++ b/src/framework/init/fw_init.c @@ -0,0 +1,320 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "nstack_securec.h" +#include "fw_module.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +NSTACK_STATIC int +nsfw_module_instance_isIndepend (nsfw_module_instance_t * inst) +{ + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + if (!dep->isReady) + return 1; + dep = dep->next; + } + + return 0; +} + +NSTACK_STATIC void +nsfw_module_instance_depend_check (nsfw_module_instance_t * inst) +{ + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (curInst == inst) + goto nextLoop; + if (NSFW_INST_STAT_CHECKING == curInst->stat + || NSFW_INST_STAT_DEPENDING == curInst->stat) + { + nsfw_module_depends_t *dep = curInst->depends; + while (dep) + { + if (0 == dep->isReady && 0 == strcmp (dep->name, inst->name)) + { + dep->isReady = 1; /* Don't break for case that duplicate name exist, though I think it should + not happen */ + } + dep = dep->next; + } + } + nextLoop: + curInst = curInst->next; + } + +} + +/** + * @Function nstack_framework_init + * @Description Init child modules + * @param father instance , NULL means root + * @return 0 on success, -1 on error + */ +NSTACK_STATIC int +nstack_framework_initChild_unsafe (nsfw_module_instance_t * father) +{ + NSFW_LOGDBG ("init framework module] name=%s", + father ? father->name : "NULL"); + + nsfw_module_instance_t *inst = nsfw_module_getManager ()->inst; + + while (inst) + { + NSFW_LOGDBG + ("init child] inst=%s, inst->father=%s, inst->depends=%s, inst->state=%d", + inst->name, inst->father ? inst->father->name : "NULL", + inst->depends ? inst->depends->name : "NULL", inst->stat); + + if (father != inst->father) + { + NSFW_LOGDBG ("inst->father not match] inst=%s, ", inst->name); + + inst = inst->next; + continue; + } + + switch (inst->stat) + { + case NSFW_INST_STAT_CHECKING: + /* First, check if any depends, then check if other instance depends on it */ + if (nsfw_module_instance_isIndepend (inst)) + { + inst->stat = NSFW_INST_STAT_DEPENDING; + NSFW_LOGDBG ("inst is still depending] name=%s", inst->name); + inst = inst->next; + break; + } + + NSFW_LOGINF ("Going to init module] name=%s, init fun=%p", + inst->name, inst->fnInit); + if (NULL != inst->fnInit && 0 != inst->fnInit (inst->param)) + { + NSFW_LOGERR ("initial fail!!!] inst=%s", inst->name); + inst->stat = NSFW_INST_STAT_FAIL; + return -1; + } + + inst->stat = NSFW_INST_STAT_DONE; + nsfw_module_instance_depend_check (inst); + + if (-1 == nsfw_module_addDoneNode (inst)) + { + NSFW_LOGERR ("add done node fail"); + } + + inst = nsfw_module_getManager ()->inst; /* check from begining */ + break; + case NSFW_INST_STAT_DEPENDING: + /* check if depending stat is still there */ + if (!nsfw_module_instance_isIndepend (inst)) + { + inst->stat = NSFW_INST_STAT_CHECKING; + break; + } + case NSFW_INST_STAT_FAIL: + case NSFW_INST_STAT_DONE: + default: + inst = inst->next; + break; + } + } + + return 0; +} + +NSTACK_STATIC void +nstack_framework_printInstanceInfo (nsfw_module_instance_t * inst) +{ + + if (NULL == inst) + { + NSFW_LOGERR ("param error,inst==NULL"); + return; + } + + char info[1024] = ""; + int plen = 0; + + int ret = SPRINTF_S (info, sizeof (info), "Inst:%s,father:%s,depends:", + inst->name, + inst->father ? inst->father->name : "NULL"); + + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", inst->name, + inst->stat, ret); + return; + } + else + { + plen += ret; + } + + if (NULL == inst->depends) + { + ret = SPRINTF_S (info + plen, sizeof (info) - plen, "NULL"); + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", + inst->name, inst->stat, ret); + return; + } + NSFW_LOGINF ("] inst info=%s", info); + return; + } + + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + ret = SPRINTF_S (info + plen, sizeof (info) - plen, "%s ", dep->name); + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", + inst->name, inst->stat, ret); + return; + } + plen += ret; + dep = dep->next; + } + + NSFW_LOGINF ("] inst info=%s", info); +} + +NSTACK_STATIC void +nstack_framework_printInitialResult () +{ + nsfw_module_manager_t *manager = nsfw_module_getManager (); + + if (manager->doneHead) + { + NSFW_LOGINF ("Here is the initial done modules: "); + + nsfw_module_doneNode_t *curNode = manager->doneHead; + while (curNode) + { + nstack_framework_printInstanceInfo (curNode->inst); + curNode = curNode->next; + } + } + else + { + NSFW_LOGERR ("No initial done modules"); + } + + nsfw_module_instance_t *curInst = manager->inst; + int unDoneNum = 0; + while (curInst) + { + if (curInst->stat != NSFW_INST_STAT_DONE) + { + if (0 == unDoneNum) + { + NSFW_LOGINF ("Here is the unInited modules:"); + } + unDoneNum++; + nstack_framework_printInstanceInfo (curInst); + } + curInst = curInst->next; + } + if (0 == unDoneNum) + NSFW_LOGINF ("All modules are inited"); +} + +/** + * @Function nstack_framework_init + * @Description This function will do framework initial work, it will involk all initial functions + * registed using macro NSFW_MODULE_INIT before + * @param none + * @return 0 on success, -1 on error + */ +int +nstack_framework_init (void) +{ + int ret = -1; + if (nsfw_module_getManager ()->done) + { + goto init_finished; + } + + if (pthread_mutex_lock (&nsfw_module_getManager ()->initMutex)) + { + return -1; + } + + if (nsfw_module_getManager ()->done) + { + goto done; + } + + ret = nstack_framework_initChild_unsafe (NULL); + + if (0 == ret) + { + nsfw_module_getManager ()->done = 1; + } + else + { + nsfw_module_getManager ()->done = -1; + } + + // Going to print done modules and undone modules + nstack_framework_printInitialResult (); + +done: + if (pthread_mutex_unlock (&nsfw_module_getManager ()->initMutex)) + { + return -1; + } +init_finished: + ret = nsfw_module_getManager ()->done == 1 ? 0 : -1; + return ret; +} + +/** + * @Function nstack_framework_setModuleParam + * @Description This function set parameter of module initial function parameter + * @param module - name of module + * @param param - parameter to set + * @return 0 on success, -1 on error + */ +int +nstack_framework_setModuleParam (char *module, void *param) +{ + nsfw_module_instance_t *inst = nsfw_module_getModuleByName (module); + if (!inst) + return -1; + + inst->param = param; + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/init/fw_module.c b/src/framework/init/fw_module.c new file mode 100644 index 0000000..65bbb0a --- /dev/null +++ b/src/framework/init/fw_module.c @@ -0,0 +1,331 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <memory.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "nstack_securec.h" +#include "fw_module.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +COMPAT_PROTECT (NSFW_MOUDLE_INSTANCE_POOL_SIZE, 64); +COMPAT_PROTECT (NSFW_MOUDLE_DEPENDS_POOL_SIZE, 128); + +nsfw_module_instance_pool_t g_nsfw_module_inst_pool; +nsfw_module_depends_pool_t g_nsfw_module_deps_pool; + +/* +* WARNING!!!: +* This function is only used in constructor progress. Multi-thread concurrent is not supported! +*/ +NSTACK_STATIC nsfw_module_instance_t * +nsfw_module_malloc_instance () +{ + if (g_nsfw_module_inst_pool.last_idx >= NSFW_MOUDLE_INSTANCE_POOL_SIZE) + { + return NULL; + } + return + &g_nsfw_module_inst_pool.module_instance_pool[g_nsfw_module_inst_pool. + last_idx++]; +} + +/* +* WARNING!!!: +* This function is only used in constructor progress. Multi-thread concurrent is not supported! +*/ +NSTACK_STATIC nsfw_module_depends_t * +nsfw_module_malloc_depends () +{ + if (g_nsfw_module_deps_pool.last_idx >= NSFW_MOUDLE_DEPENDS_POOL_SIZE) + { + return NULL; + } + return + &g_nsfw_module_deps_pool.module_depends_pool[g_nsfw_module_deps_pool. + last_idx++]; +} + +NSTACK_STATIC void +nsfw_module_setChildInstance (nsfw_module_instance_t * + father, nsfw_module_instance_t * child) +{ + if (NULL == father || NULL == child) + return; + child->father = father; +} + +nsfw_module_depends_t * +nsfw_module_create_depends (char *name) +{ + if (NULL == name) + return NULL; + + /*Change module malloc to pool array */ + nsfw_module_depends_t *dep = nsfw_module_malloc_depends (); + + if (NULL == dep) + return NULL; + + if (EOK != + MEMSET_S (dep, sizeof (nsfw_module_depends_t), 0, + sizeof (nsfw_module_depends_t))) + { + goto fail; + } + + /*change destMax from nameSize - 1 to sizeof(dep->name) */ + if (EOK != STRCPY_S (dep->name, sizeof (dep->name), name)) + { + goto fail; + } + dep->isReady = 0; + + return dep; + +fail: + // NOTE: if dep is not null, we do not free it and just leave it there. + return NULL; +} + +nsfw_module_instance_t * +nsfw_module_create_instance (void) +{ + /*Change module malloc to pool array */ + nsfw_module_instance_t *inst = nsfw_module_malloc_instance (); + if (NULL == inst) + return NULL; + + if (EOK != + MEMSET_S (inst, sizeof (nsfw_module_instance_t), 0, + sizeof (nsfw_module_instance_t))) + { + // NOTE: if inst is not null, we do not free it and just leave it there. + return NULL; + } + + inst->stat = NSFW_INST_STAT_CHECKING; + return inst; +} + +void +nsfw_module_set_instance_name (nsfw_module_instance_t * inst, char *name) +{ + if (NULL == inst || NULL == name || inst->name[0] != '\0') + { + return; + } + + /*change destMax from nameSize - 1 to sizeof(inst->name) */ + if (EOK != STRCPY_S (inst->name, sizeof (inst->name), name)) + { + return; + } + + // Now we need to search if it's any instance's father + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (curInst == inst) + goto next_loop; + + if (0 == strcmp (curInst->fatherName, inst->name) + && NULL == curInst->father) + { + nsfw_module_setChildInstance (inst, curInst); + } + next_loop: + curInst = curInst->next; + } + return; +} + +void +nsfw_module_set_instance_father (nsfw_module_instance_t * inst, + char *fatherName) +{ + if (NULL == inst || NULL == fatherName) + { + return; + } + + if (EOK != + STRCPY_S (inst->fatherName, sizeof (inst->fatherName), fatherName)) + { + return; + } + + nsfw_module_instance_t *fatherInst = + nsfw_module_getModuleByName (fatherName); + if (fatherInst) + { + nsfw_module_setChildInstance (fatherInst, inst); + } + return; +} + +void +nsfw_module_set_instance_priority (nsfw_module_instance_t * inst, + int priority) +{ + if (NULL == inst) + return; + inst->priority = priority; + + nsfw_module_del_instance (inst); + nsfw_module_add_instance (inst); + return; +} + +void +nsfw_module_set_instance_initfn (nsfw_module_instance_t * inst, + nsfw_module_init_fn fn) +{ + if (NULL == inst) + return; + inst->fnInit = fn; + return; +} + +void +nsfw_module_set_instance_depends (nsfw_module_instance_t * inst, char *name) +{ + if (NULL == inst || name == NULL) + return; + + // Check if depends already set + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + if (0 == strcmp (dep->name, name)) + return; + dep = dep->next; + } + + dep = nsfw_module_create_depends (name); + if (NULL == dep) + return; + + if (NULL == inst->depends) + inst->depends = dep; + else + inst->depends->next = dep; +} + +/* *INDENT-OFF* */ +nsfw_module_manager_t g_nsfw_module_manager = {.inst = NULL, .initMutex = + PTHREAD_MUTEX_INITIALIZER, .done = 0}; +/* *INDENT-ON* */ + +void +nsfw_module_add_instance (nsfw_module_instance_t * inst) +{ + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + + if (NULL == curInst || curInst->priority > inst->priority) + { + inst->next = curInst; + nsfw_module_getManager ()->inst = inst; + } + else + { + while (curInst->next && curInst->next->priority <= inst->priority) + { + curInst = curInst->next; + } + inst->next = curInst->next; + curInst->next = inst; + } +} + +void +nsfw_module_del_instance (nsfw_module_instance_t * inst) +{ + if (nsfw_module_getManager ()->inst == inst) + { + nsfw_module_getManager ()->inst = inst->next; + return; + } + + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + + while (curInst->next && curInst->next != inst) + curInst = curInst->next; + + if (!curInst->next) + return; + curInst->next = inst->next; +} + +nsfw_module_instance_t * +nsfw_module_getModuleByName (char *name) +{ + if (NULL == name) + return NULL; + + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (0 == strcmp (curInst->name, name)) + { + return curInst; + } + curInst = curInst->next; + } + + return NULL; +} + +int +nsfw_module_addDoneNode (nsfw_module_instance_t * inst) +{ + nsfw_module_doneNode_t *node = + (nsfw_module_doneNode_t *) malloc (sizeof (nsfw_module_doneNode_t)); + if (NULL == node) + return -1; + node->inst = inst; + node->next = NULL; + + nsfw_module_manager_t *manager = nsfw_module_getManager (); + if (NULL == manager->doneHead) + { + manager->doneHead = node; + } + else + { + nsfw_module_doneNode_t *tail = manager->doneHead; + while (tail->next) + { + tail = tail->next; + } + + tail->next = node; + } + + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/init/fw_module.h b/src/framework/init/fw_module.h new file mode 100644 index 0000000..1cfc95f --- /dev/null +++ b/src/framework/init/fw_module.h @@ -0,0 +1,85 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _FW_MODULE +#define _FW_MODULE +#include <pthread.h> + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +#include "nsfw_init.h" + +/* Unique name declare */ +#define NSFW__STRINGIFY(x) #x +#define NSFW_STRINGIFY(x) NSFW__STRINGIFY(x) + +#define NSFW__PASTE(a,b) a##b +#define NSFW_PASTE(a,b) NSFW__PASTE(a,b) + +#define NSFW_UNIQUE_ID(prefix) NSFW_PASTE(NSFW_PASTE(__LINE__, prefix), __COUNTER__) + +#define NSFW_MODULE_INITFN(_fn) \ + static int _fn(void* param) +extern nsfw_module_depends_t *nsfw_module_create_depends (char *name); + +#define NSFW_MODULE_SET_STATE(inst, state) ((inst)->stat = (state)) + +typedef struct _nsfw_module_doneNode +{ + nsfw_module_instance_t *inst; + struct _nsfw_module_doneNode *next; +} nsfw_module_doneNode_t; + +typedef struct _nsfw_module_manager +{ + pthread_mutex_t initMutex; + int done; // 0 - not finished, 1 - finished, -1 - error + nsfw_module_instance_t *inst; + nsfw_module_doneNode_t *doneHead; +} nsfw_module_manager_t; + +extern int nsfw_module_addDoneNode (nsfw_module_instance_t * inst); + +extern nsfw_module_manager_t g_nsfw_module_manager; +#define nsfw_module_getManager() (&g_nsfw_module_manager) + +#define NSFW_MOUDLE_INSTANCE_POOL_SIZE 64 +#define NSFW_MOUDLE_DEPENDS_POOL_SIZE 128 + +typedef struct _nsfw_module_instance_pool +{ + int last_idx; + nsfw_module_instance_t + module_instance_pool[NSFW_MOUDLE_INSTANCE_POOL_SIZE]; +} nsfw_module_instance_pool_t; + +typedef struct _nsfw_module_depends_pool +{ + int last_idx; + nsfw_module_depends_t module_depends_pool[NSFW_MOUDLE_DEPENDS_POOL_SIZE]; +} nsfw_module_depends_pool_t; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +#endif /* _FW_MODULE */ |