From 697ade6190b23c80e7f60963983786e679759393 Mon Sep 17 00:00:00 2001 From: qchang Date: Thu, 8 Mar 2018 17:39:22 -0800 Subject: dmm initial commit Change-Id: I049ee277cf4efdb83f9c2ac439365fcd421c159b Signed-off-by: qchang --- .../common/base/include/common/common_func.h | 98 ++ .../common/base/include/common/common_mem_api.h | 144 +++ .../base/include/common/common_mem_base_type.h | 85 ++ .../common/base/include/common/common_mem_buf.h | 75 ++ .../common/base/include/common/common_mem_common.h | 25 + .../common/base/include/common/common_mem_malloc.h | 25 + .../common/base/include/common/common_mem_mbuf.h | 40 + .../base/include/common/common_mem_mempool.h | 25 + .../base/include/common/common_mem_memzone.h | 25 + .../common/base/include/common/common_mem_pal.h | 30 + .../base/include/common/common_mem_pal_memconfig.h | 26 + .../base/include/common/common_mem_spinlock.h | 40 + .../common/base/include/common/common_sys_config.h | 46 + .../include/common/generic/common_mem_rwlock.h | 25 + .../base/include/common_pal_bitwide_adjust.h | 222 +++++ .../common/base/include/nsfw_base_linux_api.h | 58 ++ src/framework/common/base/include/nsfw_getopt.h | 50 ++ .../base/liblinuxapi/base_linux_api_declare.h | 51 ++ .../common/base/liblinuxapi/nsfw_base_linux_api.c | 628 +++++++++++++ .../common/base/liblinuxapi/nsfw_getopt.c | 455 ++++++++++ .../common/base/liblinuxapi/nsfw_lock_file.c | 174 ++++ src/framework/common/data_struct/eprb_tree.c | 492 ++++++++++ src/framework/common/data_struct/list.c | 163 ++++ src/framework/common/data_struct/pidinfo.c | 125 +++ src/framework/common/data_struct/sha256.c | 397 +++++++++ src/framework/common/include/compile_config.h | 30 + src/framework/common/include/compiling_check.h | 106 +++ src/framework/common/include/ephlist.h | 199 +++++ src/framework/common/include/eprb_tree.h | 84 ++ src/framework/common/include/list.h | 181 ++++ src/framework/common/include/pidinfo.h | 48 + src/framework/common/include/sha256.h | 94 ++ src/framework/common/include/types.h | 97 ++ .../common/mem_mgr/include/nsfw_mem_desc.h | 172 ++++ .../common/mem_mgr/include/nsfw_ring_data.h | 95 ++ .../common/mem_mgr/include/nsfw_ring_fun.h | 110 +++ src/framework/common/mem_mgr/nsfw_mem_api.c | 879 ++++++++++++++++++ src/framework/common/mem_mgr/nsfw_mem_construct.c | 21 + src/framework/common/mem_mgr/nsfw_mem_desc.c | 92 ++ src/framework/common/mem_mgr/nsfw_mem_stat.c | 292 ++++++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c | 47 + .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h | 22 + .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c | 544 ++++++++++++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h | 70 ++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c | 436 +++++++++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h | 37 + src/framework/common/mem_mgr/nsfw_res_mgr.c | 429 +++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c | 987 +++++++++++++++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h | 51 ++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c | 47 + .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h | 22 + .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c | 880 ++++++++++++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h | 133 +++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c | 839 ++++++++++++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h | 60 ++ 55 files changed, 10628 insertions(+) create mode 100644 src/framework/common/base/include/common/common_func.h create mode 100644 src/framework/common/base/include/common/common_mem_api.h create mode 100644 src/framework/common/base/include/common/common_mem_base_type.h create mode 100644 src/framework/common/base/include/common/common_mem_buf.h create mode 100644 src/framework/common/base/include/common/common_mem_common.h create mode 100644 src/framework/common/base/include/common/common_mem_malloc.h create mode 100644 src/framework/common/base/include/common/common_mem_mbuf.h create mode 100644 src/framework/common/base/include/common/common_mem_mempool.h create mode 100644 src/framework/common/base/include/common/common_mem_memzone.h create mode 100644 src/framework/common/base/include/common/common_mem_pal.h create mode 100644 src/framework/common/base/include/common/common_mem_pal_memconfig.h create mode 100644 src/framework/common/base/include/common/common_mem_spinlock.h create mode 100644 src/framework/common/base/include/common/common_sys_config.h create mode 100644 src/framework/common/base/include/common/generic/common_mem_rwlock.h create mode 100644 src/framework/common/base/include/common_pal_bitwide_adjust.h create mode 100644 src/framework/common/base/include/nsfw_base_linux_api.h create mode 100644 src/framework/common/base/include/nsfw_getopt.h create mode 100644 src/framework/common/base/liblinuxapi/base_linux_api_declare.h create mode 100644 src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c create mode 100644 src/framework/common/base/liblinuxapi/nsfw_getopt.c create mode 100644 src/framework/common/base/liblinuxapi/nsfw_lock_file.c create mode 100644 src/framework/common/data_struct/eprb_tree.c create mode 100644 src/framework/common/data_struct/list.c create mode 100644 src/framework/common/data_struct/pidinfo.c create mode 100644 src/framework/common/data_struct/sha256.c create mode 100644 src/framework/common/include/compile_config.h create mode 100644 src/framework/common/include/compiling_check.h create mode 100644 src/framework/common/include/ephlist.h create mode 100644 src/framework/common/include/eprb_tree.h create mode 100644 src/framework/common/include/list.h create mode 100644 src/framework/common/include/pidinfo.h create mode 100644 src/framework/common/include/sha256.h create mode 100644 src/framework/common/include/types.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_mem_desc.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_ring_data.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_ring_fun.h create mode 100644 src/framework/common/mem_mgr/nsfw_mem_api.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_construct.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_desc.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_stat.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h create mode 100644 src/framework/common/mem_mgr/nsfw_res_mgr.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h (limited to 'src/framework/common') diff --git a/src/framework/common/base/include/common/common_func.h b/src/framework/common/base/include/common/common_func.h new file mode 100644 index 0000000..fdf2802 --- /dev/null +++ b/src/framework/common/base/include/common/common_func.h @@ -0,0 +1,98 @@ +/* +* +* 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 _RTE_COMM_FUNC_H_ +#define _RTE_COMM_FUNC_H_ + +#ifdef HAL_LIB + +#else + +#define common_mem_rwlock_t rte_rwlock_t +#define common_mem_spinlock_t rte_spinlock_t + //typedef rte_rwlock_t common_mem_rwlock_t; + +#define nsfw_write_lock(plock) rte_rwlock_write_lock(plock) +#define nsfw_write_unlock(plock) rte_rwlock_write_unlock(plock) +#define nsfw_read_lock(plock) rte_rwlock_read_lock(plock) +#define nsfw_read_unlock(plock) rte_rwlock_read_unlock(plock) + +#define common_mem_align32pow2 rte_align32pow2 + +#define common_mem_atomic32_cmpset rte_atomic32_cmpset +#define common_mem_pause rte_pause + +#define COMMON_MEM_MAX_MEMZONE RTE_MAX_MEMZONE + +#define common_mem_atomic32_t rte_atomic32_t + +#define common_mem_memseg rte_memseg +#define common_mem_mem_config rte_mem_config + +#define common_mem_pal_get_configuration rte_eal_get_configuration + + //#define commem_mem_pal_module_info rte_eal_module_info + // +#define common_mem_pal_init rte_eal_init + +#define COMMON_MEM_MEMPOOL_NAMESIZE RTE_MEMPOOL_NAMESIZE + +#define common_mem_memzone_lookup rte_memzone_lookup +#define common_mem_memzone rte_memzone +#define common_mem_atomic32_add_return rte_atomic32_add_return + +#define common_mem_spinlock_init rte_spinlock_init +#define common_mem_spinlock_lock rte_spinlock_lock +#define common_mem_spinlock_unlock rte_spinlock_unlock + +#define common_mem_memzone_free rte_memzone_free +#define common_mem_pktmbuf_pool_create rte_pktmbuf_pool_create + +#define common_mem_pktmbuf_alloc rte_pktmbuf_alloc + +#define common_mem_mempool rte_mempool + +#define common_mem_pktmbuf_free rte_pktmbuf_free +#define common_mem_mbuf rte_mbuf + +#define common_mem_mempool_lookup rte_mempool_lookup + +#define common_mem_ring_get_memsize rte_ring_get_memsize +#define common_mem_ring rte_ring + +#define COMMON_MEM_MAX_MEMSEG RTE_MAX_MEMSEG + +#define common_mem_memzone_reserve rte_memzone_reserve +#define common_mem_rwlock_read_lock rte_rwlock_read_lock +#define common_mem_rwlock_read_unlock rte_rwlock_read_unlock + +#define common_mem_rwlock_write_lock rte_rwlock_write_lock +#define common_mem_rwlock_write_unlock rte_rwlock_write_unlock +#define common_mem_spinlock_trylock rte_spinlock_trylock + +#define common_mem_socket_id rte_socket_id +#define common_mem_malloc_socket_stats rte_malloc_socket_stats + +#define COMMON_MEM_MIN RTE_MIN + +#define common_pal_module_init nscomm_pal_module_init +#define common_memzone_data_reserve_name nscomm_memzone_data_reserve_name +#define common_memzone_data_lookup_name nscomm_memzone_data_lookup_name + +#define common_dump_stack rte_dump_stack +#endif + +#endif // _RTE_COMM_FUNC_H_ diff --git a/src/framework/common/base/include/common/common_mem_api.h b/src/framework/common/base/include/common/common_mem_api.h new file mode 100644 index 0000000..9eb4344 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_api.h @@ -0,0 +1,144 @@ +/* +* +* 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 __COMMON_MEM_API_H__ +#define __COMMON_MEM_API_H__ + +#ifdef HAL_LIB +#else + +#include "rte_atomic.h" +#include "common_mem_spinlock.h" +#include +#include +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#ifndef NSTACK_LINT_CODE_DISABLE +#define NSTACK_LINT_CODE_DISABLE(code) /*lint -e#code */ +#endif + +#ifndef NSTACK_LINT_CODE_ENABLE +#define NSTACK_LINT_CODE_ENABLE(code) /*lint +e#code */ +#endif + +#define SYS_MBOX_NULL (sys_mbox_t)0 + +typedef sem_t *sys_sem_t_v1; +typedef sem_t sys_sem_st_v1; +typedef struct queue *sys_mbox_t; + +typedef rte_spinlock_t *sys_sem_t_v2; +typedef rte_spinlock_t sys_sem_st_v2; + +#ifndef u32_t +typedef uint32_t u32_t; +#endif + +#ifndef u8_t +typedef uint8_t u8_t; +#endif + +#ifndef s8_t +typedef int8_t s8_t; +#endif + +#ifndef err_t +typedef s8_t err_t; +#endif + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +void sys_sem_signal_s_v2 (sys_sem_t_v2 sem); +void sys_sem_init_v2 (sys_sem_t_v2 sem); + +u32_t sys_arch_sem_wait_s_v2 (sys_sem_t_v2 sem); + +#define SYS_HOST_INITIAL_PID 1 +extern volatile pid_t g_sys_host_pid; +pid_t sys_get_hostpid_from_file (pid_t pid); +static inline pid_t +get_sys_pid () +{ + if (SYS_HOST_INITIAL_PID == g_sys_host_pid) + (void) sys_get_hostpid_from_file (getpid ()); + return g_sys_host_pid; +} + +pid_t updata_sys_pid (); +long sys_now (void); + +#define sys_sem_t sys_sem_t_v2 +#define sys_sem_st sys_sem_st_v2 +#define sys_sem_new(sem, count) sys_sem_new_v2(sem, count) +#define sys_sem_free(sem) sys_sem_free_v2(sem) +#define sys_sem_signal(sem) sys_sem_signal_v2(sem) +#define sys_arch_sem_wait(sem, timeout) sys_arch_sem_wait_v2(sem) +#define sys_arch_sem_trywait(sem) sys_arch_sem_trywait_v2(sem) + +#define sys_sem_init(sem) sys_sem_init_v2(sem) +#define sys_sem_s_signal(sem) sys_sem_signal_s_v2(sem) +#define sys_arch_sem_s_wait(sem, timeout) sys_arch_sem_wait_s_v2(sem) +#define sys_arch_lock_with_pid(sem) (void)sys_arch_lock_with_pid_v2(sem) + +#define BUF_SIZE_FILEPATH 256 +#define STR_PID "pid:" +#define READ_FILE_BUFLEN 512 + +extern pid_t sys_get_hostpid_from_file (pid_t pid); +extern pid_t get_hostpid_from_file (u32_t pid); +extern void get_exec_name_by_pid (pid_t pid, char *task_name, + int task_name_len); + +static inline u32_t +sys_arch_lock_with_pid_v2 (sys_sem_t_v2 sem) +{ + if (SYS_HOST_INITIAL_PID == g_sys_host_pid) + (void) sys_get_hostpid_from_file (getpid ()); + dmm_spinlock_lock_with_pid (sem, g_sys_host_pid); + return 0; +} + +#define NSTACK_SEM_MALLOC(sys_sem,count) \ +{ \ + rte_spinlock_init(&(sys_sem)); \ + /*lint -e506*/\ + if (!(count)) \ + /*lint +e506*/\ + { \ + rte_spinlock_lock(&(sys_sem)); \ + } \ +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#endif + +#endif /* __COMMON_MEM_API_H__ */ diff --git a/src/framework/common/base/include/common/common_mem_base_type.h b/src/framework/common/base/include/common/common_mem_base_type.h new file mode 100644 index 0000000..01707d9 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_base_type.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 _COMMON_MEM_BASE_TYPE_H_ +#define _COMMON_MEM_BASE_TYPE_H_ + +#ifdef HAL_LIB + +#else + +#define ALIGN_TYPE uint64_t +#define PTR_ALIGN_TYPE uint64_t + +/*alignment define*/ +#define ALIGNMENT_DEF(name, type, aligntype) \ + union { \ + type name; \ + aligntype name##_align; \ + } + +#define PTR_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, PTR_ALIGN_TYPE) + +#define OTHER_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, ALIGN_TYPE) + +/* + * * List definitions. + * */ +#define DMM_LIST_HEAD(name, type) \ +struct name { \ + PTR_ALIGNMENT_DEF(lh_first, struct type *); /* first element */ \ +} + +#define DMM_LIST_ENTRY(type) \ +struct { \ + PTR_ALIGNMENT_DEF(le_next, struct type *); /* next element */\ + PTR_ALIGNMENT_DEF(le_prev, struct type **); /* address of previous next element */ \ +} + +/* + * * Tail queue definitions. + * */ +#define _DMM_TAILQ_HEAD(name, type, qual) \ +struct name { \ + PTR_ALIGNMENT_DEF(tqh_first, qual type *); /* first element */ \ + PTR_ALIGNMENT_DEF(tqh_last, qual type * qual *); /* addr of last next element */ \ +} + +#define DMM_TAILQ_HEAD(name, type) _DMM_TAILQ_HEAD(name, struct type,) + +#define _DMM_TAILQ_ENTRY(type, qual) \ +struct { \ + PTR_ALIGNMENT_DEF(tqe_next, qual type *); /* next element */\ + PTR_ALIGNMENT_DEF(tqe_prev, qual type * qual*); /* address of previous next element */\ +} +#define DMM_TAILQ_ENTRY(type) _DMM_TAILQ_ENTRY(struct type,) + +/* + * * Singly-linked Tail queue declarations. + * */ +#define DMM_STAILQ_HEAD(name, type) \ + struct name { \ + PTR_ALIGNMENT_DEF(stqh_first, struct type *); /* first element */ \ + PTR_ALIGNMENT_DEF(stqh_last, struct type **); /* addr of last next element */ \ + } + +#define DMM_STAILQ_ENTRY(type) \ + struct { \ + PTR_ALIGNMENT_DEF(stqe_next, struct type *); /* next element */ \ + } +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_buf.h b/src/framework/common/base/include/common/common_mem_buf.h new file mode 100644 index 0000000..d0d3588 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_buf.h @@ -0,0 +1,75 @@ +/* +* +* 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 _COMMON_MEM_BUF_H_ +#define _COMMON_MEM_BUF_H_ + +#ifdef HAL_LIB +#else + +#include "common_mem_base_type.h" + +typedef enum __DMM_PROC_TYPE +{ + DMM_PROC_T_AUTO = 0, /*auto detect */ + DMM_PROC_T_PRIMARY = 1, /* set to primary */ + DMM_PROC_T_SECONDARY = 2, /* set to seconday */ + DMM_PROC_T_INVALID +} DMM_PROC_TYPE; + +#define DMM_MBUF_RET_OK 0 +#define DMM_MBUF_RET_ERR 1 + +#define LCORE_MAX 128 +#define LCORE_MASK_PER (sizeof(int) * 8) +#define LCORE_MASK_MAX (LCORE_MAX/LCORE_MASK_PER) + +#define LCORE_MASK_SET(ilcoremask, value) \ + if (value < LCORE_MAX) \ + { \ + ilcoremask[(value/LCORE_MASK_PER)] = (int) ( (ilcoremask[(value/LCORE_MASK_PER)]) | (1< (value%LCORE_MASK_PER))); \ + } \ + +#define DMM_HUGTBL_ENABLE 0 +#define DMM_HUGTBL_DISABLE 1 + +typedef struct __common_pal_module_info +{ + int ishare_mem_size; /*shared memory size */ + int ilcoremask[LCORE_MASK_MAX]; + /**/ unsigned char uchugeflag; + unsigned char ucproctype; + unsigned char ucinstance; + unsigned char ucresrv2; +} common_mem_pal_module_info; + +/** + * rte pal module init. + * + * + * @param name + * The name of the buf pool. + */ +int nscomm_pal_module_init (common_mem_pal_module_info * pinfo); + +void *nscomm_memzone_data_reserve_name (const char *name, size_t len, + int socket_id); + +void *nscomm_memzone_data_lookup_name (const char *name); + +#endif + +#endif /* _COMMON_MEM_BUF_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_common.h b/src/framework/common/base/include/common/common_mem_common.h new file mode 100644 index 0000000..1e4cf56 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_common.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_COMMON_H_ +#define _COMMON_MEM_COMMON_H_ + +#ifdef HAL_LIB +#else +#include "rte_common.h" +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_malloc.h b/src/framework/common/base/include/common/common_mem_malloc.h new file mode 100644 index 0000000..68721cd --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_malloc.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MALLOC_H_ +#define _COMMON_MEM_MALLOC_H_ + +#ifdef HAL_LIB +#else +#include "rte_malloc.h" +#endif + +#endif /* _COMMON_MEM_MALLOC_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_mbuf.h b/src/framework/common/base/include/common/common_mem_mbuf.h new file mode 100644 index 0000000..0bb7696 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_mbuf.h @@ -0,0 +1,40 @@ +/* +* +* 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. +*/ + +/******************************************************************* + Copyright 2017 - 2047, Huawei Tech. Co., Ltd. + ALL RIGHTS RESERVED + +Filename : common_mem_mbuf.h +Description : +Version : 1.1 +********************************************************************/ + +#ifndef _COMMON_MEM_MBUF_H_ +#define _COMMON_MEM_MBUF_H_ + +#ifdef HAL_LIB +#else +#include "rte_mbuf.h" +#include "common_func.h" + +typedef uint32_t (*dmm_mbuf_item_fun) (void *data, void *argv); +int32_t dmm_pktmbuf_pool_iterator (struct common_mem_mempool *mp, + uint32_t start, uint32_t end, + dmm_mbuf_item_fun fun, void *argv); +#endif + +#endif /* _COMMON_MEM_MBUF_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_mempool.h b/src/framework/common/base/include/common/common_mem_mempool.h new file mode 100644 index 0000000..58a8e82 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_mempool.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MEMPOOL_H_ +#define _COMMON_MEM_MEMPOOL_H_ + +#ifdef HAL_LIB +#else +#include "rte_mempool.h" +#endif + +#endif /* _COMMON_MEM_MEMPOOL_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_memzone.h b/src/framework/common/base/include/common/common_mem_memzone.h new file mode 100644 index 0000000..20e18c2 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_memzone.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MEMZONE_H_ +#define _COMMON_MEM_MEMZONE_H_ + +#ifdef HAL_LIB +#else +#include "rte_memzone.h" +#endif + +#endif /* _COMMON_MEM_MEMZONE_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_pal.h b/src/framework/common/base/include/common/common_mem_pal.h new file mode 100644 index 0000000..209b8bd --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_pal.h @@ -0,0 +1,30 @@ +/* +* +* 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 _COMMON_MEM_PAL_H_ +#define _COMMON_MEM_PAL_H_ + +#ifdef HAL_LIB +#else + +#include "nsfw_base_linux_api.h" + +/*print the map address*/ +void dmm_addr_print (void); + +#endif + +#endif /* _COMMON_MEM_PAL_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_pal_memconfig.h b/src/framework/common/base/include/common/common_mem_pal_memconfig.h new file mode 100644 index 0000000..65b6e04 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_pal_memconfig.h @@ -0,0 +1,26 @@ +/* +* +* 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 _COMMON_MEM_PAL_MEMCONFIG_H_ +#define _COMMON_MEM_PAL_MEMCONFIG_H_ + +#ifdef HAL_LIB +#else +#include "rte_eal_memconfig.h" + +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_spinlock.h b/src/framework/common/base/include/common/common_mem_spinlock.h new file mode 100644 index 0000000..23f6b1e --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_spinlock.h @@ -0,0 +1,40 @@ +/* +* +* 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 _COMMON_MEM_SPINLOCK_X86_64_H_ +#define _COMMON_MEM_SPINLOCK_X86_64_H_ + +#ifdef HAL_LIB +#else +#include "rte_spinlock.h" + +static inline void +dmm_spinlock_lock_with_pid (rte_spinlock_t * sl, int pid) +{ + while (!__sync_bool_compare_and_swap (&sl->locked, 0, pid)) + while (sl->locked) + rte_pause (); +} + +static inline int +dmm_spinlock_try_lock_with_pid (rte_spinlock_t * sl, int pid) +{ + return __sync_bool_compare_and_swap (&sl->locked, 0, pid); +} + +#endif + +#endif /* _COMMON_MEM_SPINLOCK_X86_64_H_ */ diff --git a/src/framework/common/base/include/common/common_sys_config.h b/src/framework/common/base/include/common/common_sys_config.h new file mode 100644 index 0000000..552cae3 --- /dev/null +++ b/src/framework/common/base/include/common/common_sys_config.h @@ -0,0 +1,46 @@ +/* +* +* 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 __COMMON_SYS_CONFIG_H_ +#define __COMMON_SYS_CONFIG_H_ + +/* Below compile macro is used only in UT makefile */ +#if (HAL_LIB) +#else +#undef RTE_CACHE_LINE_SIZE +#define RTE_CACHE_LINE_SIZE 64 +#undef RTE_MAX_LCORE +#define RTE_MAX_LCORE 128 +#undef RTE_MAX_NUMA_NODES +#define RTE_MAX_NUMA_NODES 8 +#undef RTE_MAX_MEMSEG +#define RTE_MAX_MEMSEG 256 +#undef RTE_MAX_MEMZONE +#define RTE_MAX_MEMZONE 2560 +#undef RTE_MAX_TAILQ +#define RTE_MAX_TAILQ 32 +#undef RTE_ARCH_X86 +#define RTE_ARCH_X86 1 +#undef RTE_ARCH_64 +#define RTE_ARCH_64 1 +#undef RTE_PKTMBUF_HEADROOM +#define RTE_PKTMBUF_HEADROOM 128 +#undef RTE_MEMPOOL_CACHE_MAX_SIZE +#define RTE_MEMPOOL_CACHE_MAX_SIZE 512 + +#endif + +#endif // __COMMON_SYS_CONFIG_H_ diff --git a/src/framework/common/base/include/common/generic/common_mem_rwlock.h b/src/framework/common/base/include/common/generic/common_mem_rwlock.h new file mode 100644 index 0000000..2eed259 --- /dev/null +++ b/src/framework/common/base/include/common/generic/common_mem_rwlock.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_RWLOCK_H_ +#define _COMMON_MEM_RWLOCK_H_ + +#ifdef HAL_LIB +#else +#include "rte_rwlock.h" +#endif + +#endif /* _COMMON_MEM_RWLOCK_H_ */ diff --git a/src/framework/common/base/include/common_pal_bitwide_adjust.h b/src/framework/common/base/include/common_pal_bitwide_adjust.h new file mode 100644 index 0000000..850742b --- /dev/null +++ b/src/framework/common/base/include/common_pal_bitwide_adjust.h @@ -0,0 +1,222 @@ +/* +* +* 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 _COMMON_PAL_BITWIDE_ADJUST_H_ +#define _COMMON_PAL_BITWIDE_ADJUST_H_ + +#ifdef HAL_LIB +#include "pal_bitwide_adjust.h" +#else +#define MODULE(name) (1) + +#include "common_mem_common.h" + +#include "common_func.h" + +#ifndef _UT_FUN_DISABLE_ +/*define struct for UT restore global variant*/ +struct ut_adjust_global +{ + void **ut_PrimAddr2LocalMap; + uint64_t *ut_LocalAddr2PrimMap; + void *ut_LocalBaseAddr; + void *ut_LocalMaxAddr; + void *ut_LocalCfgAddrBase; + uint64_t ut_PrimBaseAddr; + uint64_t ut_PrimMaxAddr; + uint64_t ut_PrimCfgAddrBase; + int ut_PrimSameFlg; + uint64_t ut_LBitMask; + int ut_LBitMaskLen; + struct common_mem_memseg *ut_PMemSegArry; + void **ut_LMegAddrArry; +}; +#endif + +#define ALIGN_SIZET(size) ((uint64_t)(size)) +#define ALIGN_PTR(PTR) ((uint64_t)(PTR)) + +extern struct common_mem_memseg *g_PMemSegArry; +extern void **g_LMegAddrArry; + +/*get Local Seg addr by segIdx*/ +#define HMEM_SEG_LVADDR(segid) (g_LMegAddrArry[segid]) +/*get SegIDX by PrimSegAddr, just get the arry Idx of g_PMemSegArry*/ +#define HMEM_SEGID(segaddr) ((struct common_mem_memseg*)segaddr - &(g_PMemSegArry[0])) + +/***************************************************************** +Parameters : LMegAddrArry[] Loacol common_mem_memseg addr Arry + SegNum common_mem_memseg Num. +Return : +Description : init g_PrimAddr2LocalMap g_LocalAddr2PrimMap while the process start +*****************************************************************/ +void *pal_shddr_to_laddr (uint64_t shaddr); +uint64_t pal_laddr_to_shddr (void *laddr); +int dmm_pal_addr_align (); + +extern int g_PrimSameFlg; + +/* if __NSTACK_MAIN__ is defined, no need do addr trans*/ +#ifndef __NSTACK_MAIN__ +/* g_PrimSameFlg check should be done before calling cast functions */ + +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) (g_PrimSameFlg ? ((void*) (addr)) : pal_shddr_to_laddr((uint64_t)(addr))) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) (g_PrimSameFlg ? ((uint64_t)(addr)) : pal_laddr_to_shddr((void*)(addr))) + +#define PTR_SHTOL(type, addr) ((type)ADDR_SHTOL(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#else +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) ((void*)(addr)) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) ((uint64_t)(addr)) + +#define PTR_SHTOL(type, addr) ((type)(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#endif + +#if MODULE("list") +#define COMMON_LIST_INSERT_HEAD(lhead, lelm, field) do { \ + if (((lelm)->field.le_next_align = (lhead)->lh_first_align) != ((typeof((lhead)->lh_first_align))(long)NULL)) \ + ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align))->field.le_prev_align = \ + ADDR_LTOSH(&(lelm)->field.le_next); \ + (lhead)->lh_first_align = ADDR_LTOSH(lelm); \ + (lelm)->field.le_prev_align = ADDR_LTOSH(&(lhead)->lh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_REMOVE(lelm, field) do { \ + if ((lelm)->field.le_next_align != ((typeof((lelm)->field.le_next_align))ALIGN_PTR(NULL))) \ + ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align))->field.le_prev_align = \ + (lelm)->field.le_prev_align; \ + if (EOK != (MEMCPY_S((typeof((lelm)->field.le_prev))ADDR_SHTOL((lelm)->field.le_prev_align), \ + sizeof((lelm)->field.le_next_align), \ + &((lelm)->field.le_next_align), \ + sizeof((lelm)->field.le_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + return;\ + }\ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_EMPTY(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align) == NULL) +#define COMMON_LIST_FIRST(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align)) +#define COMMON_LIST_NEXT(lelm, field) ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align)) + +#endif + +#if MODULE("tailq") + +#define COMMON_TAILQ_INSERT_TAIL(lhead, lelm, field) do { \ + (lelm)->field.tqe_next_align = (typeof((lelm)->field.tqe_next_align))NULL; \ + (lelm)->field.tqe_prev_align = (lhead)->tqh_last_align; \ + typeof((lhead)->tqh_last_align) tempelm = ADDR_LTOSH(lelm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lhead)->tqh_last_align), sizeof(tempelm), &tempelm, sizeof(tempelm)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (lhead)->tqh_last_align = ADDR_LTOSH(&(lelm)->field.tqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_TAILQ_FOREACH(lvar, lhead, field) \ + for ((lvar) = (typeof(lvar))ADDR_SHTOL((lhead)->tqh_first_align); \ + (lvar); \ + (lvar) = (typeof(lvar))ADDR_SHTOL((lvar)->field.tqe_next_align)) + +#define COMMON_TAILQ_REMOVE(lhead, lelm, field) do { \ + if (((lelm)->field.tqe_next_align) != (typeof((lelm)->field.tqe_next_align))NULL) \ + ((typeof((lelm)->field.tqe_next))ADDR_SHTOL((lelm)->field.tqe_next_align))->field.tqe_prev_align = \ + (lelm)->field.tqe_prev_align; \ + else \ + (lhead)->tqh_last_align = (lelm)->field.tqe_prev_align; \ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lelm)->field.tqe_prev_align), \ + sizeof((lelm)->field.tqe_next_align), \ + &((lelm)->field.tqe_next_align), \ + sizeof((lelm)->field.tqe_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + } while (/*CONSTCOND*/0) + +/* + * Tail queue functions. + */ +#define COMMON_TAILQ_INIT(head) do { \ + (head)->tqh_first_align = (typeof((head)->tqh_first_align))NULL; \ + (head)->tqh_last_align = ADDR_LTOSH(&(head)->tqh_first); \ + } while (/*CONSTCOND*/0) + +/* + * Tail queue access methods. + */ +#define COMMON_TAILQ_EMPTY(head) ((head)->tqh_first_align == (typeof((head)->tqh_first_align))NULL) +#define COMMON_TAILQ_FIRST(head) ((typeof((head)->tqh_first))ADDR_SHTOL((head)->tqh_first_align)) +#define COMMON_TAILQ_NEXT(elm, field) ((typeof((elm)->field.tqe_next))ADDR_SHTOL((elm)->field.tqe_next_align)) + +#endif + +#if MODULE("stailq") +/* +* Singly-linked Tail queue functions. +*/ +#define COMMON_STAILQ_INIT(head) do { \ + (head)->stqh_first_align = ALIGN_PTR(NULL); \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next_align = ALIGN_PTR(NULL); \ + typeof((head)->stqh_last_align) telm = ADDR_LTOSH(elm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((head)->stqh_last_align), sizeof(telm), &telm, sizeof(telm))))\ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (head)->stqh_last_align = ADDR_LTOSH(&(elm)->field.stqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first_align = \ + ((typeof((head)->stqh_first))ADDR_SHTOL((head)->stqh_first_align))->field.stqe_next_align) == \ + (PTR_ALIGN_TYPE)NULL) \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_FOREACH(var, head, field) \ + for ((var) = ADDR_SHTOL((head)->stqh_first_align); \ + (var); \ + (var) = ADDR_SHTOL((var)->field.stqe_next_align)) + +/* +* Singly-linked Tail queue access methods. +*/ + +#define COMMON_STAILQ_EMPTY(head) ((head)->stqh_first_align == (PTR_ALIGN_TYPE)NULL) + +#define COMMON_STAILQ_FIRST(head) (ADDR_SHTOL((head)->stqh_first_align)) + +#define COMMON_STAILQ_NEXT(elm, field) (ADDR_SHTOL((elm)->field.stqe_next_align)) +#endif + +#endif + +#endif diff --git a/src/framework/common/base/include/nsfw_base_linux_api.h b/src/framework/common/base/include/nsfw_base_linux_api.h new file mode 100644 index 0000000..83b5a32 --- /dev/null +++ b/src/framework/common/base/include/nsfw_base_linux_api.h @@ -0,0 +1,58 @@ +/* +* +* 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 _NSFW_BASE_LINUX_API_H_ +#define _NSFW_BASE_LINUX_API_H_ + +#include +#include +#include +#include + +int nsfw_base_socket (int, int, int); +int nsfw_base_bind (int, const struct sockaddr *, socklen_t); +int nsfw_base_listen (int, int); +int nsfw_base_shutdown (int, int); +int nsfw_base_getsockname (int, struct sockaddr *, socklen_t *); +int nsfw_base_getpeername (int, struct sockaddr *, socklen_t *); +int nsfw_base_getsockopt (int, int, int, void *, socklen_t *); +int nsfw_base_setsockopt (int, int, int, const void *, socklen_t); +int nsfw_base_accept (int, struct sockaddr *, socklen_t *); +int nsfw_base_accept4 (int, struct sockaddr *, socklen_t *, int flags); +int nsfw_base_connect (int, const struct sockaddr *, socklen_t); +ssize_t nsfw_base_recv (int, void *, size_t, int); +ssize_t nsfw_base_send (int, const void *, size_t, int); +ssize_t nsfw_base_read (int, void *, size_t); +ssize_t nsfw_base_write (int, const void *, size_t); +ssize_t nsfw_base_writev (int, const struct iovec *, int); +ssize_t nsfw_base_readv (int, const struct iovec *, int); +ssize_t nsfw_base_sendto (int, const void *, size_t, int, + const struct sockaddr *, socklen_t); +ssize_t nsfw_base_recvfrom (int, void *, size_t, int, struct sockaddr *, + socklen_t *); +ssize_t nsfw_base_sendmsg (int, const struct msghdr *, int flags); +ssize_t nsfw_base_recvmsg (int, struct msghdr *, int flags); +int nsfw_base_close (int); +int nsfw_base_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); +int nsfw_base_ioctl (int, unsigned long, unsigned long); +int nsfw_base_fcntl (int, int, unsigned long); +int nsfw_base_epoll_create (int); +int nsfw_base_epoll_create1 (int); +int nsfw_base_epoll_ctl (int, int, int, struct epoll_event *); +int nsfw_base_epoll_wait (int, struct epoll_event *, int, int); +pid_t nsfw_base_fork (void); + +#endif diff --git a/src/framework/common/base/include/nsfw_getopt.h b/src/framework/common/base/include/nsfw_getopt.h new file mode 100644 index 0000000..f1394cf --- /dev/null +++ b/src/framework/common/base/include/nsfw_getopt.h @@ -0,0 +1,50 @@ +/* +* +* 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 NSFW_GETOPT_H +#define NSFW_GETOPT_H 1 + +#if defined(__cplusplus) +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define nsfw_no_argument 0 +#define nsfw_required_argument 1 +#define nsfw_optional_argument 2 + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +int nsfw_getopt_long (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex); + +extern char *nsfw_optarg; +extern int nsfw_optind, nsfw_opterr, nsfw_optopt; + +#if defined(__cplusplus) +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/common/base/liblinuxapi/base_linux_api_declare.h b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h new file mode 100644 index 0000000..943ae04 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h @@ -0,0 +1,51 @@ +/* +* +* 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. +*/ + +BASE_MK_DECL (int, socket, (int, int, int)); +BASE_MK_DECL (int, bind, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (int, listen, (int, int)); +BASE_MK_DECL (int, shutdown, (int, int)); +BASE_MK_DECL (int, getsockname, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getpeername, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getsockopt, (int, int, int, void *, socklen_t *)); +BASE_MK_DECL (int, setsockopt, (int, int, int, const void *, socklen_t)); +BASE_MK_DECL (int, accept, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, accept4, (int, struct sockaddr *, socklen_t *, int flags)); +BASE_MK_DECL (int, connect, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (ssize_t, recv, (int, void *, size_t, int)); +BASE_MK_DECL (ssize_t, send, (int, const void *, size_t, int)); +BASE_MK_DECL (ssize_t, read, (int, void *, size_t)); +BASE_MK_DECL (ssize_t, write, (int, const void *, size_t)); +BASE_MK_DECL (ssize_t, writev, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, readv, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, sendto, + (int, const void *, size_t, int, const struct sockaddr *, + socklen_t)); +BASE_MK_DECL (ssize_t, recvfrom, + (int, void *, size_t, int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (ssize_t, sendmsg, (int, const struct msghdr *, int flags)); +BASE_MK_DECL (ssize_t, recvmsg, (int, struct msghdr *, int flags)); +BASE_MK_DECL (int, close, (int)); +BASE_MK_DECL (int, select, + (int, fd_set *, fd_set *, fd_set *, struct timeval *)); +BASE_MK_DECL (int, ioctl, (int, unsigned long, unsigned long)); +BASE_MK_DECL (int, fcntl, (int, int, unsigned long)); +BASE_MK_DECL (int, epoll_create, (int)); +BASE_MK_DECL (int, epoll_create1, (int)); +BASE_MK_DECL (int, epoll_ctl, (int, int, int, struct epoll_event *)); +BASE_MK_DECL (int, epoll_wait, (int, struct epoll_event *, int, int)); +BASE_MK_DECL (pid_t, fork, (void)); +#undef BASE_MK_DECL diff --git a/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c new file mode 100644 index 0000000..de98877 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c @@ -0,0 +1,628 @@ +/* +* +* 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 "nsfw_base_linux_api.h" +#include "nstack_log.h" +#include +#include +#include +#include + +#define NSFW_BASE_OK 0 +#define NSFW_BASE_FAIL (-1) + +#define nsfw_call_ret(symbol, para){ \ + if (NSFW_BASE_OK != nsfw_posix_api_init()) \ + { \ + return NSFW_BASE_FAIL; \ + } \ + if (g_nsfw_posix_api.pf##symbol) \ + { \ + return g_nsfw_posix_api.pf##symbol para;\ + } \ + errno = ENOSYS; \ + return NSFW_BASE_FAIL; \ +} + +typedef enum +{ + BASE_STATE_INIT, + BASE_STATE_SUCCESS, + BASE_STATE_FAIL +} nsfw_base_state; + +typedef struct __base_linux_api +{ +#define BASE_MK_DECL(ret, fn, args) ret (*pf##fn) args; +#include "base_linux_api_declare.h" +} base_linux_api; + +nsfw_base_state g_nsfw_mudule_state = BASE_STATE_INIT; +pthread_mutex_t g_nsfw_init_mutex = PTHREAD_MUTEX_INITIALIZER; +base_linux_api g_nsfw_posix_api = { 0 }; + +void *g_linux_lib_handle = (void *) 0; + +int +nsfw_posix_symbol_load () +{ + g_linux_lib_handle = dlopen ("libc.so.6", RTLD_NOW | RTLD_GLOBAL); + if ((void *) 0 == g_linux_lib_handle) + { + /* optimize dlopen err print */ + NSSOC_LOGERR ("cannot dlopen libc.so.6] err_string=%s", dlerror ()); + return NSFW_BASE_FAIL; + } +#define BASE_MK_DECL(ret, fn, args) \ + g_nsfw_posix_api.pf##fn = (typeof(g_nsfw_posix_api.pf##fn))dlsym(g_linux_lib_handle, #fn); +#include + + return NSFW_BASE_OK; +} + +/***************************************************************** +Parameters : void +Return : +Description : linux posix api init with threadonce +*****************************************************************/ +static inline int +nsfw_posix_api_init () +{ + int iret = NSFW_BASE_OK; + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + (void) pthread_mutex_lock (&g_nsfw_init_mutex); + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + iret = nsfw_posix_symbol_load (); + if (NSFW_BASE_OK == iret) + { + g_nsfw_mudule_state = BASE_STATE_SUCCESS; + } + else + { + g_nsfw_mudule_state = BASE_STATE_FAIL; + } + + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return iret; +} +/* *INDENT-OFF* */ +/***************************************************************************** +* Prototype : nsfw_base_socket +* Description : linux socket api +* Input : int a +* int b +* int c +* Output : None +* Return Value : int +* Calls : +* Called By : + +* +*****************************************************************************/ +int nsfw_base_socket(int a, int b, int c) +{ + nsfw_call_ret(socket, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_bind +* Description : linux fd bind api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_bind(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(bind, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_listen +* Description : linux fd listen api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_listen(int a, int b) +{ + nsfw_call_ret(listen, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_shutdown +* Description : linux shutdown api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +* +*****************************************************************************/ +int nsfw_base_shutdown(int a, int b) +{ + nsfw_call_ret(shutdown, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockname +* Description : linux getsockname api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockname(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getsockname, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getpeername +* Description : linux getpername api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getpeername(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getpeername, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockopt +* Description : linux getsockopt api +* Input : int a +* int b +* int c +* void* d +* socklen_t* e +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockopt(int a, int b, int c, void* d, socklen_t* e) +{ + nsfw_call_ret(getsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_setsockopt +* Description : linux setsockopt api +* Input : int a +* int b +* int c +* const void* d +* socklen_t e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_setsockopt(int a, int b, int c, const void* d, socklen_t e) +{ + nsfw_call_ret(setsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept +* Description : linux accept api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(accept, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept4 +* Description : linux accept4 api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* int flags +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept4(int a, struct sockaddr* b, socklen_t* c, int flags) +{ + nsfw_call_ret(accept4, (a, b, c, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_connect +* Description : linux connect api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_connect(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(connect, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recv +* Description : linux recv api +* Input : int a +* void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recv(int a, void* b, size_t c, int d) +{ + nsfw_call_ret(recv, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_send +* Description : linux send api +* Input : int a +* const void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_send(int a, const void* b, size_t c, int d) +{ + nsfw_call_ret(send, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_read +* Description : linux read api +* Input : int a +* void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_read(int a, void* b, size_t c) +{ + nsfw_call_ret(read, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_write +* Description : linux write api +* Input : int a +* const void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_write(int a, const void* b, size_t c) +{ + nsfw_call_ret(write, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_writev +* Description : linux writev api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_writev(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(writev, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_readv +* Description : linux readv api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_readv(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(readv, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendto +* Description : linux sendto api +* Input : int a +* const void * b +* size_t c +* int d +* const struct sockaddr *e +* socklen_t f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_sendto(int a, const void * b, size_t c, int d, const struct sockaddr *e, socklen_t f) +{ + nsfw_call_ret(sendto, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvfrom +* Description : linux recvfrom api +* Input : int a +* void *b +* size_t c +* int d +* struct sockaddr *e +* socklen_t *f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_recvfrom(int a, void *b, size_t c, int d,struct sockaddr *e, socklen_t *f) +{ + nsfw_call_ret(recvfrom, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendmsg +* Description : linux sendmsg api +* Input : int a +* const struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_sendmsg(int a, const struct msghdr *b, int flags) +{ + nsfw_call_ret(sendmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvmsg +* Description : linux recvmsg api +* Input : int a +* struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recvmsg(int a, struct msghdr *b, int flags) +{ + nsfw_call_ret(recvmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_close +* Description : linux close api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_close(int a) +{ + nsfw_call_ret(close, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_select +* Description : linux select api +* Input : int a +* fd_set *b +* fd_set *c +* fd_set *d +* struct timeval *e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_select(int a, fd_set *b, fd_set *c, fd_set *d, struct timeval *e) +{ + nsfw_call_ret(select, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_ioctl +* Description : linux ioctl api +* Input : int a +* unsigned long b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_ioctl(int a, unsigned long b, unsigned long c) +{ + nsfw_call_ret(ioctl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fcntl +* Description : linux fcntl api +* Input : int a +* int b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_fcntl(int a, int b, unsigned long c) +{ + nsfw_call_ret(fcntl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create +* Description : linux epoll_create api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create(int a) +{ + nsfw_call_ret(epoll_create, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create1 +* Description : linux epoll_create1 api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create1(int a) +{ + nsfw_call_ret(epoll_create1, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_ctl +* Description : linux epoll_ctl api +* Input : int a +* int b +* int c +* struct epoll_event *d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_ctl(int a, int b, int c, struct epoll_event *d) +{ + nsfw_call_ret(epoll_ctl, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_wait +* Description : linux epoll_wait api +* Input : int a +* struct epoll_event *b +* int c +* int d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_wait(int a, struct epoll_event *b, int c, int d) +{ + nsfw_call_ret(epoll_wait, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fork +* Description : linux fork api +* Input : void +* Output : None +* Return Value : pid_t +* Calls : +* Called By : +* +*****************************************************************************/ +pid_t nsfw_base_fork(void) +{ + nsfw_call_ret(fork, ()) +} +/* *INDENT-ON* */ diff --git a/src/framework/common/base/liblinuxapi/nsfw_getopt.c b/src/framework/common/base/liblinuxapi/nsfw_getopt.c new file mode 100644 index 0000000..ac7d6bf --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_getopt.c @@ -0,0 +1,455 @@ +/* +* +* 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 +#include +#include +#include +#include "nsfw_getopt.h" +#include "nstack_log.h" + +char *nsfw_optarg = NULL; +int nsfw_optind = 1; +int nsfw_opterr = 1; +int nsfw_optopt = '?'; +NSTACK_STATIC char *nsfw_optnext = NULL; +NSTACK_STATIC int posixly_correct = -1; +NSTACK_STATIC int handle_nonopt_argv = 0; +NSTACK_STATIC int start = 0; +NSTACK_STATIC int end = 0; + +NSTACK_STATIC void check_gnu_extension (const char *optstring); +NSTACK_STATIC int nsfw_getopt_internal (int argc, char *const argv[], + const char *optstring, + const struct option *longopts, + int *longindex, int long_only); +NSTACK_STATIC int nsfw_getopt_shortopts (int argc, char *const argv[], + const char *optstring, + int long_only); +NSTACK_STATIC int nsfw_getopt_longopts (int argc, char *const argv[], + char *arg, const char *optstring, + const struct option *longopts, + int *longindex, int *long_only_flag); +NSTACK_STATIC inline int nsfw_getopt_internal_check_opts (const char + *optstring); +NSTACK_STATIC inline int nsfw_getopt_check_optind (); +NSTACK_STATIC inline int nsfw_getopt_internal_init (char *const argv[]); +NSTACK_STATIC inline int nsfw_getopt_longopts_check_longonly (int + *long_only_flag, + const char + *optstring, + char *const + argv[]); + +NSTACK_STATIC void +check_gnu_extension (const char *optstring) +{ + if (optstring[0] == '+' || getenv ("POSIXLY_CORRECT") != NULL) + { + posixly_correct = 1; + } + else + { + posixly_correct = 0; + } + if (optstring[0] == '-') + { + handle_nonopt_argv = 1; + } + else + { + handle_nonopt_argv = 0; + } +} + +int +nsfw_getopt_long (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex) +{ + return nsfw_getopt_internal (argc, argv, optstring, longopts, longindex, 0); +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_check_opts (const char *optstring) +{ + if (NULL == optstring) + { + return -1; + } + + if (nsfw_optopt == '?') + { + nsfw_optopt = 0; + } + + if (posixly_correct == -1) + { + check_gnu_extension (optstring); + } + + if (nsfw_optind == 0) + { + check_gnu_extension (optstring); + nsfw_optind = 1; + nsfw_optnext = NULL; + } + + switch (optstring[0]) + { + case '+': + case '-': + optstring++; + break; + default: + break; + } + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_check_optind () +{ + if (nsfw_optind <= 0) + nsfw_optind = 1; + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_init (char *const argv[]) +{ + if (nsfw_optnext == NULL && start != 0) + { + int last_pos = nsfw_optind - 1; + + nsfw_optind -= end - start; + (void) nsfw_getopt_check_optind (); + + while (start < end--) + { + int i; + char *arg = argv[end]; + + for (i = end; i < last_pos; i++) + { + int j = i + 1; + ((char **) argv)[i] = argv[j]; + } + ((char const **) argv)[i] = arg; + last_pos--; + } + start = 0; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_internal (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex, + int long_only) +{ + + (void) nsfw_getopt_internal_check_opts (optstring); + + (void) nsfw_getopt_internal_init (argv); + + if (nsfw_optind >= argc) + { + nsfw_optarg = NULL; + return -1; + } + if (nsfw_optnext == NULL) + { + const char *arg = argv[nsfw_optind]; + if (*arg != '-') + { + if (handle_nonopt_argv) + { + nsfw_optarg = argv[nsfw_optind++]; + start = 0; + return 1; + } + else if (posixly_correct) + { + nsfw_optarg = NULL; + return -1; + } + else + { + int i; + + start = nsfw_optind; + for (i = nsfw_optind + 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + end = i; + break; + } + } + if (i == argc) + { + nsfw_optarg = NULL; + return -1; + } + nsfw_optind = i; + arg = argv[nsfw_optind]; + } + } + if (strcmp (arg, "--") == 0) + { + nsfw_optind++; + return -1; + } + if (longopts != NULL && arg[1] == '-') + { + return nsfw_getopt_longopts (argc, argv, argv[nsfw_optind] + 2, + optstring, longopts, longindex, NULL); + } + } + + if (nsfw_optnext == NULL) + { + nsfw_optnext = argv[nsfw_optind] + 1; + } + if (long_only) + { + int long_only_flag = 0; + int rv = + nsfw_getopt_longopts (argc, argv, nsfw_optnext, optstring, longopts, + longindex, &long_only_flag); + if (!long_only_flag) + { + nsfw_optnext = NULL; + return rv; + } + } + + return nsfw_getopt_shortopts (argc, argv, optstring, long_only); +} + +NSTACK_STATIC int +nsfw_getopt_shortopts (int argc, char *const argv[], const char *optstring, + int long_only) +{ + int opt = *nsfw_optnext; + const char *os; + if (optstring != NULL) + { + os = strchr (optstring, opt); + } + else + { + /* here try to keep same with below behavior */ + return '?'; + } + + if (os == NULL) + { + nsfw_optarg = NULL; + if (long_only) + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, netopt=%s", + argv[0], nsfw_optnext); + } + nsfw_optind++; + nsfw_optnext = NULL; + } + else + { + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR ("invalid option] argv_0=%s, opt=%c", argv[0], opt); + } + if (*(++nsfw_optnext) == 0) + { + nsfw_optind++; + nsfw_optnext = NULL; + } + } + return '?'; + } + if (os[1] == ':') + { + if (nsfw_optnext[1] == 0) + { + nsfw_optind++; + if (os[2] == ':') + { + nsfw_optarg = NULL; + } + else + { + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("option requires an argument] argv_0=%s, opt=%c", + argv[0], opt); + } + return optstring[0] == ':' ? ':' : '?'; + } + nsfw_optarg = argv[nsfw_optind]; + nsfw_optind++; + } + } + else + { + nsfw_optarg = nsfw_optnext + 1; + nsfw_optind++; + } + nsfw_optnext = NULL; + } + else + { + nsfw_optarg = NULL; + if (nsfw_optnext[1] == 0) + { + nsfw_optnext = NULL; + nsfw_optind++; + } + else + { + nsfw_optnext++; + } + } + return opt; +} + +NSTACK_STATIC inline int +nsfw_getopt_longopts_check_longonly (int *long_only_flag, + const char *optstring, + char *const argv[]) +{ + if (long_only_flag) + { + *long_only_flag = 1; + } + else + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, option=%s", argv[0], + argv[nsfw_optind]); + } + nsfw_optind++; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_longopts (int argc, char *const argv[], char *arg, + const char *optstring, const struct option *longopts, + int *longindex, int *long_only_flag) +{ + char *val = NULL; + const struct option *opt; + size_t namelen; + int idx; + + if ((longopts == NULL) || (arg == NULL)) + { + return -1; + } + + for (idx = 0; longopts[idx].name != NULL; idx++) + { + opt = &longopts[idx]; + namelen = strlen (opt->name); + + if (strncmp (arg, opt->name, namelen) == 0) + { + switch (arg[namelen]) + { + case '\0': + switch (opt->has_arg) + { + case nsfw_required_argument: + nsfw_optind++; + + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("requires an argument] argv_0=%s, opt name=%s", + argv[0], opt->name); + } + return optstring[0] == ':' ? ':' : '?'; + } + + val = argv[nsfw_optind]; + break; + + default: + break; + } + + goto found; + + case '=': + if (opt->has_arg == nsfw_no_argument) + { + const char *hyphens = + (argv[nsfw_optind][1] == '-') ? "--" : "-"; + nsfw_optind++; + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("doesn't allow an argument] argv_0=%s, hyphens=%s, opt name=%s", + argv[0], hyphens, opt->name); + } + return '?'; + } + + val = arg + namelen + 1; + goto found; + + default: + break; + } + } + } + + (void) nsfw_getopt_longopts_check_longonly (long_only_flag, optstring, + argv); + return '?'; + +found: + nsfw_optarg = val; + nsfw_optind++; + + if (opt->flag) + { + *opt->flag = opt->val; + } + + if (longindex) + { + *longindex = idx; + } + + return opt->flag ? 0 : opt->val; +} diff --git a/src/framework/common/base/liblinuxapi/nsfw_lock_file.c b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c new file mode 100644 index 0000000..0ec196f --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c @@ -0,0 +1,174 @@ +/* +* +* 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 +#include +#include +#include +#include + +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_api.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mgr_com_api.h" + +#include "nsfw_base_linux_api.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_FILE_PATH_LEN 128 +#define LOCK_FOLDER "/ip_module/" +#define LOCK_SUFFIX ".pid" + +#define read_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len)) +#define readw_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) +#define write_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) +#define writew_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) +#define un_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len)) + +i32 +nsfw_lock_reg (i32 fd, i32 cmd, i32 type, off_t offset, i32 whence, off_t len) +{ + struct flock lock_file; + lock_file.l_type = type; + lock_file.l_start = offset; + lock_file.l_whence = whence; + lock_file.l_len = len; + return (fcntl (fd, cmd, &lock_file)); +} + +/***************************************************************************** +* Prototype : nsfw_proc_start_with_lock +* Description : lock file start +* Input : u8 proc_type +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_proc_start_with_lock (u8 proc_type) +{ + NSFW_LOGINF ("lock_file init]type=%u", proc_type); + char *module_name = nsfw_get_proc_name (proc_type); + if (NULL == module_name) + { + NSFW_LOGERR ("proc type error]proc_type=%u", proc_type); + return 0; + } + + const char *directory = NSFW_DOMAIN_DIR; + const char *home_dir = getenv ("HOME"); + + if (getuid () != 0 && home_dir != NULL) + { + directory = home_dir; + } + + int ret; + char lock_fpath[NSFW_FILE_PATH_LEN] = { 0 }; + ret = STRCPY_S (lock_fpath, NSFW_FILE_PATH_LEN, directory); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCPY_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_FOLDER); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, module_name); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_SUFFIX); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + i32 fd; + if ((fd = open (lock_fpath, O_RDWR | O_CREAT, 0640)) == -1) + { /* file permission no large than 0640 */ + NSFW_LOGERR ("open lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + int rc = nsfw_set_close_on_exec (fd); + if (rc == -1) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", fd, errno); + return -1; + } + + if (write_lock (fd, 0, SEEK_SET, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("get lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + char buf[32] = { 0 }; + if (ftruncate (fd, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("ftruncate file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + ret = + SNPRINTF_S (buf, sizeof (buf), sizeof (buf) - 1, "%ld", (long) getpid ()); + if (-1 == ret) + { + NSTCP_LOGERR ("SNPRINTF_S failed]ret=%d", ret); + (void) nsfw_base_close (fd); + return -1; + } + + if (write (fd, buf, strlen (buf) + 1) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("write file error!]path=%s,error = %d", lock_fpath, errno); + return -1; + } + + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/data_struct/eprb_tree.c b/src/framework/common/data_struct/eprb_tree.c new file mode 100644 index 0000000..c8af17c --- /dev/null +++ b/src/framework/common/data_struct/eprb_tree.c @@ -0,0 +1,492 @@ +/* +* +* 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 "eprb_tree.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* + * This function returns the first node (in sort order) of the tree. + */ +struct ep_rb_node * +ep_rb_first (const struct ep_rb_root *root) +{ + if (NULL == root) + return NULL; + + struct ep_rb_node *n; + n = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + + if (!n) + { + return NULL; + } + + while (n->rb_left) + { + n = (struct ep_rb_node *) ADDR_SHTOL (n->rb_left); + } + + return n; +} + +void +__ep_rb_rotate_left (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /************************** + * rotate Node X to left * + **************************/ + struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_right); + + /* estblish X->Right link */ + X->rb_right = Y->rb_left; + + if (Y->rb_left != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_left))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + } + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + + if (X->rb_parent) + { + struct ep_rb_node *xParent = + (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + + if (X == ADDR_SHTOL (xParent->rb_left)) + { + xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + else + { + xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + + /* link X and Y */ + Y->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + + return; +} + +void +__ep_rb_rotate_right (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /**************************** + * rotate Node X to right * + ****************************/ + struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_left); + + /* estblish X->Left link */ + X->rb_left = Y->rb_right; + + if (Y->rb_right != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_right))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + } + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + + if (X->rb_parent) + { + struct ep_rb_node *xParent = + (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + + if (X == (struct ep_rb_node *) ADDR_SHTOL (xParent->rb_right)) + { + xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + else + { + xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + + /* link X and Y */ + Y->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + + return; +} + +#define EP_RBTREE_PARENT(X) ((struct ep_rb_node*) ADDR_SHTOL((X)->rb_parent)) +#define EP_RBTREE_GRANDF(X) EP_RBTREE_PARENT(EP_RBTREE_PARENT(X)) + +/* X, Y are for application */ +void +ep_rb_insert_color (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after inserting node X * + *************************************/ + /* check red-black properties */ + while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node) + && EP_RBTREE_PARENT (X)->color == EP_RB_RED) + { + /* we have a violation */ + if (X->rb_parent == EP_RBTREE_GRANDF (X)->rb_left) + { + struct ep_rb_node *Y = + (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_right); + + if (Y && Y->color == EP_RB_RED) + { + + /* uncle is red */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + Y->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + X = EP_RBTREE_GRANDF (X); + } + else + { + + /* uncle is black */ + if (X == + (struct ep_rb_node *) + ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_right)) + { + /* make X a left child */ + X = EP_RBTREE_PARENT (X); + __ep_rb_rotate_left (X, root); + } + + /* recolor and rotate */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + __ep_rb_rotate_right (EP_RBTREE_GRANDF (X), root); + } + } + else + { + /* miror image of above code */ + struct ep_rb_node *Y = + (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_left); + + if (Y && (Y->color == EP_RB_RED)) + { + + /* uncle is red */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + Y->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + X = EP_RBTREE_GRANDF (X); + } + else + { + + /* uncle is black */ + if (X == + (struct ep_rb_node *) + ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_left)) + { + X = EP_RBTREE_PARENT (X); + __ep_rb_rotate_right (X, root); + } + + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + __ep_rb_rotate_left (EP_RBTREE_GRANDF (X), root); + } + } + } + + ((struct ep_rb_node *) ADDR_SHTOL (root->rb_node))->color = EP_RB_BLACK; + + return; +} + +void +__ep_rb_erase_color (struct ep_rb_node *X, struct ep_rb_node *Parent, + struct ep_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after deleting node X * + *************************************/ + while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node) + && (!X || X->color == EP_RB_BLACK)) + { + + if (Parent == NULL) + { + break; + } + + if (X == (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left)) + { + struct ep_rb_node *W = + (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + + if (W->color == EP_RB_RED) + { + W->color = EP_RB_BLACK; + Parent->color = EP_RB_RED; /* Parent != NIL? */ + __ep_rb_rotate_left (Parent, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + } + + if ((!W->rb_left + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color == + EP_RB_BLACK) && (!W->rb_right + || ((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color == + EP_RB_BLACK)) + { + W->color = EP_RB_RED; + X = Parent; + Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + } + else + { + if (!W->rb_right + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color + == EP_RB_BLACK) + { + if (W->rb_left != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color + = EP_RB_BLACK; + } + + W->color = EP_RB_RED; + __ep_rb_rotate_right (W, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + } + + W->color = Parent->color; + Parent->color = EP_RB_BLACK; + + if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color != + EP_RB_BLACK) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color = + EP_RB_BLACK; + } + + __ep_rb_rotate_left (Parent, root); + X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + break; + } + } + else + { + + struct ep_rb_node *W = + (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + + if (W->color == EP_RB_RED) + { + W->color = EP_RB_BLACK; + Parent->color = EP_RB_RED; /* Parent != NIL? */ + __ep_rb_rotate_right (Parent, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + } + + if ((!W->rb_left + || (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color == + EP_RB_BLACK)) && (!W->rb_right + || + (((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color == + EP_RB_BLACK))) + { + W->color = EP_RB_RED; + X = Parent; + Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + } + else + { + if (!W->rb_left + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color + == EP_RB_BLACK) + { + if (W->rb_right != NULL) + { + ((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color = EP_RB_BLACK; + } + + W->color = EP_RB_RED; + __ep_rb_rotate_left (W, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + } + + W->color = Parent->color; + Parent->color = EP_RB_BLACK; + + if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color != + EP_RB_BLACK) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color = + EP_RB_BLACK; + } + + __ep_rb_rotate_right (Parent, root); + X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + break; + } + } + } + + if (X) + { + X->color = EP_RB_BLACK; + } + + return; +} + +void +ep_rb_erase (struct ep_rb_node *node, struct ep_rb_root *root) +{ + struct ep_rb_node *child, *parent; + int color; + + if (!node->rb_left) + { + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + } + else if (!node->rb_right) + { + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_left); + } + else + { + struct ep_rb_node *old = node, *left; + + node = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + + while ((left = + (struct ep_rb_node *) ADDR_SHTOL (node->rb_left)) != NULL) + { + node = left; + } + + if (old->rb_parent) + { + struct ep_rb_node *oldParent = + (struct ep_rb_node *) ADDR_SHTOL (old->rb_parent); + + if (oldParent->rb_left == + (struct ep_rb_node *) ADDR_LTOSH_EXT (old)) + { + oldParent->rb_left = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + else + { + oldParent->rb_right = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent); + color = node->color; + + if (parent == old) + { + parent = node; + } + else + { + if (child) + { + child->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + } + + parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + + node->rb_right = old->rb_right; + ((struct ep_rb_node *) ADDR_SHTOL (old->rb_right))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + + node->color = old->color; + node->rb_parent = old->rb_parent; + node->rb_left = old->rb_left; + ((struct ep_rb_node *) ADDR_SHTOL (old->rb_left))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + + if (color == EP_RB_BLACK) + { + __ep_rb_erase_color (child, parent, root); + } + + return; + + } + + parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent); + color = node->color; + + if (child) + { + child->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + } + + if (parent) + { + if (parent->rb_left == (struct ep_rb_node *) ADDR_LTOSH_EXT (node)) + { + parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + else + { + parent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + + if (color == EP_RB_BLACK) + { + __ep_rb_erase_color (child, parent, root); + } + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif diff --git a/src/framework/common/data_struct/list.c b/src/framework/common/data_struct/list.c new file mode 100644 index 0000000..7645640 --- /dev/null +++ b/src/framework/common/data_struct/list.c @@ -0,0 +1,163 @@ +/* +* +* 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 "list.h" + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +inline int +list_empty (const struct list_head *head) +{ + return head->next == head; +} + +inline void +list_del (struct list_head *entry) +{ + if (entry->prev == NULL || entry->next == NULL) + { + return; + } + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = NULL; + entry->prev = NULL; +} + +/*get the first element of the list, need to check if list empty or not before calling this.*/ +inline struct list_head * +list_get_first (struct list_head *head) +{ + return head->next; +} + +inline void +list_add (struct list_head *newp, struct list_head *head) +{ + head->next->prev = newp; + newp->next = head->next; + newp->prev = head; + head->next = newp; +} + +inline void +list_link (struct list_head *newhead, struct list_head *head) +{ + struct list_head *tmp; + + newhead->prev->next = head; + head->prev->next = newhead; + + tmp = newhead->prev; + newhead->prev = head->prev; + head->prev = tmp; +} + +inline void +list_add_tail (struct list_head *newp, struct list_head *head) +{ + list_add (newp, head->prev); +} + +inline void +hlist_del_init (struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + + if (pprev == NULL && next == NULL) + { + return; + } + + if (pprev) + { + *pprev = next; + } + + if (next) + { + next->pprev = pprev; + } + + n->next = NULL; + n->pprev = NULL; +} + +/** + * next must be != NULL + * add n node before next node + * + * @n: new node + * @next: node in the hlist + */ +inline void +hlist_add_before (struct hlist_node *n, struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +/** + * next must be != NULL + * add n node after next node + * actual behavior is add after n + * @n: node in the hlist + * @next: new node + */ +inline void +hlist_add_after (struct hlist_node *n, struct hlist_node *next) +{ + next->next = n->next; + n->next = next; + next->pprev = &n->next; + if (next->next) + { + next->next->pprev = &next->next; + } +} + +/* add after the head */ +inline void +hlist_add_head (struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + + n->next = first; + if (first) + { + first->pprev = &n->next; + } + + h->first = n; + n->pprev = &h->first; +} + +inline int +hlist_unhashed (const struct hlist_node *h) +{ + return !h->pprev; +} + +inline int +hlist_empty (const struct hlist_head *h) +{ + return !h->first; +} diff --git a/src/framework/common/data_struct/pidinfo.c b/src/framework/common/data_struct/pidinfo.c new file mode 100644 index 0000000..08e551f --- /dev/null +++ b/src/framework/common/data_struct/pidinfo.c @@ -0,0 +1,125 @@ +/* +* +* 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 "pidinfo.h" +#include "nstack_securec.h" + +inline i32 +nsfw_pidinfo_init (nsfw_pidinfo * pidinfo) +{ + int retVal = + MEMSET_S (pidinfo, sizeof (nsfw_pidinfo), 0, sizeof (nsfw_pidinfo)); + if (EOK != retVal) + { + return -1; + } + + return 0; +} + +inline int +nsfw_add_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < NSFW_MAX_FORK_NUM; i++) + { + if ((0 == pidinfo->apid[i]) + && (__sync_bool_compare_and_swap (&pidinfo->apid[i], 0, pid))) + { + if (pidinfo->used_size < i + 1) + { + pidinfo->used_size = i + 1; + } + return 0; + } + } + return -1; +} + +inline int +nsfw_del_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + pidinfo->apid[i] = 0; + return 0; + } + } + return -1; +} + +inline int +nsfw_del_last_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + int count = 0; + int deleted = 0; + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + pidinfo->apid[i] = 0; + deleted = 1; + continue; + } + + if (pidinfo->apid[i] != 0) + { + ++count; + } + } + + if (!deleted) + { + return -1; + } + + return count; +} + +inline int +nsfw_pid_exist (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + return 1; + } + } + return 0; +} + +inline int +nsfw_pidinfo_empty (nsfw_pidinfo * pidinfo) +{ + u32 i; + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pidinfo->apid[i] != 0) + { + return 0; + } + } + return 1; +} diff --git a/src/framework/common/data_struct/sha256.c b/src/framework/common/data_struct/sha256.c new file mode 100644 index 0000000..504b365 --- /dev/null +++ b/src/framework/common/data_struct/sha256.c @@ -0,0 +1,397 @@ +/* +* +* 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. +*/ + +/*Possible access of out-of-bounds pointer: + The algorithms has been tested on purify. So no + out of bounds access possible.*/ + +/*Possible creation of out-of-bounds pointer + No Out of bounds pointers are created.- false positive.*/ + +#include /* for mem copy function etc. */ +#include "sha256.h" +#include "nstack_securec.h" +#include "types.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#ifdef LITTLE_ENDIAN +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + + /* round transforms for SHA256 and SHA512 compression functions */ + +#define vf(n,i) v[(n - i) & 7] + +#define hf(i) (p[i & 15] += \ + g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15])) + +#define v_cycle(i,j) \ +{ \ + vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \ + + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \ + vf(3,i) += vf(7,i); \ + vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)); \ +} + +#define SHA256_MASK (SHA256_BLOCK_SIZE - 1) + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ +{ \ + u32 _i = (n); \ + while (_i--) \ + { \ + ((u32*)p)[_i] = bswap_32(((u32*)p)[_i]); \ + } \ +} + +#else +#define bsw_32(p,n) +#endif + +#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) +#define k_0 k256 + +/* rotated SHA256 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define q(n) v##n + +#define one_cycle(a,b,c,d,e,f,g,h,k,w) \ + q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \ + q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c)) + +/* +Description: SHA256 mixing data +Value Range: None +Access: Used to mix with data to create SHA256 key. +Remarks: +*/ +static const u32 k256[64] = { + 010242427630, 016115642221, 026560175717, 035155355645, + 07125541133, 013174210761, 022217701244, 025307057325, + 033001725230, 02240655401, 04414302676, 012503076703, + 016257456564, 020067530776, 023367003247, 030146770564, + 034446664701, 035757443606, 01760316706, 04403120714, + 05572226157, 011235102252, 013454124734, 016676304332, + 023017450522, 025014343155, 026000623710, 027726277707, + 030670005763, 032551710507, 0662461521, 02412224547, + 04755605205, 05606620470, 011513066774, 012316006423, + 014502471524, 016632405273, 020160544456, 022234426205, + 024257764241, 025006463113, 030222705560, 030733050643, + 032144564031, 032646203044, 036403432605, 02032520160, + 03151140426, 03615666010, 04722073514, 06454136265, + 07107006263, 011666125112, 013347145117, 015013467763, + 016443701356, 017051261557, 020462074024, 021461601010, + 022057577772, 024424066353, 027676321767, 030634274362, +}; + +/* Compile 64 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +#define v_ v +#define ptr p + +/*===========================================================================*\ + Function :Sha256_compile__ + Description : This function generates the digest value for SHA256. + Compile 64 bytes of hash data into SHA256 digest value + Calls : mem copy - Secure mem copy function. + Called by : + Return : This is a static internal function which doesn't return any value. + Parameters : + SHA256_CTX ctx[1] - + Note : this routine assumes that the byte order in the + ctx->wbuf[] at this point is such that low address bytes in + the ORIGINAL byte stream will go into the high end of + words on BOTH big and little endian systems. +\*===========================================================================*/ +NSTACK_STATIC void +Sha256_compile__ (SHA256_CTX ctx[1]) +{ + + /* macros defined above to this function i.e. v_ and ptr should not be removed */ + /* v_cycle - for 0 to 15 */ + u32 j; + u32 *ptr = ctx->wbuf; + u32 v_[8]; + + int ret = MEMCPY_S (v_, 8 * sizeof (u32), ctx->hash, 8 * sizeof (u32)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + for (j = 0; j < 64; j += 16) + { + /*v_cycle operations from 0 to 15 */ + v_cycle (0, j); + v_cycle (1, j); + v_cycle (2, j); + v_cycle (3, j); + v_cycle (4, j); + v_cycle (5, j); + v_cycle (6, j); + v_cycle (7, j); + v_cycle (8, j); + v_cycle (9, j); + v_cycle (10, j); + v_cycle (11, j); + v_cycle (12, j); + v_cycle (13, j); + v_cycle (14, j); + v_cycle (15, j); + } + + /* update the context */ + ctx->hash[0] += v_[0]; + ctx->hash[1] += v_[1]; + ctx->hash[2] += v_[2]; + ctx->hash[3] += v_[3]; + ctx->hash[4] += v_[4]; + ctx->hash[5] += v_[5]; + ctx->hash[6] += v_[6]; + ctx->hash[7] += v_[7]; + + return; +} + +#undef v_ +#undef ptr + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +/*===========================================================================*\ + Function :Sha256_upd + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + const unsigned char data[] - + size_t len - + Note : +\*===========================================================================*/ +void +Sha256_upd (SHA256_CTX ctx[1], const u8 data[], size_t len) +{ + u32 pos = (u32) (ctx->count[0] & SHA256_MASK); + u32 space = SHA256_BLOCK_SIZE - pos; + const u8 *sp = data; + int ret; + + if ((ctx->count[0] += (u32) len) < len) + { + ++(ctx->count[1]); + } + + while (len >= space) + { + + /* tranfer whole blocks while possible */ + ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, space, sp, space); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + sp += space; + len -= space; + space = SHA256_BLOCK_SIZE; + pos = 0; + bsw_32 (ctx->wbuf, SHA256_BLOCK_SIZE >> 2); + Sha256_compile__ (ctx); + } + + if (len != 0) + { + ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, (u32) len, sp, (u32) len); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + } + + return; +} + +/* SHA256 Final padding and digest calculation */ + +/*===========================================================================*\ + Function :SHA_fin1 + Description : + Calls : + Called by : + Return :void - + Parameters : + unsigned char hval[] - + SHA256_CTX ctx[1] - + const unsigned int hlen - + Note : +\*===========================================================================*/ +NSTACK_STATIC void +SHA_fin1 (u8 hval[], SHA256_CTX ctx[1], const unsigned int hlen) +{ + u32 i = (u32) (ctx->count[0] & SHA256_MASK); + + /* Not unusal shift operation. Checked with purify. */ + + /*put bytes in the buffer in an order in which references to */ + /*32-bit words will put bytes with lower addresses into the */ + /*top of 32 bit words on BOTH big and little endian machines */ + bsw_32 (ctx->wbuf, (i + 3) >> 2); + + /*we now need to mask valid bytes and add the padding which is */ + /*a single 1 bit and as many zero bits as necessary. Note that */ + /*we can always add the first padding byte here because the */ + /*buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] &= (u32) 0xffffff80 << 8 * (~i & 3); + ctx->wbuf[i >> 2] |= (u32) 0x00000080 << 8 * (~i & 3); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if (i > SHA256_BLOCK_SIZE - 9) + { + if (i < 60) + { + ctx->wbuf[15] = 0; + } + + Sha256_compile__ (ctx); + i = 0; + } + else + { + /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + } + + while (i < 14) + { + /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + } + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + Sha256_compile__ (ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* mislaigned for 32-bit words */ + for (i = 0; i < hlen; ++i) + { + hval[i] = (u8) (ctx->hash[i >> 2] >> (8 * (~i & 3))); + } + + return; +} + +/* +Description: Internal data for SHA256 digest calculation +Value Range: None +Access: Used to store internal data for SHA256 digest calculation +Remarks: +*/ +static const u32 g_i256[] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +/*===========================================================================*\ + Function :Sha256_set + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + Note : +\*===========================================================================*/ +void +Sha256_set (SHA256_CTX ctx[1]) +{ + int ret; + ctx->count[0] = ctx->count[1] = 0; + + ret = MEMCPY_S (ctx->hash, sizeof (ctx->hash), g_i256, sizeof (g_i256)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + return; +} + +/*===========================================================================*\ + Function :Sha256_fin + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + unsigned char hval[] - + Note : +\*===========================================================================*/ +void +Sha256_fin (SHA256_CTX ctx[1], u8 hval[]) +{ + SHA_fin1 (hval, ctx, SHA256_DIGEST_SIZE); + + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif diff --git a/src/framework/common/include/compile_config.h b/src/framework/common/include/compile_config.h new file mode 100644 index 0000000..2ec5373 --- /dev/null +++ b/src/framework/common/include/compile_config.h @@ -0,0 +1,30 @@ +/* +* +* 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 COMPILE_CONFIG_H +#define COMPILE_CONFIG_H + +#ifndef NSTACK_STATIC +#ifndef NSTACK_STATIC_CHECK +#define NSTACK_STATIC static +#else +#define NSTACK_STATIC +#endif +#endif + +#include "compiling_check.h" + +#endif /*compile_config.h */ diff --git a/src/framework/common/include/compiling_check.h b/src/framework/common/include/compiling_check.h new file mode 100644 index 0000000..e4a7538 --- /dev/null +++ b/src/framework/common/include/compiling_check.h @@ -0,0 +1,106 @@ +/* +* +* 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 COMPILING_CHECK_H +#define COMPILING_CHECK_H + +/* protect the value of macro whose value impacts the version + * compatibility, can't be changed!!! */ +#define COMPAT_PROTECT(name, value) \ +static inline char value_of_##name##_equal_to() \ +{ \ + char __dummy1[(name) - (value)]; \ + char __dummy2[(value) - (name)]; \ + return __dummy1[-1] + __dummy2[-1]; \ +} + +/* check whether struct size is equal to a special value */ +#define SIZE_OF_TYPE_EQUAL_TO(type, size) \ +static inline char size_of_##type##_equal_to_##size() \ +{ \ + char __dummy1[sizeof(type) - size]; \ + char __dummy2[size - sizeof(type)]; \ + return __dummy1[-1] + __dummy2[-1]; \ +} + +/* check whether struct size is not equal to a special value */ +#define SIZE_OF_TYPE_UNEQUAL_TO(type, size) \ +static inline char size_of_##type##_unequal_to_##size() \ +{ \ + char __dummy1[0==(10/(sizeof(type)-size))]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is not larger than a special value */ +#define SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ +static inline char size_of_##type##_not_larger_than_##size() \ +{ \ + char __dummy1[size - sizeof(type)]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size + sizeof(void*) is not larger than a special value */ +/* reserve 8 bytes for 64 bits pointers */ +#define SIZE_OF_TYPE_PLUS8_NOT_LARGER_THAN(type, size) \ +static inline char size_of_##type##_not_larger_than_##size() \ +{ \ + char __dummy1[size - sizeof(type) - sizeof(void*)]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is not smaller than a special value */ +#define SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ +static inline char size_of_##type##_not_smaller_than_##size() \ +{ \ + char __dummy1[sizeof(type) - size]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is smaller than a special value */ +#define SIZE_OF_TYPE_SMALLER_THAN(type, size) \ + SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ + SIZE_OF_TYPE_UNEQUAL_TO(type, size) + +/* check whether struct size is larger than a special value */ +#define SIZE_OF_TYPE_LARGER_THAN(type, size) \ + SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ + SIZE_OF_TYPE_UNEQUAL_TO(type, size) + +/* check whether struct size is smaller than a special value, version 2 */ +#define SIZE_OF_TYPE_SMALLER_THAN2(type, size) \ +static inline char size_of_##type##_smaller_than2_##size() \ +{ \ + char __dummy1[size - sizeof(type) - 1]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is larger than a special value, version 2 */ +#define SIZE_OF_TYPE_LARGER_THAN2(type, size) \ +static inline char size_of_##type##_larger_than2_##size() \ +{ \ + char __dummy1[sizeof(type) - size - 1]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is equal to an integer multiple of a special value */ +#define SIZE_OF_TYPE_IS_MULTIPLE_OF(type, size) \ +static inline char size_of_##type##_is_multiple_of_##size() \ +{ \ + char __dummy1[0 - (sizeof(type) % size)]; \ + return __dummy1[-1]; \ +} + +#endif /*compiling_check.h */ diff --git a/src/framework/common/include/ephlist.h b/src/framework/common/include/ephlist.h new file mode 100644 index 0000000..90491b0 --- /dev/null +++ b/src/framework/common/include/ephlist.h @@ -0,0 +1,199 @@ +/* +* +* 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 _EPHLIST_H_ +#define _EPHLIST_H_ + +#include +#include "types.h" +#include "common_mem_pal.h" +#include "common_mem_buf.h" +#include "common_pal_bitwide_adjust.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +struct ep_hlist_node +{ + struct ep_hlist_node *next, **pprev; +}; + +struct ep_node_list +{ + struct ep_hlist_node *head; + struct ep_hlist_node *tail; +}; + +struct ep_hlist +{ + struct ep_hlist_node node; + struct ep_hlist_node *head; + struct ep_hlist_node *tail; +}; + +#define ep_hlist_entry(ptr, type, member) container_of(ptr, type, member) + +#define EP_HLIST_INIT_NODE(node) {\ + (node)->next = NULL;\ + (node)->pprev = NULL; \ + } + +#define EP_HLIST_INIT(ptr) {\ + EP_HLIST_INIT_NODE(&((ptr)->node)); \ + (ptr)->head = (struct ep_hlist_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + (ptr)->tail = (struct ep_hlist_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + } + +#define EP_HLIST_PREV(ptr) ((struct ep_hlist_node*)(ADDR_SHTOL((ptr)->pprev))) +/* list check may below zero check header, because if app crash before + do list->size++, it will lead problem */ +#define EP_HLIST_EMPTY(list) (NULL == ((struct ep_hlist_node*)ADDR_SHTOL((list)->head))->next) +#define EP_HLIST_NODE_LINKED(node) (!(!(node)->pprev)) + +static __inline void ep_hlist_del (struct ep_hlist *list, + struct ep_hlist_node *n); +static __inline void ep_hlist_add_tail (struct ep_hlist *list, + struct ep_hlist_node *node); + +/* + * list , n are local pointer, don't need to cast + */ +static __inline void +ep_hlist_del (struct ep_hlist *list, struct ep_hlist_node *n) +{ + if (!EP_HLIST_NODE_LINKED (n)) + return; + EP_HLIST_PREV (n)->next = n->next; + if (n->next) + { + ((struct ep_hlist_node *) ADDR_SHTOL (n->next))->pprev = n->pprev; + } + else + { + list->tail = (struct ep_hlist_node *) (n->pprev); + } + EP_HLIST_INIT_NODE (n); +} + +/** + * list, node are local pointer , don't need to case + */ +static __inline void +ep_hlist_add_tail (struct ep_hlist *list, struct ep_hlist_node *node) +{ + struct ep_hlist_node *tail = + (struct ep_hlist_node *) ADDR_SHTOL (list->tail); + EP_HLIST_INIT_NODE (node); + node->pprev = (struct ep_hlist_node **) ADDR_LTOSH_EXT (&tail->next); + tail->next = (struct ep_hlist_node *) ADDR_LTOSH_EXT (node); + list->tail = (struct ep_hlist_node *) ADDR_LTOSH_EXT (node); +} + +/*#########################################################*/ +struct list_node +{ + struct list_node *next; +}; + +struct ep_list +{ + struct list_node node; + struct list_node *head; +}; + +#define ep_list_entry(ptr, type, member) container_of(ptr, type, member) + +#define EP_LIST_INIT_NODE(node) {\ + (node)->next = NULL;\ + } + +#define EP_LIST_INIT(ptr) {\ + EP_LIST_INIT_NODE(&((ptr)->node)); \ + (ptr)->head = (struct list_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + } + +#define EP_LIST_EMPTY(list) (NULL == ((struct list_node*)ADDR_SHTOL((list)->head))->next) + +static __inline void ep_list_del (struct ep_list *list, struct list_node *n); +static __inline void ep_list_add_tail (struct ep_list *list, + struct list_node *node); + +/* + * list , n are local pointer, don't need to cast + */ +static __inline void +ep_list_del (struct ep_list *list, struct list_node *n) +{ + if (NULL == n) + { + return; + } + + struct list_node *p_node; + struct list_node *p_prev = NULL; + p_node = ((struct list_node *) ADDR_SHTOL (list->head)); + while (NULL != p_node && p_node != n) + { + p_prev = p_node; + p_node = ((struct list_node *) ADDR_SHTOL (p_node->next)); + } + + if (p_node != n || p_prev == NULL) + { + return; + } + + p_prev->next = n->next; + + EP_LIST_INIT_NODE (n); + return; +} + +/** + * list, node are local pointer , don't need to case + */ +static __inline void +ep_list_add_tail (struct ep_list *list, struct list_node *node) +{ + + struct list_node *p_node; + struct list_node *p_prev = NULL; + p_node = ((struct list_node *) ADDR_SHTOL (list->head)); + while (NULL != p_node) + { + p_prev = p_node; + p_node = ((struct list_node *) ADDR_SHTOL (p_node->next)); + } + + if (NULL == p_prev) + { + return; + } + + EP_LIST_INIT_NODE (node); + p_prev->next = (struct list_node *) ADDR_LTOSH_EXT (node); + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* _HLIST_H_ */ diff --git a/src/framework/common/include/eprb_tree.h b/src/framework/common/include/eprb_tree.h new file mode 100644 index 0000000..558ab2d --- /dev/null +++ b/src/framework/common/include/eprb_tree.h @@ -0,0 +1,84 @@ +/* +* +* 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 _EPRB_TREE_H_ +#define _EPRB_TREE_H_ + +#include +#include +#include "types.h" +#include "common_mem_pal.h" +#include "common_mem_buf.h" +#include "common_pal_bitwide_adjust.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define EP_RB_RED 0 +#define EP_RB_BLACK 1 + +struct ep_rb_node +{ + int color; + + struct ep_rb_node *rb_parent; + struct ep_rb_node *rb_right; + struct ep_rb_node *rb_left; +}; + +/* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct ep_rb_root +{ + struct ep_rb_node *rb_node; +}; + +#define ep_rb_parent(r) ((struct ep_rb_node *)((r)->rb_parent)) + +static inline void +ep_rb_set_parent (struct ep_rb_node *rb, struct ep_rb_node *p) +{ + rb->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (p); +} + +#define ep_rb_entry(ptr, type, member) container_of(ptr, type, member) + +extern void ep_rb_insert_color (struct ep_rb_node *, struct ep_rb_root *); +extern void ep_rb_erase (struct ep_rb_node *, struct ep_rb_root *); +struct ep_rb_node *ep_rb_first (const struct ep_rb_root *); + +static inline void +ep_rb_link_node (struct ep_rb_node *node, + struct ep_rb_node *parent, struct ep_rb_node **rb_link) +{ + + node->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + node->rb_left = node->rb_right = NULL; + + *rb_link = (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + node->color = EP_RB_RED; + +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/common/include/list.h b/src/framework/common/include/list.h new file mode 100644 index 0000000..01860bc --- /dev/null +++ b/src/framework/common/include/list.h @@ -0,0 +1,181 @@ +/* +* +* 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 LIST_H_ +#define LIST_H_ + +#include +#include +#include +#include + +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +struct list_head +{ + union + { + struct list_head *next; + }; + + union + { + struct list_head *prev; + }; +}; + +struct hlist_node +{ + /** + * @pprev: point the previous node's next pointer + */ + union + { + struct hlist_node *next; + }; + + union + { + struct hlist_node **pprev; + }; +}; + +struct hlist_head +{ + struct hlist_node *first; +}; + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_for_each_entry_type(tpos, typeof_tpos,pos, head, member) \ + for (pos = ((head)->next); \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof_tpos, member); 1;}); \ + pos = ((pos)->next)) + +#define LINT_LIST() + +#define list_for_each_entry(tpos, pos, head, member) \ + for (pos = ((head)->next); \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = ((pos)->next)) + +#define list_for_each_entry_list_head(tpos, pos, head, member) \ + for (pos = (struct list_head *)((head)->next); \ + pos && pos != (struct list_head *)(head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = (pos)->next) +#define list_for_each_safe_entry(tpos, pos, n, head, member) \ + for (pos = (head)->next,n = pos->next; \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n,n = (pos)->next) + +#define INIT_LIST_HEAD(list) {(list)->next = (list); (list)->prev = (list);} + +/* + * @head: the list to test. + */ +inline void list_add (struct list_head *newp, struct list_head *head); +inline void list_link (struct list_head *newhead, struct list_head *head); +inline void list_add_tail (struct list_head *newp, struct list_head *head); +inline int list_empty (const struct list_head *head); +inline void list_del (struct list_head *entry); +inline struct list_head *list_get_first (struct list_head *head); +inline void hlist_del_init (struct hlist_node *n); + +struct hlist_tail +{ + struct hlist_node *end; +}; + +struct hlist_ctl +{ + struct hlist_head head; + struct hlist_tail tail; +}; +#define INIT_HLIST_CTRL(ptr) {(ptr)->head.first = NULL; (ptr)->tail.end = NULL;} + +inline int hlist_empty (const struct hlist_head *h); +inline void hlist_add_head (struct hlist_node *n, struct hlist_head *h); + +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +#define INIT_HLIST_NODE(ptr) {(ptr)->next = NULL; (ptr)->pprev = NULL;} +#define hlist_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/*** + * hlist_for_each_entry - iterate over list of given type + * @member: the name of the hlist_node within the struct. + * @head: the head for your list. + * @pos: the &struct hlist_node to use as a loop cursor. + * @tpos: the type * to use as a loop cursor. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_type - iterate over list of given type + * @member: the name of the hlist_node within the struct. + * @head: the head for your list. + * @pos: the &struct hlist_node to use as a loop cursor. + * @tpos: the type * to use as a loop cursor. + */ +#define hlist_for_each_entry_type(tpos, typeof_tpos,pos, head, member) \ + for (pos = (head)->first; \ + pos && ({tpos = hlist_entry(pos, typeof_tpos, member); 1;}); \ + pos = pos->next) + +inline void hlist_del_init (struct hlist_node *n); + +/** + * next must be != NULL + * add n node before next node + * + * @n: new node + * @next: node in the hlist + */ +inline void hlist_add_before (struct hlist_node *n, struct hlist_node *next); + +/** + * next must be != NULL + * add n node after next node + * actual behavior is add after n + * @n: node in the hlist + * @next: new node + */ +inline void hlist_add_after (struct hlist_node *n, struct hlist_node *next); + +/* add after the head */ +inline void hlist_add_head (struct hlist_node *n, struct hlist_head *h); + +inline int hlist_unhashed (const struct hlist_node *h); + +inline int hlist_empty (const struct hlist_head *h); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +}; +/* *INDENT-ON* */ +#endif + +#endif /* HASH_H_ */ diff --git a/src/framework/common/include/pidinfo.h b/src/framework/common/include/pidinfo.h new file mode 100644 index 0000000..7438756 --- /dev/null +++ b/src/framework/common/include/pidinfo.h @@ -0,0 +1,48 @@ +/* +* +* 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 _PIDINFO_H_ +#define _PIDINFO_H_ + +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define NSFW_MAX_FORK_NUM 32 +typedef struct +{ + u32 used_size; + u32 apid[NSFW_MAX_FORK_NUM]; +} nsfw_pidinfo; + +inline i32 nsfw_pidinfo_init (nsfw_pidinfo * pidinfo); +inline int nsfw_add_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_del_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_del_last_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_pid_exist (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_pidinfo_empty (nsfw_pidinfo * pidinfo); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +}; +/* *INDENT-ON* */ +#endif + +#endif /* _PIDINFO_H_ */ diff --git a/src/framework/common/include/sha256.h b/src/framework/common/include/sha256.h new file mode 100644 index 0000000..b1c7f3c --- /dev/null +++ b/src/framework/common/include/sha256.h @@ -0,0 +1,94 @@ +/* +* +* 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 _SHA256_H_ +#define _SHA256_H_ +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Note that the following function prototypes are the same */ +/* for both the bit and byte oriented implementations. But */ +/* the length fields are in bytes or bits as is appropriate */ +/* for the version used. Bit sequences are arrays of bytes */ +/* in which bit sequence indexes increase from the most to */ +/* the least significant end of each byte */ + +#define SHA256_DIGEST_SIZE 32 /* in bytes */ +#define SHA256_BLOCK_SIZE 64 /* in bytes */ + +typedef struct +{ + u32 count[2]; + u32 hash[8]; + u32 wbuf[16]; +} SHA256_CTX; + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +/*===========================================================================*\ + Function :Sha256_upd + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + const unsigned char data[] - + size_t len - + Note : +\*===========================================================================*/ +void Sha256_upd (SHA256_CTX ctx[1], const u8 data[], size_t len); + +/* SHA256 Final padding and digest calculation */ + +/*===========================================================================*\ + Function :Sha256_set + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + Note : +\*===========================================================================*/ +void Sha256_set (SHA256_CTX ctx[1]); + +/*===========================================================================*\ + Function :Sha256_fin + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + unsigned char hval[] - + Note : +\*===========================================================================*/ +void Sha256_fin (SHA256_CTX ctx[1], u8 hval[]); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* _SHA256_H_ */ diff --git a/src/framework/common/include/types.h b/src/framework/common/include/types.h new file mode 100644 index 0000000..c7d013c --- /dev/null +++ b/src/framework/common/include/types.h @@ -0,0 +1,97 @@ +/* +* +* 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 clib_types_h +#define clib_types_h +#include + +/* Standard CLIB types. */ + +/* Define signed and unsigned 8, 16, 32, and 64 bit types + and machine signed/unsigned word for all architectures. */ +typedef char i8; +typedef short i16; + +typedef unsigned char u8; +typedef unsigned short u16; + +typedef int i32; +typedef long long i64; + +typedef unsigned int u32; +typedef unsigned long long u64; + +#ifndef bool +#define bool int +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define container_of(ptr, type, member) ( \ + (type *)((char *)(ptr) - offsetof(type,member)) \ + ) + +#define PRIMARY_ADDR + +typedef struct _nsfw_res +{ + u8 alloc_flag; + u8 u8Reserve; + u16 chk_count; + u32 data; +} nsfw_res; + +static inline void +res_alloc (nsfw_res * res) +{ + res->alloc_flag = TRUE; + res->chk_count = 0; + res->u8Reserve = 0; +} + +static inline int +res_free (nsfw_res * res) +{ + if (TRUE != res->alloc_flag) + { + return -1; + } + res->chk_count = 0; + res->alloc_flag = FALSE; + return 0; +} + +#define NSFW_THREAD __thread + +#endif /*clib_types_h */ diff --git a/src/framework/common/mem_mgr/include/nsfw_mem_desc.h b/src/framework/common/mem_mgr/include/nsfw_mem_desc.h new file mode 100644 index 0000000..1e959d9 --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_mem_desc.h @@ -0,0 +1,172 @@ +/* +* +* 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 _NSFW_MEM_DESC_H +#define _NSFW_MEM_DESC_H +#include +#include +#include +#include "nsfw_mem_api.h" +#include "nsfw_mgr_com_api.h" +#include "nsfw_ring_data.h" + +#define NSFW_MEM_NOT_INIT (0) +#define NSFW_MEM_INIT_ERR (1) +#define NSFW_MEM_INIT_OK (2) + +#define NSFW_NAME_LENCHECK_RET(name, desc) \ + { \ + i32 inamelen = strlen(name); \ + if (inamelen >= NSFW_MEM_APPNAME_LENTH) \ + { \ + NSCOMM_LOGERR("name length check fail] desc=%s, name len=%d, expected max=%d", \ + #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_NAME_LENCHECK_RET_NULL(name, desc) \ + { \ + i32 inamelen = strlen(name); \ + if (inamelen >= NSFW_MEM_APPNAME_LENTH) \ + { \ + NSCOMM_LOGERR("name length check fail] desc=%s, name len=%d, expected max=%d", \ + #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \ + return NULL; \ + } \ + } + +#define NSFW_MEM_PARA_CHECK_RET(handle, pdata, desc, num) {\ + if ((NULL == (handle)) || (NULL == (pdata)) || (num <= 0)\ + || (((struct nsfw_mem_ring*)(handle))->memtype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s,mhandle=%p, pdata=%p, inum=%d", desc, (handle), (pdata), num); \ + return 0; \ + } \ + } + +#define NSFW_MEM_ENQ_PARA_CHECK_RET(handle, desc) {\ + if ((NULL == (handle)) \ + || (((struct nsfw_mem_ring*)(handle))->memtype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s,mhandle=%p", desc, (handle)); \ + return 0; \ + } \ + } + +#define NSFW_MEM_NAME_CHECK_RET_ERR(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, pname=%p, mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_NAME_CHECK_RET_NULL(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, pname=%p, mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NULL; \ + } \ + } + +#define NSFW_MEM_RING_CHECK_RET(pringinfo, pringhandle_array, iringnum) {\ + if ((NULL == pringinfo) || (NULL == pringhandle_array) || (pringinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] pringinfo=%p, iringnum=%d, pringhandle_array=%p, mtype=%d", \ + pringinfo, iringnum, pringhandle_array, pringinfo ? pringinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_RINGV_CHECK_RET(pmpinfo, inum, pringhandle_array, iarray_num) { \ + if ((NULL == pmpinfo) || (NULL == pringhandle_array) \ + || (inum != iarray_num) || (inum <= 0) || (pmpinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] pmpinfo=%p, inum=%d, pringhandle_array=%p, iarray_num=%d", \ + pmpinfo, inum, pringhandle_array, iarray_num, pmpinfo ? pmpinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_MBUF_CHECK_RET_ERR(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, mhandle=%p, mtype=%d", desc, mhandle, entype); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_MBUF_CHECK_RET_NULL(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, mhandle=%p, mtype=%d", desc, mhandle, entype); \ + return NULL; \ + } \ + } + +/*memory access inferface define*/ +typedef struct +{ + i32 (*mem_ops_init) (nsfw_mem_para * para); + void (*mem_ops_destroy) (void); + mzone_handle (*mem_ops_zone_creae) (nsfw_mem_zone * pinfo); + i32 (*mem_ops_zone_createv) (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + mzone_handle (*mem_ops_zone_lookup) (nsfw_mem_name * pname); + i32 (*mem_ops_mzone_release) (nsfw_mem_name * pname); + mpool_handle (*mem_ops_mbfmp_create) (nsfw_mem_mbfpool * pbufinfo); + i32 (*mem_ops_mbfmp_createv) (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, + i32 iarray_num); + mbuf_handle (*mem_ops_mbf_alloc) (mpool_handle mhandle); + i32 (*mem_ops_mbf_free) (mbuf_handle mhandle); + mpool_handle (*mem_ops_mbfmp_lookup) (nsfw_mem_name * pmbfname); + i32 (*mem_ops_mbfmp_release) (nsfw_mem_name * pname); + mring_handle (*mem_ops_sp_create) (nsfw_mem_sppool * pmpinfo); + i32 (*mem_ops_sp_createv) (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, + i32 iarray_num); + i32 (*mem_ops_spring_create) (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, + i32 iringnum); + i32 (*mem_ops_sp_release) (nsfw_mem_name * pname); + mring_handle (*mem_ops_sp_lookup) (nsfw_mem_name * pname); + mring_handle (*mem_ops_ring_create) (nsfw_mem_mring * pringinfo); + mring_handle (*mem_ops_ring_lookup) (nsfw_mem_name * pname); + i32 (*mem_ops_ring_release) (nsfw_mem_name * pname); + ssize_t (*mem_ops_mem_statics) (void *handle, nsfw_mem_struct_type type); + i32 (*mem_ops_mbuf_recycle) (mpool_handle handle); + i32 (*mem_ops_sp_iterator) (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + i32 (*mem_ops_mbuf_iterator) (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +} nsfw_mem_ops; + +typedef struct +{ + nsfw_mem_type entype; + nsfw_mem_ops *stmemop; +} nsfw_mem_attr; + +typedef struct +{ + fw_poc_type enflag; /*app, nStackMain, Master */ +} nsfw_mem_localdata; + +extern nsfw_mem_attr g_nsfw_mem_ops[]; +extern i32 g_mem_type_num; +#endif diff --git a/src/framework/common/mem_mgr/include/nsfw_ring_data.h b/src/framework/common/mem_mgr/include/nsfw_ring_data.h new file mode 100644 index 0000000..99ec0ed --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_ring_data.h @@ -0,0 +1,95 @@ +/* +* +* 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 _NSFW_RING_DATA_H_ +#define _NSFW_RING_DATA_H_ + +#include +#include "types.h" +#include "common_mem_api.h" + +#define VALUE_LEN 40 + +/* +Ring Data has two part; Ver&Data +val is a pointer offset base on rte_perf_ring::Addrbase, this struct support 1TB, it's enough now; +future __int128 maybe used, this type can perfectly solve the version & address rang problem. +*/ +union RingData_U +{ + struct RingData_S + { + /* + value of data, indeed it's a pointer offset base on rte_perf_ring::Addrbase;40bit is enough for user space addr + ver must using 24bit, so val using 40bit; a CAS now just support 64bit; in future, we may using __int128,now __int128 not support well. + */ + volatile unsigned long long val:VALUE_LEN; + /* + version of data, using 16b store version flg is more suitable for Address save, but using 16b version is too short, it's value range is [0-65535]; + between two cpu schedule time (TM-SPACE) of one process/thread, other processes/threads do N times queue oper. if N > 65535, still have a chance of ABA. + if using a 24bit save version flg, if ABA happened, 16777216 times queue oper need done in one TM-SPACE, it's impossible for today cpu. + */ + volatile unsigned long long ver:(64 - VALUE_LEN); + } data_s; + u64 data_l; +}; + +/* + this high perf Ring rely on the init value of Ring Slot; + Ring Must init using PerfRingInit, Pool Must init using PerfPoolInit + + the addrbase is base addr for all element; now we support 1024G offset; + for nstack the Ring element is from hugepage, and the addr is in stack space. + + 1. not support a ring who's element space range bigger than 1024GB + [if one element from heep, one from stack, range will bigger than 1024GB, we not support] + 2. one more thing addr from mmap is in stack + 3. rte_perf_ring must create by rte_perf_ring_create/rte_perf_pool_create +*/ +struct nsfw_mem_ring +{ + u8 memtype; //shared, no shared + u8 ringflag; //scmp, scsp, mcsp,mcmp + u16 reserv; //reserv data + u32 size; //size of the Ring, must 2^n + u32 eltsize; //for sppool, it is the size of per buf, if is ring, eltsize is zero. + u32 mask; //mask of the Ring, used mask mod Head/Tail to get real pos, must 2^n-1 + void *Addrbase; /*Cause the Addr we support just 40b(1024G), we using a basAddr+offset to get the real addr; ring[x].data_s.val just store offset; + * not used when no shared mode + */ + volatile u32_t prodhflag; //for nshmem fork recover + volatile u32_t prodtflag; //for nshmem fork recover + volatile u32_t conshflag; //for nshmem fork recover + volatile u32_t constflag; //for nshmem fork recover + nsfw_res res_chk; + + struct + { + volatile u32 head; //Head of the Ring, used to indicat pos where to pull a val + volatile u32 tail; //for nshmem, shmem not used. + } prod; + struct + { + volatile u32 head; //for nshmem, shmem not used. + volatile u32 tail; //Tail of the Ring, used to indicat pos where to push a val + } cons; + u32 uireserv[4]; //reserved for update + union RingData_U ring[0]; //Value of Ring +}; + +#define PERFRING_ADDR_RANGE (0xFFFFFFFFFFL) + +#endif /*_NSFW_RING_DATA_H_*/ diff --git a/src/framework/common/mem_mgr/include/nsfw_ring_fun.h b/src/framework/common/mem_mgr/include/nsfw_ring_fun.h new file mode 100644 index 0000000..57a7bf3 --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_ring_fun.h @@ -0,0 +1,110 @@ +/* +* +* 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 _NSFW_RING_FUN_H_ +#define _NSFW_RING_FUN_H_ + +#include +#include "common_pal_bitwide_adjust.h" +#include "nsfw_mem_api.h" +#include "nsfw_ring_data.h" + +/* + for nstack I advise addrbase set to lowest of mmaped hugepage Addr. + to simple: + 1. ring element is from mmaped mem, set Addrbase to 0x7fffffffffff - 0xffffffffff is OK; + 1. ring element is from heap, set Addrbase to NULL is ok; +*/ +static inline void +nsfw_mem_ring_init (struct nsfw_mem_ring *ring, unsigned int size, + void *addrbase, unsigned char memtype, unsigned char flag) +{ + unsigned int loop = 0; + + if (!ring) + { + return; + } + + ring->prod.head = 0; + ring->prod.tail = 0; + ring->cons.head = 0; + ring->cons.tail = 0; + ring->size = size; + ring->eltsize = 0; + ring->mask = size - 1; + ring->memtype = memtype; + ring->ringflag = flag; + ring->prodtflag = ring->prodhflag = get_sys_pid (); + ring->conshflag = ring->constflag = get_sys_pid (); + /*if shmem, addrbase already changed to primary memory address */ + ring->Addrbase = addrbase; + ring->uireserv[0] = 0; + ring->uireserv[1] = 0; + ring->uireserv[2] = 0; + ring->uireserv[3] = 0; + + /*init Ring */ + for (loop = 0; loop < size; loop++) + { + /* + for a empty ring, version is the mapping head val - size + so the empty ring's ver is loop-size; + */ + ring->ring[loop].data_s.ver = (loop - size); + ring->ring[loop].data_s.val = 0; + } +} + +/* +another way to init Pool while no continuous space +1. init a empt rte_perf_ring +2. add element to PerRing. +*/ +static inline void +nsfw_mem_pool_head_init (struct nsfw_mem_ring *ring, unsigned int size, + unsigned int eltsize, void *addrbase, + nsfw_mem_type memtype, nsfw_mpool_type flag) +{ + ring->prod.head = size; + ring->prod.tail = size; + ring->cons.head = 0; + ring->cons.tail = 0; + ring->size = size; + ring->eltsize = eltsize; + ring->mask = size - 1; + ring->memtype = memtype; + ring->ringflag = flag; + ring->prodtflag = ring->prodhflag = get_sys_pid (); + ring->conshflag = ring->constflag = get_sys_pid (); + /*if shmem, addrbase already changed to primary memory address */ + ring->Addrbase = addrbase; + ring->uireserv[0] = 0; + ring->uireserv[1] = 0; + ring->uireserv[2] = 0; + ring->uireserv[3] = 0; + return; +} + +#define NSFW_RING_FLAG_CHECK_RET(handle, desc) {\ + if (((struct nsfw_mem_ring*)mhandle)->ringflag >= NSFW_MPOOL_TYPEMAX) \ + { \ + NSCOMM_LOGERR("invalid ring] desc=%s, ringflag=%d", desc, ((struct nsfw_mem_ring*)mhandle)->ringflag); \ + return 0; \ + } \ + } + +#endif /*_NSFW_RING_FUN_H_*/ diff --git a/src/framework/common/mem_mgr/nsfw_mem_api.c b/src/framework/common/mem_mgr/nsfw_mem_api.c new file mode 100644 index 0000000..b795921 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_api.c @@ -0,0 +1,879 @@ +/* +* +* 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 +#include +#include "nsfw_mem_desc.h" +#include "nstack_securec.h" + +#ifdef SYS_MEM_RES_STAT +#include "common_mem_ring.h" +#include "common_mem_mempool.h" +#endif + +#define MEM_OP_CALL_OK_RET(mtype, fun, para) { \ + if (g_nsfw_mem_ops[mtype].stmemop->fun) \ + { \ + return g_nsfw_mem_ops[mtype].stmemop->fun para; \ + } \ + } + +/***************************************************************************** +* Prototype : nsfw_mem_init +* Description : memory mgr module init +* Input : point to nstak_fwmem_para +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_init (void *para) +{ + nsfw_mem_para *ptempara = NULL; + i32 iret = NSFW_MEM_OK; + i32 icount = 0; + i32 iindex = 0; + + if (NULL == para) + { + NSCOMM_LOGERR ("ns mem init input error"); + return NSFW_MEM_ERR; + } + + ptempara = (nsfw_mem_para *) para; + + if (ptempara->enflag >= NSFW_PROC_MAX) + { + NSCOMM_LOGERR ("ns mem init input enflag invalid] enflag=%d", + ptempara->enflag); + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("ns mem init begin] enflag=%d, iargsnum=%d", + ptempara->enflag, ptempara->iargsnum); + + for (iindex = 0; iindex < ptempara->iargsnum; iindex++) + { + NSCOMM_LOGINF ("%s", ptempara->pargs[iindex]); + } + + for (icount = 0; icount < g_mem_type_num; icount++) + { + if ((NULL != g_nsfw_mem_ops[icount].stmemop) + && (NULL != g_nsfw_mem_ops[icount].stmemop->mem_ops_init)) + { + iret = g_nsfw_mem_ops[icount].stmemop->mem_ops_init (ptempara); + + if (NSFW_MEM_OK != iret) + { + NSCOMM_LOGERR ("mem init failed]index=%d, memtype=%d", icount, + g_nsfw_mem_ops[icount].entype); + break; + } + } + } + + /*if some module init fail, destory the moudles that success */ + if (icount < g_mem_type_num) + { + for (iindex = 0; iindex < icount; iindex++) + { + if (g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy) + { + g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy (); + } + } + + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("ns mem init end"); + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_create +* Description : create a block memory with name +* nsfw_mem_zone::stname +* nsfw_mem_zone::isize +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pinfo +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_mem_zone_create (nsfw_mem_zone * pinfo) +{ + + if ((NULL == pinfo) || (pinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("zone create input para error] pinfo=%p, mtype=%d", + pinfo, pinfo ? pinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pinfo->stname.entype, mem_ops_zone_creae, (pinfo)); + NSCOMM_LOGINF ("mem create fail] memtype=%d, name=%s, size=%zu", + pinfo->stname.entype, pinfo->stname.aname, pinfo->lenth); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_createv +* Description : create some memory blocks +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pmeminfo +* i32 inum +* mzone_handle* paddr_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_zone_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + if ((NULL == pmeminfo) || (NULL == paddr_array) + || (inum != iarray_num) || (inum <= 0) + || (pmeminfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR + ("input para error] pmeminfo=%p, inum=%d, paddr_array=%p, iarray_num=%d, mtype=%d", + pmeminfo, inum, paddr_array, iarray_num, + pmeminfo ? pmeminfo[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + + MEM_OP_CALL_OK_RET (pmeminfo[0].stname.entype, mem_ops_zone_createv, + (pmeminfo, inum, paddr_array, iarray_num)); + NSCOMM_LOGINF ("mem create fail] memtype=%d", pmeminfo[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_lookup +* Description : look up a memory +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_mem_zone_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "mem zone look up"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_zone_lookup, (pname)); + NSCOMM_LOGERR ("mem lookup fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_release +* Description : release a memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_zone_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "mem zone release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_mzone_release, (pname)); + NSCOMM_LOGERR ("mem release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_create +* Description : create a mbuf pool +* Input : nsfw_mem_mbfpool* pbufinfo +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mpool_handle +nsfw_mem_mbfmp_create (nsfw_mem_mbfpool * pbufinfo) +{ + if ((NULL == pbufinfo) || (pbufinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pbufinfo=%p, mtype=%d", pbufinfo, + pbufinfo ? pbufinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pbufinfo->stname.entype, mem_ops_mbfmp_create, + (pbufinfo)); + NSCOMM_LOGERR ("mbufmp create fail] memtype=%d, name=%s ", + pbufinfo->stname.entype, pbufinfo->stname.aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_createv +* Description : create some mbuf pools +* 1. the name of lenth must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mbfpool* pmbfname +* i32 inum +* mpool_handle* phandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbfmp_createv (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + if ((NULL == pmbfname) || (NULL == phandle_array) + || (inum != iarray_num) || (inum <= 0) + || (pmbfname[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR + ("input para error] pmbfname=%p, inum=%d, phandle_array=%p, iarray_num=%d", + pmbfname, inum, phandle_array, iarray_num, + pmbfname ? pmbfname[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + + MEM_OP_CALL_OK_RET (pmbfname[0].stname.entype, mem_ops_mbfmp_createv, + (pmbfname, inum, phandle_array, iarray_num)); + NSCOMM_LOGERR ("mbufmp createv fail] memtype=%d", + pmbfname[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_alloc +* Description : alloc a mbuf from mbuf pool +* Input : mpool_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : mbuf_handle +* Calls : +* Called By : +*****************************************************************************/ +mbuf_handle +nsfw_mem_mbf_alloc (mpool_handle mhandle, nsfw_mem_type entype) +{ + NSFW_MEM_MBUF_CHECK_RET_NULL (mhandle, entype, "mbf alloc"); + MEM_OP_CALL_OK_RET (entype, mem_ops_mbf_alloc, (mhandle)); + NSCOMM_LOGERR ("mbf alloc fail] handle=%p, type=%d", mhandle, entype); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_free +* Description : put a mbuf backintp mbuf pool +* Input : mbuf_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbf_free (mbuf_handle mhandle, nsfw_mem_type entype) +{ + NSFW_MEM_MBUF_CHECK_RET_ERR (mhandle, entype, "mbuf free"); + MEM_OP_CALL_OK_RET (entype, mem_ops_mbf_free, (mhandle)); + NSCOMM_LOGERR ("mbf free fail] handle=%p, type=%d", mhandle, entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_lookup +* Description : look up mbuf mpool +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pmbfname +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mpool_handle +nsfw_mem_mbfmp_lookup (nsfw_mem_name * pmbfname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pmbfname, "mbuf pool look up"); + MEM_OP_CALL_OK_RET (pmbfname->entype, mem_ops_mbfmp_lookup, (pmbfname)); + NSCOMM_LOGERR ("mbufmp lookup fail] memtype=%d, name=%s ", pmbfname->entype, + pmbfname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_release +* Description : release mbuf pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbfmp_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "mbuf mp release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_mbfmp_release, (pname)); + NSCOMM_LOGERR ("mbfmp release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_create +* Description : create a simple pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_sp_create (nsfw_mem_sppool * pmpinfo) +{ + if ((NULL == pmpinfo) || (pmpinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pmpinfo=%p, mtype=%d", pmpinfo, + pmpinfo ? pmpinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pmpinfo->stname.entype, mem_ops_sp_create, (pmpinfo)); + NSCOMM_LOGERR ("sp create fail] memtype=%d, name=%s ", + pmpinfo->stname.entype, pmpinfo->stname.aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_createv +* Description : create some simple pools one time +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* i32 inum +* mring_handle* pringhandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_createv (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_MEM_RINGV_CHECK_RET (pmpinfo, inum, pringhandle_array, iarray_num); + MEM_OP_CALL_OK_RET (pmpinfo[0].stname.entype, mem_ops_sp_createv, + (pmpinfo, inum, pringhandle_array, iarray_num)); + NSCOMM_LOGERR ("sp createv fail] memtype=%d", pmpinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_ring_create +* Description : create a simple pool with many rings +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mring* pringinfo +* mring_handle* pringhandle_array +* i32 iringnum +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_ring_create (nsfw_mem_mring * pringinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + NSFW_MEM_RING_CHECK_RET (pringinfo, pringhandle_array, iringnum); + MEM_OP_CALL_OK_RET (pringinfo[0].stname.entype, mem_ops_spring_create, + (pringinfo, pringhandle_array, iringnum)); + NSCOMM_LOGERR ("mppool spring creat fail] memtype=%d", + pringinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_release +* Description : release a simple mempool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_sp_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "sp release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_sp_release, (pname)); + NSCOMM_LOGERR ("sp release fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_lookup +* Description : look up a simpile ring +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_sp_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "sp look up"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_sp_lookup, (pname)); + NSCOMM_LOGERR ("sp lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_create +* Description : create a ring +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. shared memory ring (NSFW_SHMEM) just can put a pointor into the queue, the queue also point to a shared block memory. +* no shared memory ring(NSFW_NSHMEM) is other wise. +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_ring_create (nsfw_mem_mring * pringinfo) +{ + if ((NULL == pringinfo) || (pringinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pmpinfo=%p, mtype=%d", pringinfo, + pringinfo ? pringinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pringinfo->stname.entype, mem_ops_ring_create, + (pringinfo)); + NSCOMM_LOGERR ("ring create fail] memtype=%d, name=%s ", + pringinfo->stname.entype, pringinfo->stname.aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_lookup +* Description : look up a ring by name +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note: +* 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +* +*****************************************************************************/ +mring_handle +nsfw_mem_ring_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "ring lookup"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_ring_lookup, (pname)); + NSCOMM_LOGERR ("ring lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_reset +* Description : reset the number of producer and consumer, also, the +* state of ring reset to empty +* notes : must be called before doing any operations base on the ring +* Input : mring_handle mhandle +* nsfw_mpool_type entype +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_ring_reset (mring_handle mhandle, nsfw_mpool_type entype) +{ + u32 loop = 0; + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) mhandle; + + if (!ring) + { + return; + } + + ring->prod.head = 0; + ring->cons.tail = 0; + ring->ringflag = (u8) entype; + + /*init Ring */ + for (loop = 0; loop < ring->size; loop++) + { + /* + for a empty ring, version is the mapping head val - size + so the empty ring's ver is loop-size; + */ + ring->ring[loop].data_s.ver = (loop - ring->size); + ring->ring[loop].data_s.val = 0; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_free_count +* Description : get the free number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_ring_free_count (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + thead = temp->prod.head; + ttail = temp->cons.tail; + return ttail + temp->size - thead; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_using_count +* Description : get the in using number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_ring_using_count (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + thead = temp->prod.head; + ttail = temp->cons.tail; + return thead - ttail; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_size +* Description : get size of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +*****************************************************************************/ +u32 +nsfw_mem_ring_size (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + + return temp->size; +} + +#ifdef SYS_MEM_RES_STAT +/***************************************************************************** +* Prototype : nsfw_mem_mbfpool_free_count +* Description : get the free mbuf count of a mbuf pool +* Input : mpool_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_mbfpool_free_count (mpool_handle mhandle) +{ + if (!mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + struct common_mem_mempool *mp = (struct common_mem_mempool *) mhandle; + struct common_mem_ring *mp_ring = + (struct common_mem_ring *) (mp->ring_align); + if (!mp_ring) + { + NSCOMM_LOGERR ("ring is null"); + return 0; + } + u32 p_head = mp_ring->prod.head; + u32 c_tail = mp_ring->cons.tail; + + return p_head - c_tail; +} +#endif /* SYS_MEM_RES_STAT */ + +/***************************************************************************** +* Prototype : nsfw_mem_ring_release +* Description : release a ring memory +* notes : the lenth of name must be less than NSFW_MEM_APPNAME_LENTH +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_ring_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "ring release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_ring_release, (pname)); + NSCOMM_LOGERR ("ring release fail] name=%s, type=%d", pname->aname, + pname->entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_get_len +* Description : statics mbufpool, sppool, ring mem size. +* return: <=0, err happen, >0 mem size +* NSFW_MEM_MZONE: not surport because you already know the lenth when create +* Input : void * handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t +nsfw_mem_get_len (void *handle, nsfw_mem_struct_type type) +{ + if (NULL == handle) + { + NSCOMM_LOGERR ("input para error] handle=%p", handle); + return -1; + } + if ((NSFW_MEM_SPOOL == type) || (NSFW_MEM_RING == type)) + { + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + if (ring->memtype >= NSFW_MEM_TYPEMAX) + { + NSCOMM_LOGERR ("invalid ring] ring type=%u ,handle=%p", + ring->memtype, handle); + return -1; + } + MEM_OP_CALL_OK_RET (ring->memtype, mem_ops_mem_statics, (handle, type)); + } + else + { + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mem_statics, (handle, type)); + } + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbuf_pool_recycle +* Description : recycle mbuf +* Input : mpool_handle handle +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_mbuf_pool_recycle (mpool_handle handle) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mbuf_recycle, (handle)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_iterator +* Description : spool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_sp_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbuf_iterator +* Description : mbuf iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mbuf_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_dfx_ring_print +* Description : print ring info +* Input : mring_handle mhandle +* Output : None +* Return Value : if no err happen, return the lenth of string print, 0 or -1 maybe err happen +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_dfx_ring_print (mring_handle mhandle, char *pbuf, int lenth) +{ + struct nsfw_mem_ring *temp = (struct nsfw_mem_ring *) mhandle; + u32 head = 0; + u32 tail = 0; + int ret = 0; + if ((!temp) || (!pbuf) || (lenth <= 0)) + { + return 0; + } + head = temp->prod.head; + tail = temp->cons.tail; + ret = + SPRINTF_S (pbuf, lenth, + "[.Head=%u,\n .Tail=%u,\n .(|Tail-Head|)=%u,\n .size=%u,\n .mask=%u]\n", + head, tail, (tail >= head) ? (tail - head) : (head - tail), + temp->size, temp->mask); + return ret; +} diff --git a/src/framework/common/mem_mgr/nsfw_mem_construct.c b/src/framework/common/mem_mgr/nsfw_mem_construct.c new file mode 100644 index 0000000..ed6fe27 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_construct.c @@ -0,0 +1,21 @@ +/* +* +* 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 "nsfw_init.h" +#include "nsfw_mem_api.h" + +NSFW_MODULE_NAME (NSFW_MEM_MGR_MODULE) +NSFW_MODULE_PRIORITY (10) NSFW_MODULE_INIT (nsfw_mem_init) diff --git a/src/framework/common/mem_mgr/nsfw_mem_desc.c b/src/framework/common/mem_mgr/nsfw_mem_desc.c new file mode 100644 index 0000000..d0fbfd3 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_desc.c @@ -0,0 +1,92 @@ +/* +* +* 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 +#include +#include "nsfw_mem_desc.h" +#include "nsfw_shmem_mdesc.h" +#include "nsfw_nshmem_mdesc.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_nshmem_ring.h" + +/* *INDENT-OFF* */ +/*the order you add must be NSFW_SHMEM, NSFW_NSHMEM*/ +nsfw_mem_attr g_nsfw_mem_ops[] = +{ + {NSFW_SHMEM, &g_shmem_ops}, + {NSFW_NSHMEM, &g_nshmem_ops}, +}; + +i32 g_mem_type_num = sizeof(g_nsfw_mem_ops) / sizeof(nsfw_mem_attr); + + +nsfw_ring_ops g_ring_ops_arry[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX] = { + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_singlethread_dequeuev + } + }, + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_singlethread_dequeuev + } + } +}; +/* *INDENT-ON* */ diff --git a/src/framework/common/mem_mgr/nsfw_mem_stat.c b/src/framework/common/mem_mgr/nsfw_mem_stat.c new file mode 100644 index 0000000..f7a1f41 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_stat.c @@ -0,0 +1,292 @@ +/* +* +* 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 +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_MEM_STAT_NUM 512 + +#define NSFW_MEM_STAT_MODULE "nsfw_mem_stat_module" + +typedef struct _nsfw_mem_stat +{ + u8 mem_type; + u8 alloc_flag; + char module[NSFW_MEM_MODULE_LEN]; + char mem_name[NSFW_MEM_NAME_LEN]; + u32 mem_size; +} nsfw_mem_stat_t; + +nsfw_mem_stat_t g_mem_stat[NSFW_MEM_STAT_NUM]; + +#ifdef SYS_MEM_RES_STAT +#define MAX_STAT_ITEM_NUM 20 +typedef struct _mem_stat_item_t +{ + char name[32]; + u64 size; +} mem_stat_item_t; + +typedef struct _mem_stat_mgr_t +{ + u32 item_num; + mem_stat_item_t item[MAX_STAT_ITEM_NUM]; +} mem_stat_mgr; + +mem_stat_mgr g_max_mem_list; +#endif + +/***************************************************************************** +* Prototype : nsfw_mem_stat +* Description : add memory stat +* Input : char *module +* char *mem_name +* u8 mem_type +* u32 mem_size +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_stat (char *module, char *mem_name, u8 mem_type, u32 mem_size) +{ + if (NULL == module || NULL == mem_name) + { + NSFW_LOGERR ("argv err]module=%p,mem_name=%p", module, mem_name); + return; + } + + int i; + nsfw_mem_stat_t *mem_stat_item = NULL; + for (i = 0; i < NSFW_MEM_STAT_NUM; i++) + { + if (FALSE == g_mem_stat[i].alloc_flag) + { + g_mem_stat[i].alloc_flag = TRUE; + mem_stat_item = &g_mem_stat[i]; + break; + } + } + + if (NULL == mem_stat_item) + { + NSFW_LOGERR ("mem stat full]module=%s,type=%u,name=%s,size=%u", + module, mem_type, mem_name, mem_size); + return; + } + + mem_stat_item->mem_type = mem_type; + mem_stat_item->mem_size = mem_size; + + if (EOK != STRCPY_S (mem_stat_item->module, NSFW_MEM_MODULE_LEN, module)) + { + NSFW_LOGERR ("STRNCPY_S failed"); + return; + } + if (EOK != STRCPY_S (mem_stat_item->mem_name, NSFW_MEM_NAME_LEN, mem_name)) + { + NSFW_LOGERR ("STRNCPY_S failed"); + return; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_mem_stat_print +* Description : print all memory info +* Input : None +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_stat_print () +{ + int i; + for (i = 0; i < NSFW_MEM_STAT_NUM; i++) + { + if (TRUE == g_mem_stat[i].alloc_flag) + { + NSFW_LOGINF ("mem_module=%s,name=%s,type=%u,size=%u", + g_mem_stat[i].module, g_mem_stat[i].mem_name, + g_mem_stat[i].mem_type, g_mem_stat[i].mem_size); + } + } + +} + +#ifdef SYS_MEM_RES_STAT +void +clear_mem_stat_item () +{ + if (EOK != MEMSET_S ((char *) &g_max_mem_list, sizeof (mem_stat_mgr), + 0, sizeof (mem_stat_mgr))) + { + NSFW_LOGERR ("MEMSET_S failed"); + } +} + +void +insert_mem_stat_item (char *name, u64 len) +{ + int j, temp; + + if (g_max_mem_list.item_num == 0) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[0].name, + sizeof (g_max_mem_list.item[0].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[0].size = len; + g_max_mem_list.item_num++; + return; + } + else if (g_max_mem_list.item_num < MAX_STAT_ITEM_NUM) + { + if (len <= g_max_mem_list.item[g_max_mem_list.item_num - 1].size) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[g_max_mem_list.item_num].name, + sizeof (g_max_mem_list.item + [g_max_mem_list.item_num].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[g_max_mem_list.item_num].size = len; + g_max_mem_list.item_num++; + return; + } + j = 0; + temp = g_max_mem_list.item_num; + while (j < temp) + { + if (len >= g_max_mem_list.item[j].size) + { + goto insert_it; + } + j++; + } + if (j == temp) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[j].name, + sizeof (g_max_mem_list.item[j].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[j].size = len; + g_max_mem_list.item_num++; + return; + } + } + else + { + j = 0; + temp = MAX_STAT_ITEM_NUM - 1; + while (j < MAX_STAT_ITEM_NUM) + { + if (len >= g_max_mem_list.item[j].size) + { + goto insert_it; + } + j++; + } + } + + return; + +insert_it: + while (temp - 1 >= j) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[temp].name, + sizeof (g_max_mem_list.item[temp].name), + g_max_mem_list.item[temp - 1].name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[temp].size = g_max_mem_list.item[temp - 1].size; + temp--; + } + if (EOK != + STRCPY_S (g_max_mem_list.item[j].name, + sizeof (g_max_mem_list.item[j].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[j].size = len; + g_max_mem_list.item_num++; + return; +} + +int +get_mem_stat_item (int idx, char **name, u64 * len) +{ + if (idx < 0 || idx >= MAX_STAT_ITEM_NUM) + { + return -1; + } + + *name = g_max_mem_list.item[idx].name; + *len = g_max_mem_list.item[idx].size; + + return 0; +} +#endif + +static int nsfw_mem_stat_init (void *param); +static int +nsfw_mem_stat_init (void *param) +{ + MEM_STAT (NSFW_MEM_STAT_MODULE, "g_mem_stat", NSFW_NSHMEM, + sizeof (g_mem_stat)); + nsfw_mem_stat_print (); +#ifdef SYS_MEM_RES_STAT + clear_mem_stat_item (); +#endif + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_MEM_STAT_MODULE) +NSFW_MODULE_PRIORITY (99) +NSFW_MODULE_INIT (nsfw_mem_stat_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c new file mode 100644 index 0000000..c78c27e --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c @@ -0,0 +1,47 @@ +/* +* +* 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 "nsfw_mem_desc.h" +#include "nsfw_nshmem_mng.h" +#include "nsfw_nshmem_mdesc.h" + +/*no share memory access inferface*/ +nsfw_mem_ops g_nshmem_ops = { + nsfw_nshmem_init, + nsfw_nshmem_destory, + nsfw_nshmem_create, + NULL, + nsfw_nshmem_lookup, + nsfw_nshmem_release, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nsfw_nshmem_spcreate, + NULL, + NULL, + nsfw_nshmem_sprelease, + nsfw_nshmem_sp_lookup, + nsfw_nshmem_ringcreate, + NULL, + nsfw_nshmem_ringrelease, + nsfw_nshmem_stactic, + NULL, + NULL, /*mem_ops_sp_iterator */ + NULL, /*mem_ops_mbuf_iterator */ +}; diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h new file mode 100644 index 0000000..1b63520 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* 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 _NSFW_NSHMEM_MDESC_H +#define _NSFW_NSHMEM_MDESC_H + +extern nsfw_mem_ops g_nshmem_ops; + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c new file mode 100644 index 0000000..d5661fd --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c @@ -0,0 +1,544 @@ +/* +* +* 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 +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_mem_desc.h" +#include "nsfw_ring_fun.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_nshmem_mng.h" + +#include "common_func.h" + +#define nsfw_get_glb_lock() (&g_nshmem_internal_cfg->mlock) + +#define NSFW_NSHMEM_INIT_CHK_RET_NULL() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSCOMM_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NULL; \ + } + +#define NSFW_NSHMEM_INIT_CHK_RET() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSCOMM_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NSFW_MEM_ERR; \ + } + +nsfw_mem_localdata *g_nshmem_localdata = NULL; +nsfw_nshmem_cfg *g_nshmem_internal_cfg = NULL; + +/*look up a mem zone*/ +NSTACK_STATIC inline nsfw_nshmem_mzone * +nsfw_nshmem_get_free_zone (void) +{ + int icnt = 0; + + /*g_nshmem_internal_cfg must not be null if come here */ + for (icnt = 0; icnt < COMMON_MEM_MAX_MEMZONE; icnt++) + { + if (g_nshmem_internal_cfg->amemzone[icnt].addr == NULL) + { + return &g_nshmem_internal_cfg->amemzone[icnt]; + } + } + + return NULL; +} + +NSTACK_STATIC inline void +nsfw_nshmem_free_zone (nsfw_nshmem_mzone * pzone) +{ + nsfw_nshmem_mzone *pzonebase = &g_nshmem_internal_cfg->amemzone[0]; + nsfw_nshmem_mzone *pzoneend = + &g_nshmem_internal_cfg->amemzone[NSFW_NSHMEM_ZONE_MAX - 1]; + + if ((((int) ((char *) pzone - (char *) pzonebase) < 0) + || ((int) ((char *) pzone - (char *) pzoneend) > 0)) + && ((unsigned int) ((char *) pzone - (char *) pzonebase) % + sizeof (nsfw_nshmem_mzone) != 0)) + { + NSCOMM_LOGERR ("nshmem free fail] mem=%p", pzone); + return; + } + if (pzone->addr) + { + free (pzone->addr); + } + pzone->addr = NULL; + + int ret = MEMSET_S ((void *) pzone, sizeof (nsfw_nshmem_mzone), 0, + sizeof (nsfw_nshmem_mzone)); + if (EOK != ret) + { + NSCOMM_LOGERR ("MEMSET_S failed] mem=%p, ret=%d", pzone, ret); + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_init +* Description : nsh module init +* Input : nsfw_mem_para* para +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_nshmem_init (nsfw_mem_para * para) +{ + i32 iret = NSFW_MEM_OK; + NSCOMM_LOGINF ("nsfw nshmem init begin"); + g_nshmem_localdata = + (nsfw_mem_localdata *) malloc (sizeof (nsfw_mem_localdata)); + + if (NULL == g_nshmem_localdata) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + MEMSET_S (g_nshmem_localdata, sizeof (nsfw_mem_localdata), 0, + sizeof (nsfw_mem_localdata)); + + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_localdata MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_internal_cfg = + (nsfw_nshmem_cfg *) malloc (sizeof (nsfw_nshmem_cfg)); + + if (NULL == g_nshmem_internal_cfg) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_internal_cfg malloc fail"); + goto ERROR; + } + + iret = + MEMSET_S (g_nshmem_internal_cfg, sizeof (nsfw_nshmem_cfg), 0, + sizeof (nsfw_nshmem_cfg)); + + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_internal_cfg MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_localdata->enflag = para->enflag; + NSCOMM_LOGINF ("nsfw nshmem init end"); + goto OK; + +ERROR: + iret = NSFW_MEM_ERR; + nsfw_nshmem_destory (); + return iret; +OK: + iret = NSFW_MEM_OK; + return iret; +} + +/* + * memory destory + */ +void +nsfw_nshmem_destory (void) +{ + if (g_nshmem_localdata) + { + free (g_nshmem_localdata); + g_nshmem_localdata = NULL; + } + + if (g_nshmem_internal_cfg) + { + free (g_nshmem_internal_cfg); + g_nshmem_internal_cfg = NULL; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_reserv_safe +* Description : malloc a memory and save to memzone +* Input : const char* name +* size_t lenth +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_nshmem_reserv_safe (const char *name, size_t lenth) +{ + void *addr = NULL; + i32 iret = NSFW_MEM_OK; + nsfw_nshmem_mzone *pmemzone = NULL; + + if (lenth <= 0) + { + return NULL; + } + + nsfw_write_lock (nsfw_get_glb_lock ()); + + addr = malloc (lenth); + if (!addr) + { + NSCOMM_LOGERR ("nshmem malloc addr fail] addr=%p", addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + iret = MEMSET_S (addr, lenth, 0, lenth); + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem malloc addr MEMSET_S fail] addr=%p", addr); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + pmemzone = nsfw_nshmem_get_free_zone (); + + if (!pmemzone) + { + NSCOMM_LOGERR ("nshmem get free zone fail"); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + pmemzone->addr = addr; + pmemzone->lenth = lenth; + /*name must be less than NSFW_MEM_APPNAME_LENTH */ + if (EOK != + STRCPY_S ((char *) pmemzone->aname, sizeof (pmemzone->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S failed]name=%s", name); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + nsfw_write_unlock (nsfw_get_glb_lock ()); + return addr; +} + +/* + * create no shared memory + * nsfw_mem_zone::stname no shared memory name + * nsfw_mem_zone::isize memory size + */ +mzone_handle +nsfw_nshmem_create (nsfw_mem_zone * pinfo) +{ + + NSFW_NAME_LENCHECK_RET_NULL (pinfo->stname.aname, "nshmem create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + return nsfw_nshmem_reserv_safe (pinfo->stname.aname, pinfo->lenth); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_lookup +* Description : find a block memory by name +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_nshmem_lookup (nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "nshmem lookup"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + nsfw_read_lock (nsfw_get_glb_lock ()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp (pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_read_unlock (nsfw_get_glb_lock ()); + return mz->addr; + } + } + + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_release +* Description : free a block memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_release (nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem release"); + NSFW_NSHMEM_INIT_CHK_RET (); + nsfw_read_lock (nsfw_get_glb_lock ()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp (pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_nshmem_free_zone (mz); + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NSFW_MEM_OK; + } + } + + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NSFW_MEM_OK; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_spcreate +* Description : create a memory pool by ring +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle +nsfw_nshmem_spcreate (nsfw_mem_sppool * pmpinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2 (pmpinfo->usnum + 1); + unsigned int uselt_size = pmpinfo->useltsize; + struct nsfw_mem_ring *pringhead = NULL; + unsigned int uscnt = 0; + char *pmz = NULL; + NSFW_NAME_LENCHECK_RET_NULL (pmpinfo->stname.aname, "nshmem sp create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + + len = + sizeof (struct nsfw_mem_ring) + + (size_t) usnum *sizeof (union RingData_U) + (size_t) usnum *uselt_size; + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe (pmpinfo->stname.aname, + len); + + if (!pringhead) + { + NSCOMM_LOGERR ("nshmem sp create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init (pringhead, usnum, pringhead, NSFW_NSHMEM, + pmpinfo->enmptype); + pmz = + ((char *) pringhead + sizeof (struct nsfw_mem_ring) + + usnum * sizeof (union RingData_U)); + + for (uscnt = 0; uscnt < usnum; uscnt++) + { + if (0 == + g_ring_ops_arry[pringhead->memtype][pringhead-> + ringflag].ring_ops_enqueue + (pringhead, (void *) pmz)) + { + NSCOMM_LOGERR ("nsfw_nshmem_ringenqueue enque fail] uscnt=%u", + uscnt); + } + + pmz = pmz + uselt_size; + } + + return pringhead; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sp_lookup +* Description : look up a sppool memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle +nsfw_nshmem_sp_lookup (nsfw_mem_name * pname) +{ + return nsfw_nshmem_lookup (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sprelease +* Description : release a sp pool +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_sprelease (nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem sp mempool release"); + NSFW_NSHMEM_INIT_CHK_RET (); + return nsfw_nshmem_release (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringcreate +* Description : create a ring +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_nshmem_ringcreate (nsfw_mem_mring * pringinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2 (pringinfo->usnum + 1); + struct nsfw_mem_ring *pringhead = NULL; + NSFW_NAME_LENCHECK_RET_NULL (pringinfo->stname.aname, "nshmem ring create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + + len = sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe (pringinfo->stname.aname, + len); + + if (!pringhead) + { + NSCOMM_LOGERR ("nshmem ring create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init (pringhead, usnum, (void *) pringhead, NSFW_NSHMEM, + pringinfo->enmptype); + return pringhead; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringrelease +* Description : release a nsh ring memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_ringrelease (nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem ring mempool release"); + NSFW_NSHMEM_INIT_CHK_RET (); + return nsfw_nshmem_release (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sppool_statics +* Description : static the memory size of sppool +* Input : mring_handle sppool +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_sppool_statics (mring_handle sppool) +{ + struct nsfw_mem_ring *phead = (struct nsfw_mem_ring *) sppool; + + return sizeof (struct nsfw_mem_ring) + + (ssize_t) phead->size * sizeof (union RingData_U) + + (ssize_t) phead->size * phead->eltsize; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ring_statics +* Description : static the memory size of ring +* Input : mring_handle handle +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_ring_statics (mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof (union RingData_U) + + sizeof (struct nsfw_mem_ring); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_stactic +* Description : static the memory size according to mem type +* Input : void* handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_stactic (void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return -1; + case NSFW_MEM_SPOOL: + return nsfw_nshmem_sppool_statics (handle); + case NSFW_MEM_RING: + return nsfw_nshmem_ring_statics (handle); + default: + break; + } + return -1; +} diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h new file mode 100644 index 0000000..3f5b1b9 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h @@ -0,0 +1,70 @@ +/* +* +* 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 _NSFW_NSHMEM_MNG_H_ +#define _NSFW_NSHMEM_MNG_H_ + +#include "generic/common_mem_rwlock.h" + +#include "common_func.h" + +#define NSFW_NSHMEM_ZONE_MAX 2560 + +typedef struct +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + void *addr; + int lenth; +} nsfw_nshmem_mzone; + +typedef struct +{ + nsfw_nshmem_mzone amemzone[NSFW_NSHMEM_ZONE_MAX]; + common_mem_rwlock_t mlock; +} nsfw_nshmem_cfg; + +/* + * no share memory module init + */ +i32 nsfw_nshmem_init (nsfw_mem_para * para); + +/* + * no share memory moudle destory + */ +void nsfw_nshmem_destory (void); + +/* + * create a no shared memory + */ +mzone_handle nsfw_nshmem_create (nsfw_mem_zone * pinfo); + +mzone_handle nsfw_nshmem_lookup (nsfw_mem_name * pname); + +i32 nsfw_nshmem_release (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_spcreate (nsfw_mem_sppool * pmpinfo); + +i32 nsfw_nshmem_sprelease (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_sp_lookup (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_ringcreate (nsfw_mem_mring * pringinfo); + +i32 nsfw_nshmem_ringrelease (nsfw_mem_name * pname); + +ssize_t nsfw_nshmem_stactic (void *handle, nsfw_mem_struct_type type); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c new file mode 100644 index 0000000..64e7d57 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c @@ -0,0 +1,436 @@ +/* +* +* 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 +#include +#include "nstack_securec.h" + +#include "nsfw_mem_desc.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_func.h" + +/*copy the data to obj*/ +NSTACK_STATIC inline void +nsfw_nshmem_ring_obj_copy (struct nsfw_mem_ring *r, uint32_t cons_head, + void **obj_table, unsigned n) +{ + uint32_t idx = cons_head & r->mask; + unsigned i = 0; + const uint32_t size = r->size; + + if (likely (idx + n < size)) + { + for (i = 0; i < (n & (~(unsigned) 0x3)); i += 4, idx += 4) + { + obj_table[i] = (void *) r->ring[idx].data_l; + obj_table[i + 1] = (void *) r->ring[idx + 1].data_l; + obj_table[i + 2] = (void *) r->ring[idx + 2].data_l; + obj_table[i + 3] = (void *) r->ring[idx + 3].data_l; + } + switch (n & 0x3) + { + case 3: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 2: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 1: + obj_table[i++] = (void *) r->ring[idx++].data_l; + } + } + else + { + for (i = 0; idx < size; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + + for (idx = 0; i < n; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + } +} + +/*fork recover*/ +NSTACK_STATIC inline void +nsfw_nshmem_enqueue_fork_recov (struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid (); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->prodhflag; + + if (unlikely (pidflag != curpid)) + { + success = common_mem_atomic32_cmpset (&r->prodhflag, pidflag, curpid); + + if (unlikely (success != 0)) + { + /*recover it */ + if (r->prod.tail != r->prod.head) + { + r->prod.head = r->prod.tail; + } + + r->prodtflag = curpid; + } + } + + return; +} + +NSTACK_STATIC inline void +nsfw_nshmem_dequeue_fork_recov (struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid (); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->conshflag; + + if (unlikely (pidflag != curpid)) + { + success = common_mem_atomic32_cmpset (&r->conshflag, pidflag, curpid); + + if (unlikely (success != 0)) + { + /*recover it */ + if (r->cons.tail != r->cons.head) + { + r->cons.head = r->cons.tail; + } + + r->constflag = curpid; + } + } + + return; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int +nsfw_nshmem_ring_mp_enqueue (struct nsfw_mem_ring *mem_ring, void *obj_table) +{ + uint32_t prod_head, prod_next; + uint32_t cons_tail, free_entries; + int success; + unsigned rep = 0; + uint32_t mask = mem_ring->mask; + uint32_t size = mem_ring->size; + uint32_t n = 1; + + /* move prod.head atomically */ + do + { + + prod_head = mem_ring->prod.head; + cons_tail = mem_ring->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * prod_head > cons_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = (size + cons_tail - prod_head); + + /* check that we have enough room in ring */ + if (unlikely (n > free_entries)) + { + return 0; + /* Below code is commented currenlty as its a dead code. */ + } + + /*if pid is not the same, maybe mult thread fork happen */ + nsfw_nshmem_enqueue_fork_recov (mem_ring); + + while (unlikely + ((mem_ring->prod.tail != mem_ring->prod.head) + || (mem_ring->prodtflag != mem_ring->prodhflag))) + { + common_mem_pause (); + } + + prod_next = prod_head + n; + success = + common_mem_atomic32_cmpset (&mem_ring->prod.head, prod_head, + prod_next); + } + while (unlikely (success == 0)); + + mem_ring->ring[prod_head & mask].data_l = (u64) obj_table; + + /* + * If there are other enqueues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely (mem_ring->prod.tail != prod_head)) + { + common_mem_pause (); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-empted thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield (); + } + } + + mem_ring->prod.tail = prod_next; + return (int) n; +} + +/* + this is a single thread/process enqueue function + */ +int +nsfw_nshmem_ring_sp_enqueue (struct nsfw_mem_ring *r, void *obj_table) +{ + uint32_t prod_head, cons_tail; + uint32_t prod_next, free_entries; + uint32_t mask = r->mask; + uint32_t n = 1; + uint32_t size = r->size; + + prod_head = r->prod.head; + cons_tail = r->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * prod_head > cons_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = size + cons_tail - prod_head; + + /* check that we have enough room in ring */ + if (unlikely (n > free_entries)) + { + return 0; + } + + nsfw_nshmem_enqueue_fork_recov (r); + + prod_next = prod_head + n; + r->prod.head = prod_next; + + r->ring[prod_head & mask].data_l = (u64) obj_table; + + r->prod.tail = prod_next; + return (int) n; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_nshmem_ring_mc_dequeuev (struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t cons_head, prod_tail; + uint32_t cons_next, entries; + int success; + unsigned rep = 0; + uint32_t num = n; + + /* Avoid the unnecessary cmpset operation below, which is also + * potentially harmful when n equals 0. */ + if (unlikely (num == 0)) + { + return 0; + } + + nsfw_nshmem_dequeue_fork_recov (r); + + /* move cons.head atomically */ + do + { + num = n; + cons_head = r->cons.head; + prod_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = (prod_tail - cons_head); + + /* Set the actual entries for dequeue */ + if (unlikely (num > entries)) + { + if (likely (entries > 0)) + { + num = entries; + } + else + { + return 0; + } + } + + /* check the queue can be operate */ + while (unlikely + ((r->cons.tail != r->cons.head) + || (r->conshflag != r->constflag))) + { + common_mem_pause (); + } + + cons_next = cons_head + num; + + success = + common_mem_atomic32_cmpset (&r->cons.head, cons_head, cons_next); + } + while (unlikely (success == 0)); + + nsfw_nshmem_ring_obj_copy (r, cons_head, obj_table, num); + + /* + * If there are other dequeues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely (r->cons.tail != cons_head)) + { + common_mem_pause (); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-empted thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield (); + } + } + + r->cons.tail = cons_next; + + return (int) num; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +1. while dequeue corrupt, the tail no one added, may multy the try times. +*/ +int +nsfw_nshmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_mc_dequeuev (ring, box, 1); +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_nshmem_ring_sc_dequeuev (struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t cons_head, prod_tail; + uint32_t cons_next, entries; + uint32_t inum = n; + cons_head = r->cons.head; + prod_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = prod_tail - cons_head; + + if (unlikely (inum > entries)) + { + if (likely (entries > 0)) + { + inum = entries; + } + else + { + return 0; + } + } + + nsfw_nshmem_dequeue_fork_recov (r); + + cons_next = cons_head + inum; + r->cons.head = cons_next; + + nsfw_nshmem_ring_obj_copy (r, cons_head, obj_table, inum); + + r->cons.tail = cons_next; + return (int) inum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_nshmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_sc_dequeuev (ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + + /*if queue is full, just return 0 */ + if (unlikely (ring->prod.head >= (ring->size + ring->cons.tail))) + { + return 0; + } + + head = ring->prod.head; + ring->ring[head & ring->mask].data_l = (u64) box; + ring->prod.head++; + return 1; +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_singlethread_dequeuev (ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return num; + } + + box[num] = (void *) ring->ring[tail & ring->mask].data_l; + ring->cons.tail++; + num++; + } + + return num; +} diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h new file mode 100644 index 0000000..93a4d4a --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h @@ -0,0 +1,37 @@ +/* +* +* 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 _NSFW_NSHMEM_RING_H_ +#define _NSFW_NSHMEM_RING_H_ + +#include + +int nsfw_nshmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, + void *box); +int nsfw_nshmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, + void **box); +int nsfw_nshmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_NSHMEM_RING_H_*/ diff --git a/src/framework/common/mem_mgr/nsfw_res_mgr.c b/src/framework/common/mem_mgr/nsfw_res_mgr.c new file mode 100644 index 0000000..2f676c9 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_res_mgr.c @@ -0,0 +1,429 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ + +/*==============================================* + * project-wide global variables * + *----------------------------------------------*/ + +/*==============================================* + * routines' or functions' implementations * + *----------------------------------------------*/ + +#include +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_mbuf.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" + +#include "nsfw_mem_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_ring_data.h" + +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +nsfw_res_mgr_item_cfg g_all_res_can[NSFW_MAX_RES_SCAN_COUNT]; + +#define NSFW_RES_SCAN_TVLAUE_DEF 60 +#define NSFW_RES_SCAN_TVLAUE (g_scan_cfg.scan_tvalue) + +typedef struct _nsfw_res_scan_init_cfg +{ + nsfw_timer_info *scan_timer; + u16 scan_tvalue; +} nsfw_res_scan_init_cfg; +nsfw_res_scan_init_cfg g_scan_cfg; + +u8 +nsfw_res_mgr_reg (nsfw_res_scn_cfg * cfg) +{ + if (NULL == cfg) + { + NSFW_LOGERR ("argv err!"); + return FALSE; + } + + u32 i; + for (i = 0; i < NSFW_MAX_RES_SCAN_COUNT; i++) + { + if ((NULL == g_all_res_can[i].scn_cfg.free_fun) + && + (__sync_bool_compare_and_swap + (&g_all_res_can[i].scn_cfg.free_fun, 0, cfg->free_fun))) + { + g_all_res_can[i].scn_cfg = *cfg; + NSFW_LOGINF ("reg res_mgr fun suc]fun=%p,data=%p", cfg->free_fun, + cfg->data); + return TRUE; + } + } + + NSFW_LOGERR + ("reg]type=%u,per=%u,chk=%u,cyc=%u,total=%u,size=%u,offset=%u,fun=%p,data=%p", + cfg->type, cfg->force_free_percent, cfg->force_free_chk_num, + cfg->num_per_cyc, cfg->total_num, cfg->elm_size, cfg->res_mem_offset, + cfg->res_mem_offset, cfg->free_fun, cfg->data); + return FALSE; +} + +static inline u32 +nsfw_get_alloc_count (u32 head, u32 tail) +{ + if (head >= tail) + { + return head - tail; + } + + return head + (0xFFFFFFFF - tail); +} + +int +nsfw_res_sp_item_chk (void *data, void *argv) +{ + nsfw_res_mgr_item_cfg *res_scn_item = (nsfw_res_mgr_item_cfg *) argv; + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + char *elm = (char *) data; + + if (NULL == scn_cfg || NULL == elm) + { + return FALSE; + } + + nsfw_res *res_item = NULL; + res_item = (nsfw_res *) (elm + scn_cfg->res_mem_offset); + if (0 == res_item->chk_count) + { + res_item->data = res_scn_item->cons_head; + } + res_item->chk_count++; + + if (res_item->chk_count < scn_cfg->force_free_chk_num) + { + return FALSE; + } + + if (res_scn_item->free_percent > scn_cfg->force_free_percent) + { + return FALSE; + } + + if (scn_cfg->total_num * scn_cfg->alloc_speed_factor > + nsfw_get_alloc_count (res_scn_item->cons_head, res_item->data)) + { + return FALSE; + } + + if (NULL == scn_cfg->free_fun) + { + return FALSE; + } + + if (TRUE == scn_cfg->free_fun ((void *) elm)) + { + res_scn_item->force_count++; + } + + res_item->chk_count = 0; + return TRUE; +} + +int +nsfw_res_flash_data (nsfw_res_mgr_item_cfg * res_scn_item) +{ + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + + u32 cur_head = 0; + u32 cur_tail = 0; + u32 elm_num = 0; + u32 free_count = 0; + + switch (scn_cfg->type) + { + case NSFW_RES_SCAN_MBUF: + { + struct common_mem_ring *ring = + (struct common_mem_ring *) scn_cfg->mgr_ring; + struct common_mem_mempool *mp = + (struct common_mem_mempool *) scn_cfg->data; + if (NULL == ring) + { + ring = mp->ring; + if (NULL == ring) + return FALSE; + } + cur_head = ring->prod.head; + cur_tail = ring->cons.head; + elm_num = mp->size; + } + break; + case NSFW_RES_SCAN_SPOOL: + { + struct nsfw_mem_ring *mem_ring = + (struct nsfw_mem_ring *) scn_cfg->mgr_ring; + if (NULL == mem_ring) + { + mem_ring = (struct nsfw_mem_ring *) scn_cfg->data; + if (NULL == mem_ring) + return FALSE; + } + + cur_head = mem_ring->prod.head; + cur_tail = mem_ring->cons.tail; + elm_num = mem_ring->size; + } + break; + case NSFW_RES_SCAN_ARRAY: + { + struct nsfw_mem_ring *mem_ring = + (struct nsfw_mem_ring *) scn_cfg->mgr_ring; + if (NULL == mem_ring) + { + return FALSE; + } + + cur_head = mem_ring->prod.head; + cur_tail = mem_ring->cons.tail; + elm_num = scn_cfg->total_num; + } + break; + default: + return FALSE; + } + + free_count = nsfw_get_alloc_count (cur_head, cur_tail); + + res_scn_item->cons_head = cur_head; + res_scn_item->prod_head = cur_tail; + if (0 != elm_num) + { + res_scn_item->free_percent = free_count * 100 / elm_num; + } + else + { + res_scn_item->free_percent = 100; + } + + scn_cfg->total_num = elm_num; + return TRUE; +} + +void +nsfw_res_scan_mem (nsfw_res_mgr_item_cfg * res_scn_item) +{ + if (NULL == res_scn_item) + { + return; + } + + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + if (NULL == scn_cfg->data) + { + return; + } + + u32 start = res_scn_item->last_scn_idx; + u32 end = start + scn_cfg->num_per_cyc; + int res_chk_number = 0; + if (NSFW_RES_SCAN_SPOOL == scn_cfg->type) + { + res_chk_number = + nsfw_mem_sp_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, (void *) res_scn_item); + } + else + { + res_chk_number = + nsfw_mem_mbuf_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, (void *) res_scn_item); + } + + if (0 == res_chk_number) + { + res_scn_item->last_scn_idx = 0; + start = res_scn_item->last_scn_idx; + end = start + scn_cfg->num_per_cyc; + if (NSFW_RES_SCAN_SPOOL == scn_cfg->type) + { + res_chk_number = + nsfw_mem_sp_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, + (void *) res_scn_item); + } + else + { + res_chk_number = + nsfw_mem_mbuf_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, + (void *) res_scn_item); + } + } + + if (res_chk_number + start < end) + { + res_scn_item->last_scn_idx = 0; + } + else + { + res_scn_item->last_scn_idx += res_chk_number; + } + + return; +} + +void +nsfw_res_scan_array (nsfw_res_mgr_item_cfg * res_scn_item) +{ + if (NULL == res_scn_item) + { + return; + } + + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + if (NULL == scn_cfg->data) + { + return; + } + + u32 i; + char *elm = + (char *) scn_cfg->data + (res_scn_item->last_scn_idx * scn_cfg->elm_size); + for (i = res_scn_item->last_scn_idx; i < scn_cfg->total_num; i++) + { + if (i >= res_scn_item->last_scn_idx + scn_cfg->num_per_cyc) + { + break; + } + + if (TRUE == nsfw_res_sp_item_chk (elm, (void *) res_scn_item)) + { + NSFW_LOGINF ("force free item]data=%p,cfg=%p", elm, res_scn_item); + } + + elm += scn_cfg->elm_size; + } + + if (i >= scn_cfg->total_num) + { + res_scn_item->last_scn_idx = 0; + } + else + { + res_scn_item->last_scn_idx = i; + } + + return; +} + +void +nsfw_res_scan_proc (nsfw_res_mgr_item_cfg * res_scn_item) +{ + (void) nsfw_res_flash_data (res_scn_item); + switch (res_scn_item->scn_cfg.type) + { + case NSFW_RES_SCAN_ARRAY: + nsfw_res_scan_array (res_scn_item); + break; + case NSFW_RES_SCAN_SPOOL: + case NSFW_RES_SCAN_MBUF: + nsfw_res_scan_mem (res_scn_item); + break; + default: + break; + } +} + +int +nsfw_res_scan_all (u32 timer_type, void *data) +{ + NSFW_LOGDBG ("scan start!"); + struct timespec time_left = { NSFW_RES_SCAN_TVLAUE, 0 }; + g_scan_cfg.scan_timer = + nsfw_timer_reg_timer (0, NULL, nsfw_res_scan_all, time_left); + + if (g_hbt_switch) + { + return TRUE; + } + + int i; + for (i = 0; i < NSFW_MAX_RES_SCAN_COUNT; i++) + { + /*last fun */ + if (NULL == g_all_res_can[i].scn_cfg.data) + { + break; + } + + nsfw_res_scan_proc (&g_all_res_can[i]); + } + + return TRUE; +} + +static int nsfw_resmgr_module_init (void *param); +static int +nsfw_resmgr_module_init (void *param) +{ + u8 proc_type = (u8) ((long long) param); + NSFW_LOGINF ("res mgr module init]type=%u", proc_type); + g_scan_cfg.scan_tvalue = NSFW_RES_SCAN_TVLAUE_DEF; + switch (proc_type) + { + case NSFW_PROC_MAIN: + { + struct timespec time_left = { NSFW_RES_SCAN_TVLAUE, 0 }; + g_scan_cfg.scan_timer = + nsfw_timer_reg_timer (0, NULL, nsfw_res_scan_all, time_left); + return 0; + } + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME(NSFW_RES_MGR_MODULE) +NSFW_MODULE_PRIORITY(99) +NSFW_MODULE_INIT(nsfw_resmgr_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c new file mode 100644 index 0000000..dc3400d --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c @@ -0,0 +1,987 @@ +/* +* +* 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 +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_buf.h" +#include "common_mem_common.h" + +#include "common_func.h" + +/*get the base address of msg data */ +#define NSFW_SHMEM_GET_DATA(pmsg, type) (type *)&((pmsg)->aidata[0]) + +/*if input point is nun, just return null*/ +#define NSFW_POINT_CHK_RET_NULL(p, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGERR("point check fail] desc_para=%s", desc); \ + return NULL; \ + } + +/*if input point is nun, just return err num*/ +#define NSFW_POINT_CHK_RET_ERR(p, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGDBG("point check fail] desc_para=%s", desc); \ + return NSFW_MEM_ERR; \ + } + +/*if input point is nun, goto flag*/ +#define NSFW_POINT_CHK_RET_GOTO(p, gotoflag, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGERR("point check fail] desc_para=%s", desc); \ + goto gotoflag; \ + } + +/*init the msg head*/ +#define NSFW_SHMEM_MSG_HEAD_INIT(pmsg, type, lenth) { \ + (pmsg)->usmsg_type = (type); \ + (pmsg)->uslenth = (lenth); \ + } + +/*rsp msg head check, and if err goto*/ +#define NSFW_SHMEM_MSGHEAD_CHK_GOTO(pmsg, type, lenth, gotoflag) { \ + if (((type) != pmsg->usmsg_type) && ((lenth) != pmsg->uslenth)) \ + { \ + NSCOMM_LOGERR("check fail] msgtype=%d, type_para=%d, len=%d", (pmsg->usmsg_type), (type), (lenth)); \ + goto gotoflag; \ + } \ + } + +/*rsp check the state*/ +#define NSFW_SHMEM_ACKSTATE_CHK_GOTO(expret, ret, expseg, seg, gotoflag) { \ + if (((ret) != (expret)) || ((expseg) != (seg))) \ + { \ + NSCOMM_LOGERR("ackstate check fail]msgack exp=%d, real=%d,eseg=%d, rseg=%d", (expret), (ret), (expseg), (seg)); \ + goto gotoflag; \ + } \ + } + +/*mzone msg init*/ +#define NSFW_SHMEM_MZONE_DATA_INIT(pdata, slenth, seg, socketid) { \ + (pdata)->isocket_id = (socketid); \ + (pdata)->lenth = (slenth); \ + (pdata)->usseq = (seg); \ + (pdata)->ireserv = 0; \ + } + +/*mbuf msg init*/ +#define NSFW_SHMEM_MBUF_DATA_INIT(pdata, seg, num, cashsize, priv_size, data_room, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->uscash_size = (cashsize); \ + (pdata)->uspriv_size = (priv_size); \ + (pdata)->usdata_room = (data_room); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mpool msg init*/ +#define NSFW_SHMEM_MPOOL_DATA_INIT(pdata, seg, num, eltsize, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->useltsize = (eltsize); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mring msg init*/ +#define NSFW_SHMEM_MRING_DATA_INIT(pdata, seg, num, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +#define NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg) {\ + if (pmsg) \ + { \ + nsfw_mgr_msg_free(pmsg); \ + } \ + if (prsp_msg) \ + { \ + nsfw_mgr_msg_free(prsp_msg); \ + } \ +} + +/* + * create a block memory by send a msg + * + */ +mzone_handle +nsfw_memzone_remote_reserv (const i8 * name, size_t mlen, i32 socket_id) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head point define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data point define */ + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + /*ack msg define */ + nsfw_shmem_ack *pack_data = NULL; + + mzone_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote reserv pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote reserv rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RESERV_REQ_MSG, + sizeof (nsfw_shmem_reserv_req)); + + /*msg data init */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_reserv_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("reserv mem copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MZONE_DATA_INIT (pdata, mlen, (u16) 0, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("reserv mem req rsp fail] ret=%u", ucret); + goto release; + } + + /*interrupt msg head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RESERV_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, release); + + hhandle = (mzone_handle) ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mem reserve] name=%s, handle=%p, seg=%u", name, hhandle, + pack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some memorys by send a msg + */ +i32 +nsfw_memzone_remote_reserv_v (nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_reserv_req *ptempdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + u16 ussegbase = 0; + u16 ustempv = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_reserv_req); + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (pmsg, err, "remote reserv_v msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, err, "remote reserv_v rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_reserv_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RESERV_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_reserv_req)); + + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT (ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("reserv v mem req rsp fail] ret=%u", ucret); + goto err; + } + + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RESERV_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + err); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + ustempv = ussegbase + iindex; + + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, ustempv, + (u16) pack_data->usseq, err); + + paddr_array[ustempv] = ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("remote reserve]index=%u, seg=%u, handle=%p", + ustempv, pack_data->usseq, paddr_array[ustempv]); + pack_data++; + } + + ussegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT (ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + iretval = NSFW_MEM_OK; + goto free; + +err: + iretval = NSFW_MEM_ERR; +free: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *release a block memory with name by send msg + */ +i32 +nsfw_remote_free (const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_free_req *pdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_ERR (pmsg, "remote free msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, terr, "remote free rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RELEASE_REQ_MSG, + sizeof (nsfw_shmem_free_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_free_req); + if (EOK != STRCPY_S (pdata->aname, sizeof (pdata->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S failed]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("free mem req rsp fail] ret=%u", ucret); + goto release; + } + + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RELEASE_ACK_MSG, + sizeof (nsfw_shmem_ack), terr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, terr); + + iretval = NSFW_MEM_OK; + goto release; +terr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *create a mbuf pool by send a msg + */ +mpool_handle +nsfw_remote_shmem_mbf_create (const i8 * name, unsigned n, + unsigned cache_size, unsigned priv_size, + unsigned data_room_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_msg_head *tpack_head = NULL; + nsfw_shmem_ack *tpack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote mbf create pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote mbf create msg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MBUF_REQ_MSG, + sizeof (nsfw_shmem_mbuf_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_mbuf_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("mbf create name cpy fail] ret=%d", iretval); + goto release; + } + + NSFW_SHMEM_MBUF_DATA_INIT (pdata, 0, n, cache_size, priv_size, + data_room_size, (u16) entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mbf create mem req rsp fail] ret=%u", ucret); + goto release; + } + + tpack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (tpack_head, NSFW_MBUF_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + tpack_data = NSFW_SHMEM_GET_DATA (tpack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, tpack_data->cstate, 0, + tpack_data->usseq, release); + + hhandle = ADDR_SHTOL (tpack_data->pbase_addr); + NSCOMM_LOGDBG ("mbf create] name=%s, handle=%p, seg=%u", name, hhandle, + tpack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some mbuf pools + */ +i32 +nsfw_remote_shmem_mbf_createv (nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *mbpmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_mbuf_req *ptempdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_mbuf_req); + + mbpmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (mbpmsg, lerr, "remote mbf createv msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, lerr, "remote mbf createv rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, mbpmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_mbuf_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MBUF_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_mbuf_req)); + + /*fill msg data */ + itindex = icount - 1; + if (-1 == + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSCOMM_LOGERR ("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT (ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (mbpmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mbf createv mem req rsp fail] ret=%d", ucret); + goto lerr; + } + + /*interrup msg head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_MBUF_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + lerr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, lerr); + phandle_array[isegbase + iindex] = + ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mbf createv] seg=%d, handle=%p", + pack_data->usseq, hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + if (-1 == + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSCOMM_LOGERR ("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT (ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + /*release memory */ + iretval = NSFW_MEM_OK; + goto release; + +lerr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (mbpmsg, prsp_msg); + return iretval; +} + +/* + *create a simpile pool + */ +mring_handle +nsfw_remote_shmem_mpcreate (const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_msg_head *mppack_head = NULL; + nsfw_shmem_ack *mppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote mbf mpcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote mpcreate rspmsg alloc"); + + /*init msg head */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_SPPOOL_REQ_MSG, + sizeof (nsfw_shmem_sppool_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_sppool_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("mp create copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MPOOL_DATA_INIT (pdata, 0, n, elt_size, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mp create rsp fail] ret=%d", ucret); + goto release; + } + + /*get msg head */ + mppack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (mppack_head, NSFW_SPPOOL_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + mppack_data = NSFW_SHMEM_GET_DATA (mppack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, mppack_data->cstate, 0, + mppack_data->usseq, release); + + hhandle = ADDR_SHTOL (mppack_data->pbase_addr); + NSCOMM_LOGDBG ("mpcreate] name=%s, handle=%p, seg=%d", name, hhandle, + mppack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some simpile pools by send a msg + */ +i32 +nsfw_remote_shmem_mpcreatev (nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_sppool_req *ptempdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + /*the max members that a msg can take */ + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_sppool_req); + + /*alloc a msg */ + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (pmsg, mperr, "remote mpcreatev pmsg alloc"); + + /*alloc rsp msg */ + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, mperr, "remote mpcreatev rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_sppool_req); + + do + { + icount++; + ieltnum++; + + /*if the element num reach the bigest, or already send all, just deal */ + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + /*init msg header */ + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_SPPOOL_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_sppool_req)); + + /*fill the msg data */ + itindex = icount - 1; + + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT (ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mpcreatev create fail] ret=%u", ucret); + goto mperr; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_SPPOOL_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + mperr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, mperr); + pringhandle_array[isegbase + iindex] = + ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mpcreatev] seg=%u, handle=%p", pack_data->usseq, + hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT (ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ptempdata++; + } + } + while (icount < inum); + + /*release the memory */ + iretval = NSFW_MEM_OK; + goto release; + +mperr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *create a ring + */ +mring_handle +nsfw_remote_shmem_ringcreate (const char *name, unsigned int n, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_ring_req *pdata = NULL; + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *ppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote ringcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, + "remote ringcreate rspmsg alloc"); + + /*fill msg head */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RING_REQ_MSG, + sizeof (nsfw_shmem_ring_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_ring_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("ring create cpy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MRING_DATA_INIT (pdata, 0, n, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("ring create rsp fail] ret=%d", ucret); + goto release; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RING_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + ppack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, ppack_data->cstate, 0, + ppack_data->usseq, release); + + hhandle = ADDR_SHTOL (ppack_data->pbase_addr); + NSCOMM_LOGDBG ("ring create] name=%s, handle=%p, seg=%u", name, hhandle, + ppack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create a mem pool that the members are rings by send a msg + *ieltnum:the num of ring member + *iringnum:the num of ring in simple mem pook + *entype:the defualt the of ring + */ +i32 +nsfw_remote_shmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + unsigned int useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + /*the num of ring member must be power of 2 */ + unsigned int usnum = common_mem_align32pow2 (ieltnum + 1); + + useltsize = + sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + nhandle = + nsfw_remote_shmem_mpcreate (name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + NSFW_POINT_CHK_RET_ERR (nhandle, "remote ringcreatev msg alloc"); + + n = + nsfw_shmem_ring_sc_dequeuev (nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSCOMM_LOGERR ("ring dequeue fail] ringnum=%d, retnum=%d", iringnum, n); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query (&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init (pringhandle_array[icount], usnum, (void *) baseaddr, + NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +/* + *look up a msg by send a msg + */ +void * +nsfw_remote_shmem_lookup (const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + void *addr = NULL; + /*msg head data define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_lookup_req *pdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *lpack_data = NULL; + u8 ucret = TRUE; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote lookup pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, perr, "remote lookup rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MEM_LOOKUP_REQ_MSG, + sizeof (nsfw_shmem_lookup_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_lookup_req); + if (EOK != STRCPY_S (pdata->aname, sizeof (pdata->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S faild]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mem lookup fail] ret=%u", ucret); + goto release; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_MEM_LOOKUP_ACK_MSG, + sizeof (nsfw_shmem_ack), perr); + + lpack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, lpack_data->cstate, 0, + lpack_data->usseq, perr); + + addr = ADDR_SHTOL (lpack_data->pbase_addr); + NSCOMM_LOGDBG ("shmem lookup] name=%s, handle=%p, seg=%u", name, addr, + lpack_data->usseq); + goto release; +perr: + addr = NULL; + +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return addr; +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h new file mode 100644 index 0000000..60c4115 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h @@ -0,0 +1,51 @@ +/* +* +* 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 _NSFW_RSHMEM_MNG_H +#define _NSFW_RSHMEM_MNG_H + +mzone_handle nsfw_memzone_remote_reserv (const i8 * name, size_t mlen, + i32 socket_id); +i32 nsfw_memzone_remote_reserv_v (nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, + pid_t pid); +i32 nsfw_remote_free (const i8 * name, nsfw_mem_struct_type entype); +mpool_handle nsfw_remote_shmem_mbf_create (const i8 * name, unsigned int n, + unsigned cache_size, + unsigned priv_size, + unsigned data_room_size, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mbf_createv (nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_mpcreate (const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mpcreatev (nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_ringcreate (const char *name, unsigned int n, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, + i32 iringnum, i32 socket_id, + nsfw_mpool_type entype); + +void *nsfw_remote_shmem_lookup (const i8 * name, nsfw_mem_struct_type entype); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c new file mode 100644 index 0000000..e7a11ad --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c @@ -0,0 +1,47 @@ +/* +* +* 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 "nsfw_mem_desc.h" +#include "nsfw_shmem_mng.h" +#include "nsfw_shmem_mdesc.h" + +/*the inferaces accessing memory*/ +nsfw_mem_ops g_shmem_ops = { + nsfw_shmem_init, + nsfw_shmem_destroy, + nsfw_shmem_create, + nsfw_shmem_createv, + nsfw_shmem_lookup, + nsfw_shmem_release, + nsfw_shmem_mbfmpcreate, + nsfw_shmem_mbfmpcreatev, + nsfw_shmem_mbfalloc, + nsfw_shmem_mbffree, + nsfw_shmem_mbfmplookup, + nsfw_shmem_mbfmprelease, + nsfw_shmem_spcreate, + nsfw_shmem_spcreatev, + nswf_shmem_sp_ringcreate, + nsfw_shmem_sprelease, + nsfw_shmem_sp_lookup, + nsfw_shmem_ringcreate, + nsfw_shmem_ring_lookup, + nsfw_shmem_ringrelease, + nsfw_shmem_stactic, + nsfw_shmem_mbuf_recycle, + nsfw_shmem_sp_iterator, + nsfw_shmem_mbuf_iterator +}; diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h new file mode 100644 index 0000000..afd9e29 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* 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 _NSFW_SHMEM_MDESC_H_ +#define _NSFW_SHMEM_MDESC_H_ + +extern nsfw_mem_ops g_shmem_ops; + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c new file mode 100644 index 0000000..f85e70d --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c @@ -0,0 +1,880 @@ +/* +* +* 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 "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_mem_desc.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_mempool.h" +#include "common_mem_memzone.h" +#include "common_mem_buf.h" +#include "common_mem_mbuf.h" +#include "nsfw_rshmem_mng.h" +#include "common_mem_api.h" +#include "common_sys_config.h" +#include "nsfw_maintain_api.h" +#include "common_pal_bitwide_adjust.h" + +#include "common_mem_pal.h" + +#include "common_func.h" + +#define NSFW_SHMEM_PID (get_sys_pid()) +#define NSFW_SHMEM_FLAG (g_shmem_localdata->enflag) + +nsfw_mem_localdata *g_shmem_localdata = NULL; + +/*check g_mem_localdata*/ +#define NSFW_INIT_CHK_RET() \ + if (!g_shmem_localdata) \ + { \ + return NSFW_MEM_ERR; \ + } + +#define NSFW_INIT_CHK_RET_NULL() \ + if (!g_shmem_localdata) \ + { \ + return NULL; \ + } + +/* + *share memory mng module init + * + */ +i32 +nsfw_shmem_init (nsfw_mem_para * para) +{ + common_mem_pal_module_info rteinfo = { 0 }; + i32 iret = NSFW_MEM_ERR; + int flag = 0; + if (!para) + { + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("nsfw shmem init begin"); + + if (NSFW_PROC_MASTER == para->enflag) + { + iret = common_mem_pal_init (para->iargsnum, para->pargs); + } + else if (NSFW_PROC_MAIN == para->enflag) + { + iret = common_pal_module_init (NULL); + } + else + { + LCORE_MASK_SET (rteinfo.ilcoremask, 1); + rteinfo.ucproctype = DMM_PROC_T_SECONDARY; + iret = common_pal_module_init (&rteinfo); + } + + if (NSFW_MEM_OK != iret) + { + NSCOMM_LOGERR ("rte init fail] ret=0x%x", iret); + return NSFW_MEM_ERR; + } + + flag = dmm_pal_addr_align (); + if ((0 == flag) && (NSFW_PROC_MAIN == para->enflag)) + { + dmm_addr_print (); + NSCOMM_LOGERR + ("rte init addr is not the same with primary] nstackmain flag=%d", + flag); + return NSFW_MEM_ERR; + } + + g_shmem_localdata = + (nsfw_mem_localdata *) malloc (sizeof (nsfw_mem_localdata)); + + if (NULL == g_shmem_localdata) + { + NSCOMM_LOGERR ("g_shmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + MEMSET_S (g_shmem_localdata, sizeof (nsfw_mem_localdata), 0, + sizeof (nsfw_mem_localdata)); + if (EOK != iret) + { + NSCOMM_LOGERR ("memset fail] g_shmem_localdata=%p ", g_shmem_localdata); + free (g_shmem_localdata); + g_shmem_localdata = NULL; + return NSFW_MEM_ERR; + } + + g_shmem_localdata->enflag = para->enflag; + + NSCOMM_LOGINF ("nsfw shmem init end] enflag=%d", para->enflag); + return NSFW_MEM_OK; + +} + +/* + *module destroy + */ +void +nsfw_shmem_destroy (void) +{ + if (g_shmem_localdata) + { + free (g_shmem_localdata); + g_shmem_localdata = NULL; + } + + return; +} + +/* + * create a shared memory + * nsfw_mem_zone::stname memory name + * nsfw_mem_zone::isize + */ +mzone_handle +nsfw_shmem_create (nsfw_mem_zone * pinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL ()if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_reserve_name (pinfo->stname.aname, + pinfo->lenth, + pinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pinfo->stname.aname, "shmem create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + return NULL; + } + } + + return nsfw_memzone_remote_reserv ((char *) &aname[0], pinfo->lenth, + SOCKET_ID_ANY); +} + +/* + *create some memory + *inum must be equal iarray_num + */ +i32 +nsfw_shmem_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_memzone_remote_reserv_v (pmeminfo, paddr_array, iarray_num, + 0); + } + else + { + return nsfw_memzone_remote_reserv_v (pmeminfo, paddr_array, iarray_num, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +mzone_handle +nsfw_shmem_lookup (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_lookup_name (pname->aname); + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + int retVal = + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NULL; + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "shmem lookup") + int retVal = + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", pname->aname, + NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NULL; + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_MZONE); +} + +i32 +nsfw_shmem_release (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + const struct common_mem_memzone *pmzone = NULL; + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + pmzone = common_mem_memzone_lookup (pname->aname); + + if (pmzone) + { + common_mem_memzone_free (pmzone); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET (pname->aname, "shmem free") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NSFW_MEM_ERR; + } + } + + return nsfw_remote_free (aname, NSFW_MEM_MZONE); +} + +mpool_handle +nsfw_shmem_mbfmpcreate (nsfw_mem_mbfpool * pbufinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_pktmbuf_pool_create (pbufinfo->stname.aname, + pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, + pbufinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pbufinfo->stname.aname, "mbufpool create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pbufinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_mbf_create (aname, pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, SOCKET_ID_ANY, + pbufinfo->enmptype); +} + +/* + *create some mbuf pools + */ +i32 +nsfw_shmem_mbfmpcreatev (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mbf_createv (pmbfname, phandle_array, + iarray_num, 0); + } + else + { + return nsfw_remote_shmem_mbf_createv (pmbfname, phandle_array, + iarray_num, NSFW_SHMEM_PID); + } + + return NSFW_MEM_ERR; +} + +mbuf_handle +nsfw_shmem_mbfalloc (mpool_handle mhandle) +{ + return (mbuf_handle) common_mem_pktmbuf_alloc ((struct common_mem_mempool *) + mhandle); +} + +i32 +nsfw_shmem_mbffree (mbuf_handle mhandle) +{ + common_mem_pktmbuf_free ((struct common_mem_mbuf *) mhandle); + return NSFW_MEM_OK; +} + +i32 +nsfw_shmem_mbfmprelease (nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +mpool_handle +nsfw_shmem_mbfmplookup (nsfw_mem_name * pmbfname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_mempool_lookup (pmbfname->aname); + } + + if ((NSFW_PROC_NULL == pmbfname->enowner) + || (NSFW_PROC_MAIN == pmbfname->enowner)) + { + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", + pmbfname->aname)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pmbfname->aname, "shmem lookup") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmbfname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_MBUF); +} + +mring_handle +nsfw_shmem_spcreate (nsfw_mem_sppool * pmpinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_pool_create (pmpinfo->stname.aname, pmpinfo->usnum, + pmpinfo->useltsize, pmpinfo->isocket_id, + pmpinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL (pmpinfo->stname.aname, "mpool create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmpinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_mpcreate (aname, pmpinfo->usnum, + pmpinfo->useltsize, SOCKET_ID_ANY, + pmpinfo->enmptype); +} + +i32 +nsfw_shmem_spcreatev (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mpcreatev (pmpinfo, pringhandle_array, inum, + 0); + } + else + { + return nsfw_remote_shmem_mpcreatev (pmpinfo, pringhandle_array, inum, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +i32 +nsfw_lshmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + i32 useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + i32 usnum = common_mem_align32pow2 (ieltnum + 1); + + useltsize = + sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + nhandle = + nsfw_shmem_pool_create (name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + if (NULL == (nhandle)) + { + return NSFW_MEM_ERR; + } + + n = + nsfw_shmem_ring_sc_dequeuev (nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSCOMM_LOGERR + ("ring dequeuev failed] ring=%p, dequeue num=%d, expect num=%d", + nhandle, n, iringnum); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query (&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init (pringhandle_array[icount], usnum, (void *) baseaddr, + NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +i32 +nswf_shmem_sp_ringcreate (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_lshmem_ringcreatev (prpoolinfo->stname.aname, + prpoolinfo->usnum, pringhandle_array, + iringnum, SOCKET_ID_ANY, + prpoolinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET (prpoolinfo->stname.aname, "ring pool") + int retVal = SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + prpoolinfo->stname.aname, NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_ringcreatev (aname, prpoolinfo->usnum, + pringhandle_array, iringnum, + SOCKET_ID_ANY, prpoolinfo->enmptype); +} + +i32 +nsfw_shmem_sprelease (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name (pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + nsfw_shmem_pool_free (ring_ptr); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET (pname->aname, "shmem free") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_free (aname, NSFW_MEM_SPOOL); +} + +mring_handle +nsfw_shmem_sp_lookup (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name (pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + return ring_ptr; + } + return mz_mem; + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + else + { + /*app's name can not over NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "shmem lookup") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_SPOOL); +} + +mring_handle +nsfw_shmem_ringcreate (nsfw_mem_mring * pringinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_ring_create (pringinfo->stname.aname, + pringinfo->usnum, pringinfo->isocket_id, + pringinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL (pringinfo->stname.aname, "ring create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pringinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_ringcreate (aname, pringinfo->usnum, SOCKET_ID_ANY, + pringinfo->enmptype); +} + +mring_handle +nsfw_shmem_ring_lookup (nsfw_mem_name * pname) +{ + return nsfw_shmem_lookup (pname); +} + +i32 +nsfw_shmem_ringrelease (nsfw_mem_name * pname) +{ + return nsfw_shmem_release (pname); +} + +size_t +nsfw_shmem_mbufpool_statics (mpool_handle mbufpool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) mbufpool; + return (size_t) mp->size * (mp->header_size + mp->elt_size + + mp->trailer_size) + + (size_t) mp->private_data_size + + (size_t) + common_mem_ring_get_memsize (common_mem_align32pow2 (mp->size + 1)); +} + +size_t +nsfw_shmem_sppool_statics (mring_handle sppool) +{ + struct nsfw_shmem_ring_head *temp = NULL; + size_t lent = 0; + temp = + (struct nsfw_shmem_ring_head *) ((char *) sppool - + sizeof (struct nsfw_shmem_ring_head)); + + while (temp) + { + lent += temp->mem_zone->len; + temp = temp->next; + } + + return lent; +} + +size_t +nsfw_shmem_ring_statics (mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof (union RingData_U) + + sizeof (struct nsfw_mem_ring); +} + +ssize_t +nsfw_shmem_stactic (void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return nsfw_shmem_mbufpool_statics (handle); + case NSFW_MEM_SPOOL: + return nsfw_shmem_sppool_statics (handle); + case NSFW_MEM_RING: + return nsfw_shmem_ring_statics (handle); + default: + break; + } + return -1; +} + +i32 +nsfw_shmem_mbuf_recycle (mpool_handle handle) +{ +#if 0 + const struct common_mem_mempool *mp = (struct common_mem_mempool *) handle; + struct common_mem_ring *rteRing = NULL; + struct common_mem_mbuf *m_buf = NULL; + uint32_t item; + u32_t *recycle_flg; + uint32_t size = mp->size; + uint32_t threadsize = (size >> 2) * 3; + rteRing = (struct common_mem_ring *) ADDR_SHTOL (mp->ring); + + if (rteRing->prod.tail - rteRing->cons.head < threadsize) + { + for (item = 0; item < size - 1; item++) + { + m_buf = (struct common_mem_mbuf *) ADDR_SHTOL (mp->elt_va_start + item * (mp->header_size + mp->elt_size + mp->trailer_size) + mp->header_size); /*lint !e647 */ + recycle_flg = + (uint32_t *) ((char *) (ADDR_SHTOL (m_buf->buf_addr_align)) + + RTE_PKTMBUF_HEADROOM - sizeof (uint32_t)); + + if (m_buf->refcnt > 0 && *recycle_flg == MBUF_HLD_BY_APP) + { + NSCOMM_LOGINF ("free mbuf hold by app]ring=%p, mbuf=%p", handle, + m_buf); + *recycle_flg = MBUF_UNUSED; + common_mem_pktmbuf_free (m_buf); + } + } + } + + NSCOMM_LOGINF ("To recycle app_tx_pool now]ring=%p,prod.head=%u," + "prod.tail=%u,cons.head=%u,cons.tail=%u.", handle, + rteRing->prod.head, rteRing->prod.tail, + rteRing->cons.head, rteRing->cons.tail); + + /*we Must check and recorrect the Queue if Queue is not correct + 1.if proc.head != proc.tail set proc.head to proc.tail [may lost some buf,but the queue still can use] + App May not putIn Data , just done head++, we can't set proc.tail to proc.head. + 2.if cons.head != cons.tail set cons.tail to cons.head [may lost some buf,but the queue still can use] + App May alread finish deque,just not tail++, we can't set cons.head to cons.tail. + */ + if ((rteRing->prod.head != rteRing->prod.tail) + || (rteRing->cons.head != rteRing->cons.tail)) + { + rteRing->prod.head = rteRing->prod.tail; + rteRing->cons.tail = rteRing->cons.head; + } +#endif + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_shmem_sp_iterator +* Description : sp pool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_shmem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + struct nsfw_mem_ring *perfring_ptr = (struct nsfw_mem_ring *) handle; + if (NULL == perfring_ptr || NULL == fun) + { + return 0; + } + + if (0 == perfring_ptr->eltsize) + { + return 0; + } + + int num = perfring_ptr->size; + if (start >= (u32) num || end <= start) + { + return 0; + } + + struct nsfw_shmem_ring_head *ring_head = + (struct nsfw_shmem_ring_head *) ((char *) handle - + sizeof (struct nsfw_shmem_ring_head)); + void *mz = + (void *) ((char *) perfring_ptr + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)); + + if (ring_head->mem_zone->len < + sizeof (struct nsfw_shmem_ring_head) + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)) + { + return 0; + } + + u32 mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head) - + sizeof (struct nsfw_mem_ring) - num * sizeof (union RingData_U); + + u32 start_idx = 0; + u32 elm_num = 0; + elm_num = mz_len / perfring_ptr->eltsize; + while (start > start_idx + elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + return 0; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next->mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = + (void *) ((char *) ring_head + sizeof (struct nsfw_shmem_ring_head)); + start_idx += elm_num; + } + + u32 cur_idx = start - start_idx; + char *cur_elm = NULL; + int proc_count = 0; + while (cur_idx + start_idx < end && cur_idx + start_idx < (u32) num) + { + if (cur_idx >= elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + break; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next-> + mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = + (void *) ((char *) ring_head + + sizeof (struct nsfw_shmem_ring_head)); + start_idx += elm_num; + + cur_idx = 0; + cur_elm = NULL; + continue; + } + + if (NULL == cur_elm) + { + cur_elm = ((char *) mz + cur_idx * perfring_ptr->eltsize); + } + else + { + cur_elm += perfring_ptr->eltsize; + } + + cur_idx++; + proc_count++; + (void) fun (cur_elm, argv); + } + + return proc_count; +} + +i32 +nsfw_shmem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + return dmm_pktmbuf_pool_iterator ((struct common_mem_mempool *) handle, + start, end, (dmm_mbuf_item_fun) fun, + argv); +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h new file mode 100644 index 0000000..f81b34a --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h @@ -0,0 +1,133 @@ +/* +* +* 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 _NSFW_SHMEM_MNG_H +#define _NSFW_SHMEM_MNG_H + +/* + * mem mgr module init + * para:point to nstak_fwmem_para + */ +i32 nsfw_shmem_init (nsfw_mem_para * para); + +/* + * mem mgr module destory + * + */ +void nsfw_shmem_destroy (void); + +/* + * create a block memory with name + * fw_mem_zone::stname name of memory + * fw_mem_zone::isize memory size + */ +mzone_handle nsfw_shmem_create (nsfw_mem_zone * pinfo); + +/* + *create some blocks memeory + */ +i32 nsfw_shmem_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + +/* + *lookup a memory + */ +mzone_handle nsfw_shmem_lookup (nsfw_mem_name * pname); + +/*release the memory*/ +i32 nsfw_shmem_release (nsfw_mem_name * pname); + +/* + *create mbuf pool + */ +mpool_handle nsfw_shmem_mbfmpcreate (nsfw_mem_mbfpool * pbufinfo); + +/* + *create some mbuf pool + */ +i32 nsfw_shmem_mbfmpcreatev (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num); + +/* + *alloc a mbuf from mbuf pool + */ +mbuf_handle nsfw_shmem_mbfalloc (mpool_handle mhandle); + +/* + *release a mbuf pool + */ +i32 nsfw_shmem_mbffree (mbuf_handle mhandle); + +/* + *put mbuf backto mbuf pool + */ +i32 nsfw_shmem_mbfmprelease (nsfw_mem_name * pname); + +/*look up mbuf mpool*/ +mpool_handle nsfw_shmem_mbfmplookup (nsfw_mem_name * pmbfname); + +/* + *create simple pool + */ +mring_handle nsfw_shmem_spcreate (nsfw_mem_sppool * pmpinfo); + +/* + *create some simple pools + */ +i32 nsfw_shmem_spcreatev (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num); + +/* + *create a simple pool that members are rings + */ +i32 nswf_shmem_sp_ringcreate (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum); + +/* + *release a simple pool + */ +i32 nsfw_shmem_sprelease (nsfw_mem_name * pname); + +/* + *look up a simple pool + */ +mring_handle nsfw_shmem_sp_lookup (nsfw_mem_name * pname); + +/* + *create a ring with name + */ +mring_handle nsfw_shmem_ringcreate (nsfw_mem_mring * pringinfo); + +/* + *look up a ring with name + */ +mring_handle nsfw_shmem_ring_lookup (nsfw_mem_name * pname); + +/* + *release ring + */ +i32 nsfw_shmem_ringrelease (nsfw_mem_name * pname); + +ssize_t nsfw_shmem_stactic (void *handle, nsfw_mem_struct_type type); + +i32 nsfw_shmem_mbuf_recycle (mpool_handle handle); + +i32 nsfw_shmem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +i32 nsfw_shmem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c new file mode 100644 index 0000000..af46e18 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c @@ -0,0 +1,839 @@ +/* +* +* 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 +#include + +#include "common_mem_pal.h" +#include "common_mem_pal_memconfig.h" +#include "nstack_securec.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_mem_buf.h" +#include "common_func.h" + +void +nsfw_shmem_ring_baseaddr_query (uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr) +{ + struct common_mem_mem_config *pMemCfg = + common_mem_pal_get_configuration ()->mem_config; + struct common_mem_memseg *PMemSegArry = pMemCfg->memseg; + + *rte_lowest_addr = PMemSegArry[0].addr_64; + *rte_highest_addr = PMemSegArry[0].addr_64 + PMemSegArry[0].len; + + int s = 1; + + while (s < COMMON_MEM_MAX_MEMSEG && PMemSegArry[s].len > 0) + { + if (*rte_lowest_addr > PMemSegArry[s].addr_64) + { + *rte_lowest_addr = PMemSegArry[s].addr_64; + } + + if (*rte_highest_addr < PMemSegArry[s].addr_64 + PMemSegArry[s].len) + { + *rte_highest_addr = PMemSegArry[s].addr_64 + PMemSegArry[s].len; + } + + s++; + } + +} + +static unsigned +nsfw_shmem_pool_node_alloc (struct nsfw_mem_ring *perfring_ptr, + unsigned alloc_index, unsigned max_index, + void *mz, size_t mz_len, unsigned elt_size) +{ + size_t alloc_size = 0; + unsigned offset_idx = 0; + NSTCP_LOGINF ("mz(%p), mz_len = 0x%x", mz, mz_len); + + while (alloc_size + elt_size <= mz_len) + { + perfring_ptr->ring[alloc_index + offset_idx].data_s.ver = + alloc_index + offset_idx; + perfring_ptr->ring[alloc_index + offset_idx].data_s.val = + ADDR_LTOSH_EXT (mz) - ((uint64_t) perfring_ptr->Addrbase); + mz = (char *) mz + elt_size; + alloc_size += elt_size; + offset_idx++; + + if (alloc_index + offset_idx == max_index) + { + break; + } + } + + return offset_idx; +} + +void +nsfw_shmem_pool_free (struct nsfw_mem_ring *perfring_ptr) +{ + struct nsfw_shmem_ring_head *ptemp; + + if (NULL == perfring_ptr) + { + return; + } + + struct nsfw_shmem_ring_head *pnode = + (struct nsfw_shmem_ring_head *) ((char *) perfring_ptr - + sizeof (struct nsfw_shmem_ring_head)); + + while (pnode) + { + // phead is involved in phead->mem_zone + ptemp = pnode->next; + common_mem_memzone_free (pnode->mem_zone); + pnode = ptemp; + } +} + +struct nsfw_mem_ring * +nsfw_shmem_pool_create (const char *name, unsigned int n, + unsigned int elt_size, int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr = NULL; + struct common_mem_memzone *mz_mem; + void *mz = NULL; + + /*get pool size, pool size must pow of 2 */ + unsigned int num = common_mem_align32pow2 (n + 1); + + struct nsfw_shmem_ring_head *pcur = NULL; + /*calculat the empty rte_perf_ring Size */ + size_t len = + sizeof (struct nsfw_shmem_ring_head) + sizeof (struct nsfw_mem_ring) + + (size_t) num * sizeof (union RingData_U) + (size_t) num * elt_size; + size_t alloc_len = len; + unsigned int alloc_num = 0; + unsigned int alloc_index = 0; + + size_t mz_len = 0; + + unsigned int mz_index = 1; + char mz_name[128] = { 0 }; + int retVal; + /*we'd better use `strlen(src)` or `sizeof(dst)` to explain copying length of src string. + it's meaningless using `sizeof(dst) - 1` to reserve 1 byte for '\0'. + if copying length equals to or bigger than dst length, just let STRNCPY_S() returns failure. */ + retVal = STRNCPY_S (mz_name, sizeof (mz_name), name, sizeof (mz_name)); + + if (EOK != retVal) + { + NSTCP_LOGERR ("STRNCPY_S failed]ret=%d", retVal); + return NULL; + } + + mz_mem = common_memzone_data_lookup_name (name); + NSTCP_LOGINF ("memzone data look up] n=%u,num=%u,len=%zu", n, num, len); + + if (mz_mem) + { + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + return perfring_ptr; + } + + while (alloc_len > 0) + { + if (NULL != perfring_ptr) + { + retVal = + SPRINTF_S (mz_name, sizeof (mz_name), "%s_%03d", name, mz_index); + + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + } + + mz_mem = + (struct common_mem_memzone *) common_mem_memzone_reserve (mz_name, + alloc_len, + socket_id, + 0); + + if (mz_mem == NULL) + { + mz_mem = + (struct common_mem_memzone *) common_mem_memzone_reserve (mz_name, + 0, + socket_id, + 0); + } + + if (mz_mem == NULL) + { + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + + if (NULL == perfring_ptr + && (mz_mem->len < + sizeof (struct nsfw_shmem_ring_head) + + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U))) + { + common_mem_memzone_free (mz_mem); + return NULL; + } + + if (NULL == perfring_ptr) + { + pcur = (struct nsfw_shmem_ring_head *) ADDR_SHTOL (mz_mem->addr_64); + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) pcur + + sizeof (struct nsfw_shmem_ring_head)); + + mz = + (void *) ((char *) perfring_ptr + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)); + mz_len = + mz_mem->len - sizeof (struct nsfw_shmem_ring_head) - + sizeof (struct nsfw_mem_ring) - num * sizeof (union RingData_U); + + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + nsfw_shmem_ring_baseaddr_query (&rte_base_addr, &rte_highest_addr); + nsfw_mem_pool_head_init (perfring_ptr, num, elt_size, + (void *) rte_base_addr, NSFW_SHMEM, + (nsfw_mpool_type) flag); + } + else + { + if (pcur) + { + pcur->next = + (struct nsfw_shmem_ring_head *) ADDR_SHTOL (mz_mem->addr_64); + pcur = pcur->next; + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + if (mz_mem->len < sizeof (struct nsfw_shmem_ring_head)) + { + NSCOMM_LOGERR ("mz_len error %d", mz_mem->len); + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + + mz = + (void *) ((char *) pcur + + sizeof (struct nsfw_shmem_ring_head)); + mz_len = mz_mem->len - sizeof (struct nsfw_shmem_ring_head); + } + } + + alloc_num = + nsfw_shmem_pool_node_alloc (perfring_ptr, alloc_index, num, mz, + mz_len, elt_size); + alloc_index += alloc_num; + + if (alloc_index >= num) + { + break; + } + + // second time allocate should not containd all ring head + alloc_len = + (size_t) (num - alloc_index) * elt_size + + sizeof (struct nsfw_shmem_ring_head); + mz_index++; + } + + return perfring_ptr; +} + +/*ring create*/ +struct nsfw_mem_ring * +nsfw_shmem_ring_create (const char *name, unsigned int n, int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr; + struct common_mem_memzone *mz; + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + + unsigned int num = common_mem_align32pow2 (n); + + mz = + (struct common_mem_memzone *) common_mem_memzone_reserve (name, + sizeof (struct + nsfw_mem_ring) + + + num * + sizeof (union + RingData_U), + socket_id, 0); + + if (mz == NULL) + { + return NULL; + } + + perfring_ptr = mz->addr; + + nsfw_shmem_ring_baseaddr_query (&rte_base_addr, &rte_highest_addr); + nsfw_mem_ring_init (perfring_ptr, num, (void *) rte_base_addr, NSFW_SHMEM, + flag); + + return perfring_ptr; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int +nsfw_shmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U expectPostVal; + union RingData_U curVal; + unsigned int tmpHead; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int size = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + /*do box range check */ + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + /*invalid addr of box, can't put in rte_perf_ring, maybe should set a errno here */ + return -1; + } + + do + { + /* + if the ring is Full return directly; this not a exact check, cause we made tail++ after dequeue success. + the thing we could make sure is ring[ring->Tail&mask] already dequeue + */ + tmpTail = ring->cons.tail; + + if (tmpTail + size - CurHead == 0) + { + /* + here we give enque a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + + /* + the old version of ring->ring[CurHead&mask] must CurHead - size, which enqueue set to this pos lasttime + & the val must already dequeue. otherwise this pos can't enqueue; + */ + expectPostVal.data_l = + (((unsigned long long) (CurHead - size)) << VALUE_LEN); + + /* + the new version of ring->ring[CurHead&mask] must CurHead, which enqueue set to this pos this time. + */ + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + if (ring->ring[CurHead & mask].data_s.ver == expectPostVal.data_s.ver + && __sync_bool_compare_and_swap (&ring->ring[CurHead & mask].data_l, + expectPostVal.data_l, + curVal.data_l)) + { + /* + enqueue success, add Head Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Head, 1) to assume that, if one process enque sucess && been killed before + add Head, other process can recorrect the Head Value; + one more thing the direction of Tail must been add-direction, so we using the condition (ring->Head - CurHead >0x80000000); + while many thread do enque at same time, Head may not correct,exp: + thread A get old head 10, thread A want set head to 11 + thread B get old head 10, thread B want set head to 12 + thread A do CAS && thread B do CAS at same time, thread A do CAS success; + the result of head is 11, but the correct Value should be 12; + + then thread C get old head 11, thread C will set head to 13[cause pos 12 already has value, thread C will skill 12], + the head will be recorrect by thread C. + if no thread C, thread A& B are the last enque thread; the head must recorrect by the deque function. + */ + tmpHead = ring->prod.head; + + if (0 == (CurHead & 0x03) && tmpHead - CurHead > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + CurHead + 1); + } + + break; + } + + /* + CurHead++ here; + may be cpu slice is end here; while re-sched CurHead < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurHead++ instead CurHead++ directly. + if using CurHead++ will amplify the probability of ABA problem + */ + /*CurHead++; */ + tmpHead = ring->prod.head; + CurHead = CurHead - tmpHead < mask - 1 ? CurHead + 1 : tmpHead; + } + while (1); + + return 1; +} + +/* + this is a single thread/process enqueue function + */ +int +nsfw_shmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U texpectPostVal; + union RingData_U curVal; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int uisize = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + return -1; + } + + do + { + tmpTail = ring->cons.tail; + if (tmpTail + uisize - CurHead == 0) + { + /* + *here we give enque a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + texpectPostVal.data_l = + (((unsigned long long) (CurHead - uisize)) << VALUE_LEN); + + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + + if (ring->ring[CurHead & mask].data_l == texpectPostVal.data_l) + { + ring->ring[CurHead & mask].data_l = curVal.data_l; + ring->prod.head = CurHead + 1; + break; + } + + CurHead++; + } + while (1); + return 1; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +*/ +int +nsfw_shmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + + CurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap (&ring->ring[CurTail & mask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + *box = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue sucess && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + while multi CAS done the result value of CurTail may not correct, but we don't care, it will be recorrect while next deque done. + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (CurTail & 0x03) && tmpTail - CurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + CurTail + 1); + } + break; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + CurTail = CurTail - tmpTail < mask - 1 ? CurTail + 1 : tmpTail; + } + while (1); + + return 1; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_shmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int uiCurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int uimask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int deqNum = 0; + uiCurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (uiCurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (deqNum == 0 && ring->ring[tmpHead & uimask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return deqNum; + } + } + + curNullVal.data_l = (((unsigned long long) uiCurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[uiCurTail & uimask]; + + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap (&ring-> + ring[uiCurTail & uimask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + box[deqNum] = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue sucess && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (uiCurTail & 0x03) && tmpTail - uiCurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + uiCurTail + 1); + } + + deqNum++; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + uiCurTail = uiCurTail - tmpTail < uimask - 1 ? uiCurTail + 1 : tmpTail; + + } + while (n > deqNum); + + return deqNum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_shmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int uitmpHead; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + uitmpHead = ring->prod.head; + if (CurTail == uitmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[uitmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, + uitmpHead, uitmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + *box = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + break; + } + + CurTail++; + } + while (1); + + return 1; +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_shmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int CurTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int usdeqNum = 0; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (usdeqNum == 0 && ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return usdeqNum; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + /* + the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + box[usdeqNum] = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + usdeqNum++; + } + + CurTail++; + } + while (n > usdeqNum); + + return usdeqNum; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + void *prmBox = NULL; + + /*if queue is full, just return 0 */ + if (ring->prod.head >= (ring->size + ring->cons.tail)) + { + return 0; + } + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + head = ring->prod.head; + ring->prod.head = head + 1; + ring->ring[head & ring->mask].data_s.ver = head; + ring->ring[head & ring->mask].data_s.val = + (char *) prmBox - (char *) ring->Addrbase; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + u32 tail = 0; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return 0; + } + + tail = ring->cons.tail; + *box = + ADDR_SHTOL ((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + ring->cons.tail++; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return num; + } + + ring->cons.tail = tail + 1; + + box[num] = + ADDR_SHTOL ((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + num++; + } + + return num; +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h new file mode 100644 index 0000000..15cd1dd --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h @@ -0,0 +1,60 @@ +/* +* +* 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 _NSFW_SHMEM_RING_H_ +#define _NSFW_SHMEM_RING_H_ + +#include + +#include "common_func.h" + +struct nsfw_shmem_ring_head +{ + struct common_mem_memzone *mem_zone; + struct nsfw_shmem_ring_head *next; + unsigned int uireserv[4]; +}; + +void nsfw_shmem_ring_baseaddr_query (uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr); +struct nsfw_mem_ring *nsfw_shmem_pool_create (const char *name, + unsigned int n, + unsigned int elt_size, + int socket_id, + unsigned char flag); +struct nsfw_mem_ring *nsfw_shmem_ring_create (const char *name, + unsigned int n, int socket_id, + unsigned char flag); + +void nsfw_shmem_pool_free (struct nsfw_mem_ring *perfring_ptr); + +void nsfw_shmem_ring_reset (struct nsfw_mem_ring *ring, unsigned char flag); +int nsfw_shmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, + void *box); +int nsfw_shmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, + void **box); +int nsfw_shmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_SHMEM_RING_H_*/ -- cgit 1.2.3-korg