summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/src/mem/nsfw_shmem
diff options
context:
space:
mode:
authorsharath reddy <bs.reddy@huawei.com>2019-06-04 11:53:49 +0530
committersharath reddy <bs.reddy@huawei.com>2019-06-04 20:38:30 +0530
commit2a42ad20b9730706ad371ae3787d4597c4e42276 (patch)
treefa01cd312586ea007468e7233f94c0ce53d75873 /stacks/lwip_stack/src/mem/nsfw_shmem
parenta826fe833d3f2a8fe2673fa05811fe1a22baf045 (diff)
Feature: 19.04 part-2DMM-2
Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9 Signed-off-by: sharath reddy <bs.reddy@huawei.com>
Diffstat (limited to 'stacks/lwip_stack/src/mem/nsfw_shmem')
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c989
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h51
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c48
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h22
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c800
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h135
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c843
-rw-r--r--stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h60
8 files changed, 2948 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c
new file mode 100644
index 0000000..9016282
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.c
@@ -0,0 +1,989 @@
+/*
+*
+* 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 <stdint.h>
+#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"
+#include "common_pal_bitwide_adjust.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)) \
+ { \
+ NSRTP_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)) \
+ { \
+ NSRTP_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)) \
+ { \
+ NSRTP_LOGERR("point check fail] desc_para=%s", desc); \
+ goto gotoflag; \
+ }
+
+/*init the msg head*/
+#define NSFW_SHMEM_MSG_HEAD_INIT(pmsg, type, length) { \
+ (pmsg)->usmsg_type = (type); \
+ (pmsg)->uslenth = (length); \
+ }
+
+/*rsp msg head check, and if err goto*/
+#define NSFW_SHMEM_MSGHEAD_CHK_GOTO(pmsg, type, length, gotoflag) { \
+ if (((type) != pmsg->usmsg_type) && ((length) != pmsg->uslenth)) \
+ { \
+ NSRTP_LOGERR("check fail] msgtype=%d, type_para=%d, len=%d", (pmsg->usmsg_type), (type), (length)); \
+ goto gotoflag; \
+ } \
+ }
+
+/*rsp check the state*/
+#define NSFW_SHMEM_ACKSTATE_CHK_GOTO(expret, ret, expseg, seg, gotoflag) { \
+ if (((ret) != (expret)) || ((expseg) != (seg))) \
+ { \
+ NSRTP_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, slength, seg, socketid) { \
+ (pdata)->isocket_id = (socketid); \
+ (pdata)->lenth = (slength); \
+ (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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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);
+ NSRTP_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 memories 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)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]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)
+ {
+ NSRTP_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);
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]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))
+ {
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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);
+ NSRTP_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))
+ {
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("mbf createv mem req rsp fail] ret=%d", ucret);
+ goto lerr;
+ }
+
+ /*interrupt 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);
+ NSRTP_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))
+ {
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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);
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("mpcreatev create fail] ret=%u", ucret);
+ goto mperr;
+ }
+
+ /*interrupt 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);
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("ring create rsp fail] ret=%d", ucret);
+ goto release;
+ }
+
+ /*interrupt 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);
+ NSRTP_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 pool
+ *entype:the default 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)
+ {
+ NSRTP_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))
+ {
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("mem lookup fail] ret=%u", ucret);
+ goto release;
+ }
+
+ /*interrupt 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);
+ NSRTP_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/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_rshmem_mng.h
new file mode 100644
index 0000000..0ae5cd5
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/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/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c
new file mode 100644
index 0000000..3d4dd42
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.c
@@ -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.
+*/
+
+#include "nsfw_mem_api.h"
+#include "nsfw_shmem_mng.h"
+#include "nsfw_shmem_mdesc.h"
+#include "common_pal_bitwide_adjust.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_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_static,
+ nsfw_shmem_sp_iterator,
+ nsfw_shmem_mbuf_iterator,
+ NULL,
+ shmem_shddr_to_laddr,
+ shmem_laddr_to_shddr,
+ nsfw_attach_core_id
+};
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mdesc.h
new file mode 100644
index 0000000..afd9e29
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/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/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c
new file mode 100644
index 0000000..1066b9a
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.c
@@ -0,0 +1,800 @@
+/*
+*
+* 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_api.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_func.h"
+
+#define NSFW_SHMEM_PID (get_sys_pid())
+#define NSFW_SHMEM_FLAG (g_shmem_localdata->enflag)
+
+/* app_mode 1: simple stack with APP*/
+extern u8 app_mode;
+u8 app_mode = 0;
+
+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;
+ }
+
+ NSRTP_LOGINF("nsfw shmem init begin");
+
+ LCORE_MASK_SET(rteinfo.ilcoremask, 1);
+ rteinfo.ucproctype = DMM_PROC_T_SECONDARY;
+ iret = common_pal_module_init(para, &rteinfo, app_mode);
+
+ if (DMM_MBUF_RET_OK != iret)
+ {
+ NSRTP_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();
+ NSRTP_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_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;
+
+ NSRTP_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_LENGTH */
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ 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_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)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ return NULL;
+ }
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ 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)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed");
+ 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_LENGTH */
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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_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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+ else
+ {
+ /*app must less than NSFW_MEM_APPNAME_LENGTH */
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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_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)
+ {
+ NSRTP_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)
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S fails]");
+ }
+ }
+ else
+ {
+ /*app's name can not over NSFW_MEM_APPNAME_LENGTH */
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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))
+ {
+ NSRTP_LOGERR("SPRINTF_S failed]");
+ }
+ }
+
+ 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_static(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)
+{
+ 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);
+}
+
+int nsfw_attach_core_id(nsfw_mem_name * name)
+{
+ return 0;
+}
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h
new file mode 100644
index 0000000..6fbff59
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_mng.h
@@ -0,0 +1,135 @@
+/*
+*
+* 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 nstack_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 memory
+ */
+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 back to 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_static(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);
+
+int nsfw_attach_core_id(nsfw_mem_name * name);
+
+#endif
diff --git a/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c
new file mode 100644
index 0000000..f580640
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.c
@@ -0,0 +1,843 @@
+/*
+*
+* 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 <string.h>
+#include <common_sys_config.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"
+#include "common_pal_bitwide_adjust.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;
+ /*calculate 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)
+ {
+ NSRTP_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))
+ {
+ NSRTP_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 contained 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 enqueue 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 enqueue success && 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 enqueue 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 enqueue 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 enqueue 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 success && 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 success && 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 dequeued 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 dequeued 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/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h b/stacks/lwip_stack/src/mem/nsfw_shmem/nsfw_shmem_ring.h
new file mode 100644
index 0000000..af7c30c
--- /dev/null
+++ b/stacks/lwip_stack/src/mem/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 <stdint.h>
+
+#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_*/