diff options
Diffstat (limited to 'stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c')
-rw-r--r-- | stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c new file mode 100644 index 0000000..a3c7f60 --- /dev/null +++ b/stacks/lwip_stack/src/mem/nsfw_nshmem/nsfw_nshmem_mng.c @@ -0,0 +1,529 @@ +/* +* +* 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 <stdlib.h> +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_mem_api.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)) \ + { \ + NSRTP_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)) \ + { \ + NSRTP_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)) + { + NSRTP_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) + { + NSRTP_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; + NSRTP_LOGINF("nsfw nshmem init begin"); + g_nshmem_localdata = + (nsfw_mem_localdata *) malloc(sizeof(nsfw_mem_localdata)); + + if (NULL == g_nshmem_localdata) + { + NSRTP_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) + { + NSRTP_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) + { + NSRTP_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) + { + NSRTP_LOGERR("nshmem init g_nshmem_internal_cfg MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_localdata->enflag = para->enflag; + NSRTP_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 length +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle nsfw_nshmem_reserv_safe(const char *name, size_t length) +{ + void *addr = NULL; + i32 iret = NSFW_MEM_OK; + nsfw_nshmem_mzone *pmemzone = NULL; + + if (length <= 0) + { + return NULL; + } + + nsfw_write_lock(nsfw_get_glb_lock()); + + addr = malloc(length); + if (!addr) + { + NSRTP_LOGERR("nshmem malloc addr fail] addr=%p", addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + iret = memset_s(addr, length, 0, length); + if (EOK != iret) + { + NSRTP_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) + { + NSRTP_LOGERR("nshmem get free zone fail"); + free(addr); + nsfw_write_unlock(nsfw_get_glb_lock()); + return NULL; + } + + pmemzone->addr = addr; + pmemzone->length = length; + /*name must be less than NSFW_MEM_APPNAME_LENGTH */ + if (EOK != + strcpy_s((char *) pmemzone->aname, sizeof(pmemzone->aname), name)) + { + NSRTP_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) + { + NSRTP_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)) + { + NSRTP_LOGERR("nsfw_nshmem_ringenqueue enqueue 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) + { + NSRTP_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_static +* 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_static(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; +} |