aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornanger <zhenyinan@huawei.com>2018-08-20 11:14:15 +0800
committeryinan zhen <zhenyinan@huawei.com>2018-08-24 01:00:15 +0000
commitb63ec47559ad7b90f348dd733b805d78d156893d (patch)
tree2118aca2dd56f41972d96b7e478c00af55206d95
parent866a942c3581440bef9ebda5d84c039490bb3179 (diff)
Feat: add new share memory module
Change-Id: I25e6ca1bd3d2acc0031926e3f46d4501e8d78f1a Signed-off-by: nanger <zhenyinan@huawei.com>
-rw-r--r--CMakeLists.txt5
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/framework/CMakeLists.txt7
-rw-r--r--src/framework/common/include/arch/x86/dmm_atomic.h21
-rw-r--r--src/framework/common/include/arch/x86/dmm_barrier.h21
-rw-r--r--src/framework/common/include/arch/x86/dmm_pause.h30
-rw-r--r--src/framework/common/include/arch/x86/dmm_rwlock.h21
-rw-r--r--src/framework/common/include/arch/x86/dmm_spinlock.h21
-rw-r--r--src/framework/common/include/dmm_fs.h32
-rw-r--r--src/framework/common/include/generic/dmm_atomic.h177
-rw-r--r--src/framework/common/include/generic/dmm_barrier.h25
-rw-r--r--src/framework/common/include/generic/dmm_pause.h30
-rw-r--r--src/framework/common/include/generic/dmm_rwlock.h76
-rw-r--r--src/framework/common/include/generic/dmm_spinlock.h53
-rw-r--r--src/framework/include/dmm_config.h43
-rw-r--r--src/framework/mem/dmm_fshm.c144
-rw-r--r--src/framework/mem/dmm_group.c185
-rw-r--r--src/framework/mem/dmm_group.h36
-rw-r--r--src/framework/mem/dmm_heap.c83
-rw-r--r--src/framework/mem/dmm_huge.c53
-rw-r--r--src/framework/mem/dmm_memory.c133
-rw-r--r--src/framework/mem/dmm_memory.h78
-rw-r--r--src/framework/mem/dmm_segment.c543
-rw-r--r--src/framework/mem/dmm_segment.h35
-rw-r--r--src/framework/mem/dmm_share.h114
25 files changed, 1967 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf17c75..19ca514 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_PATH})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_PATH_SHARED})
SET(DMM_DPDK_INSTALL_DIR "" CACHE STRING "to get the dpdk install path by cmd")
SET(DMM_REL_INC_DIR ${CMAKE_CURRENT_LIST_DIR}/release/include)
+SET(DMM_ARCH x86)
SET(GENERATE_RPM_PATH ${CMAKE_CURRENT_LIST_DIR}/release/rpm)
file(MAKE_DIRECTORY ${GENERATE_RPM_PATH})
@@ -119,7 +120,9 @@ cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/include/* ${CMAKE_CURRENT_LIST_DIR
cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/base/include/*.h ${CMAKE_CURRENT_LIST_DIR}/release/include/
cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/base/include/common/* ${CMAKE_CURRENT_LIST_DIR}/release/include/
-cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/* ${CMAKE_CURRENT_LIST_DIR}/release/include/
+cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/*.h ${CMAKE_CURRENT_LIST_DIR}/release/include/
+cp -rf ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/generic ${CMAKE_CURRENT_LIST_DIR}/release/include/
+cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/common/include/arch/${DMM_ARCH}/* ${CMAKE_CURRENT_LIST_DIR}/release/include/
cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/ipc/mgr_com/mgr_com.h ${CMAKE_CURRENT_LIST_DIR}/release/include/
cp -f ${CMAKE_CURRENT_LIST_DIR}/src/framework/hal/hal.h ${CMAKE_CURRENT_LIST_DIR}/release/include/
cp -f ${CMAKE_CURRENT_LIST_DIR}/src/nSocket/include/nstack_dmm_api.h ${CMAKE_CURRENT_LIST_DIR}/release/include/
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1a7f63f..c71659c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,11 +22,13 @@ endif()
INCLUDE_DIRECTORIES(
framework/log/
+ framework/mem
framework/include/
framework/common/include/
+ framework/common/include/arch/${DMM_ARCH}
framework/common/base/include/
- framework/common/base/include/common/
- ${PRI_DIRECTORIES}
+ framework/common/base/include/common/
+ ${PRI_DIRECTORIES}
../platform/SecureC/include/
../thirdparty/glog/glog-0.3.4/src/
)
diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt
index b76e1ce..6b22e51 100644
--- a/src/framework/CMakeLists.txt
+++ b/src/framework/CMakeLists.txt
@@ -29,10 +29,13 @@ FILE(GLOB STARTUP startup/*.c)
FILE(GLOB MAINTAIN maintain/*.c)
FILE(GLOB HAL hal/*.c)
FILE(GLOB DMM_ADPT ../adapt/*.c)
+FILE(GLOB MEM mem/*.c)
+ADD_LIBRARY(dmm_api SHARED
+ ${COMMON} ${INIT} ${IPC} ${LOG} ${SNAPSHOT}
+ ${STARTUP} ${MAINTAIN} ${TRACEING} ${HAL}
+ ${DMM_ADPT} ${LIBCOMM} ${MEM})
-
-ADD_LIBRARY(dmm_api SHARED ${COMMON} ${INIT} ${IPC} ${LOG} ${SNAPSHOT} ${STARTUP} ${MAINTAIN} ${TRACEING} ${HAL} ${DMM_ADPT} ${LIBCOMM})
if(WITH_SECUREC_LIB)
ADD_DEPENDENCIES(dmm_api SECUREC JSON GLOG)
else()
diff --git a/src/framework/common/include/arch/x86/dmm_atomic.h b/src/framework/common/include/arch/x86/dmm_atomic.h
new file mode 100644
index 0000000..fae99c2
--- /dev/null
+++ b/src/framework/common/include/arch/x86/dmm_atomic.h
@@ -0,0 +1,21 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_ATOMIC_H__ARCH_X86_
+#define _DMM_ATOMIC_H__ARCH_X86_
+
+#include "generic/dmm_atomic.h"
+
+#endif /* #ifndef _DMM_ATOMIC_H__ARCH_X86_ */
diff --git a/src/framework/common/include/arch/x86/dmm_barrier.h b/src/framework/common/include/arch/x86/dmm_barrier.h
new file mode 100644
index 0000000..bf53650
--- /dev/null
+++ b/src/framework/common/include/arch/x86/dmm_barrier.h
@@ -0,0 +1,21 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_BARRIER_H__ARCH_X86_
+#define _DMM_BARRIER_H__ARCH_X86_
+
+#include "generic/dmm_barrier.h"
+
+#endif /* #ifndef _DMM_BARRIER_H__ARCH_X86_ */
diff --git a/src/framework/common/include/arch/x86/dmm_pause.h b/src/framework/common/include/arch/x86/dmm_pause.h
new file mode 100644
index 0000000..56c60f0
--- /dev/null
+++ b/src/framework/common/include/arch/x86/dmm_pause.h
@@ -0,0 +1,30 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_PAUSE_H_
+#define _DMM_PAUSE_H_
+
+#include <emmintrin.h>
+
+inline static void
+dmm_pause (void)
+{
+ _mm_pause ();
+}
+
+#define DMM_PAUSE_WHILE(cond) do { dmm_pause(); } while (!!(cond))
+#define DMM_WHILE_PAUSE(cond) do { while (!!(cond)) dmm_pause(); } while (0)
+
+#endif /* #ifndef _DMM_PAUSE_H_ */
diff --git a/src/framework/common/include/arch/x86/dmm_rwlock.h b/src/framework/common/include/arch/x86/dmm_rwlock.h
new file mode 100644
index 0000000..0c31329
--- /dev/null
+++ b/src/framework/common/include/arch/x86/dmm_rwlock.h
@@ -0,0 +1,21 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_RWLOCK_H__ARCH_X86_
+#define _DMM_RWLOCK_H__ARCH_X86_
+
+#include "generic/dmm_rwlock.h"
+
+#endif /* #ifndef _DMM_RWLOCK_H__ARCH_X86_ */
diff --git a/src/framework/common/include/arch/x86/dmm_spinlock.h b/src/framework/common/include/arch/x86/dmm_spinlock.h
new file mode 100644
index 0000000..69ed9a6
--- /dev/null
+++ b/src/framework/common/include/arch/x86/dmm_spinlock.h
@@ -0,0 +1,21 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_SPINLOCK_H__ARCH_X86_
+#define _DMM_SPINLOCK_H__ARCH_X86_
+
+#include "generic/dmm_spinlock.h"
+
+#endif /* #ifndef _DMM_SPINLOCK_H__ARCH_X86_ */
diff --git a/src/framework/common/include/dmm_fs.h b/src/framework/common/include/dmm_fs.h
new file mode 100644
index 0000000..8fd9cd0
--- /dev/null
+++ b/src/framework/common/include/dmm_fs.h
@@ -0,0 +1,32 @@
+/*
+*
+* 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 _DMM_FS_H_
+#define _DMM_FS_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static size_t
+dmm_file_size (int fd)
+{
+ struct stat st;
+ if (fstat (fd, &st) < 0)
+ return 0;
+ return st.st_size;
+}
+
+#endif /* _DMM_FS_H_ */
diff --git a/src/framework/common/include/generic/dmm_atomic.h b/src/framework/common/include/generic/dmm_atomic.h
new file mode 100644
index 0000000..637306b
--- /dev/null
+++ b/src/framework/common/include/generic/dmm_atomic.h
@@ -0,0 +1,177 @@
+/*
+*
+* 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 _DMM_ATOMIC_H_
+#define _DMM_ATOMIC_H_
+
+/* atomic 32 bit operation */
+
+typedef struct
+{
+ volatile int cnt;
+} dmm_atomic_t;
+
+inline static int
+dmm_atomic_get (dmm_atomic_t * a)
+{
+ return a->cnt;
+}
+
+inline static int
+dmm_atomic_add (dmm_atomic_t * a, int n)
+{
+ return __sync_fetch_and_add (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_sub (dmm_atomic_t * a, int n)
+{
+ return __sync_fetch_and_sub (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_and (dmm_atomic_t * a, int n)
+{
+ return __sync_fetch_and_and (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_or (dmm_atomic_t * a, int n)
+{
+ return __sync_fetch_and_or (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_xor (dmm_atomic_t * a, int n)
+{
+ return __sync_fetch_and_xor (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_swap (dmm_atomic_t * a, int o, int n)
+{
+ return __sync_val_compare_and_swap (&a->cnt, o, n);
+}
+
+inline static int
+dmm_atomic_add_return (dmm_atomic_t * a, int n)
+{
+ return __sync_add_and_fetch (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_sub_return (dmm_atomic_t * a, int n)
+{
+ return __sync_sub_and_fetch (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_and_return (dmm_atomic_t * a, int n)
+{
+ return __sync_and_and_fetch (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_or_return (dmm_atomic_t * a, int n)
+{
+ return __sync_or_and_fetch (&a->cnt, n);
+}
+
+inline static int
+dmm_atomic_xor_return (dmm_atomic_t * a, int n)
+{
+ return __sync_xor_and_fetch (&a->cnt, n);
+}
+
+/* atomit 64bit operation */
+
+typedef struct
+{
+ volatile long long int cnt;
+} dmm_atomic64_t;
+
+inline static long long int
+dmm_atomic64_get (dmm_atomic64_t * a)
+{
+ return a->cnt;
+}
+
+inline static long long int
+dmm_atomic64_add (dmm_atomic64_t * a, int n)
+{
+ return __sync_fetch_and_add (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_sub (dmm_atomic64_t * a, int n)
+{
+ return __sync_fetch_and_sub (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_and (dmm_atomic64_t * a, int n)
+{
+ return __sync_fetch_and_and (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_or (dmm_atomic64_t * a, int n)
+{
+ return __sync_fetch_and_or (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_xor (dmm_atomic64_t * a, int n)
+{
+ return __sync_fetch_and_xor (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_swap (dmm_atomic_t * a, int o, int n)
+{
+ return __sync_val_compare_and_swap (&a->cnt, o, n);
+}
+
+inline static long long int
+dmm_atomic64_add_return (dmm_atomic64_t * a, int n)
+{
+ return __sync_add_and_fetch (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_sub_return (dmm_atomic64_t * a, int n)
+{
+ return __sync_sub_and_fetch (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_and_return (dmm_atomic64_t * a, int n)
+{
+ return __sync_and_and_fetch (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_or_return (dmm_atomic64_t * a, int n)
+{
+ return __sync_or_and_fetch (&a->cnt, n);
+}
+
+inline static long long int
+dmm_atomic64_xor_return (dmm_atomic64_t * a, int n)
+{
+ return __sync_xor_and_fetch (&a->cnt, n);
+}
+
+#endif /* #ifndef _DMM_ATOMIC_H_ */
diff --git a/src/framework/common/include/generic/dmm_barrier.h b/src/framework/common/include/generic/dmm_barrier.h
new file mode 100644
index 0000000..b70fe85
--- /dev/null
+++ b/src/framework/common/include/generic/dmm_barrier.h
@@ -0,0 +1,25 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_BARRIER_H_
+#define _DMM_BARRIER_H_
+
+inline static void
+dmm_barrier (void)
+{
+ __sync_synchronize ();
+}
+
+#endif /* #ifndef _DMM_BARRIER_H_ */
diff --git a/src/framework/common/include/generic/dmm_pause.h b/src/framework/common/include/generic/dmm_pause.h
new file mode 100644
index 0000000..56c60f0
--- /dev/null
+++ b/src/framework/common/include/generic/dmm_pause.h
@@ -0,0 +1,30 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef _DMM_PAUSE_H_
+#define _DMM_PAUSE_H_
+
+#include <emmintrin.h>
+
+inline static void
+dmm_pause (void)
+{
+ _mm_pause ();
+}
+
+#define DMM_PAUSE_WHILE(cond) do { dmm_pause(); } while (!!(cond))
+#define DMM_WHILE_PAUSE(cond) do { while (!!(cond)) dmm_pause(); } while (0)
+
+#endif /* #ifndef _DMM_PAUSE_H_ */
diff --git a/src/framework/common/include/generic/dmm_rwlock.h b/src/framework/common/include/generic/dmm_rwlock.h
new file mode 100644
index 0000000..93570f1
--- /dev/null
+++ b/src/framework/common/include/generic/dmm_rwlock.h
@@ -0,0 +1,76 @@
+/*
+*
+* 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 _DMM_RWLOCK_H_
+#define _DMM_RWLOCK_H_
+
+#include "dmm_pause.h"
+
+typedef struct
+{
+ volatile int lock;
+} dmm_rwlock_t;
+
+#define DMM_RWLOCK_INIT { 0 }
+
+inline static void
+dmm_rwlock_init (dmm_rwlock_t * rwlock)
+{
+ rwlock->lock = 0;
+}
+
+inline static void
+dmm_read_lock (dmm_rwlock_t * rwlock)
+{
+ int val;
+
+ do
+ {
+ if ((val = rwlock->lock) < 0)
+ {
+ dmm_pause ();
+ continue;
+ }
+ }
+ while (!__sync_bool_compare_and_swap (&rwlock->lock, val, val + 1));
+}
+
+inline static void
+dmm_read_unlock (dmm_rwlock_t * rwlock)
+{
+ __sync_sub_and_fetch (&rwlock->lock, 1);
+}
+
+inline static void
+dmm_write_lock (dmm_rwlock_t * rwlock)
+{
+ do
+ {
+ if (rwlock->lock != 0)
+ {
+ dmm_pause ();
+ continue;
+ }
+ }
+ while (!__sync_bool_compare_and_swap (&rwlock->lock, 0, -1));
+}
+
+inline static void
+dmm_write_unlock (dmm_rwlock_t * rwlock)
+{
+ rwlock->lock = 0;
+}
+
+#endif /* #ifndef _DMM_RWLOCK_H_ */
diff --git a/src/framework/common/include/generic/dmm_spinlock.h b/src/framework/common/include/generic/dmm_spinlock.h
new file mode 100644
index 0000000..be183a6
--- /dev/null
+++ b/src/framework/common/include/generic/dmm_spinlock.h
@@ -0,0 +1,53 @@
+/*
+*
+* 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 _DMM_SPINLOCK_H_
+#define _DMM_SPINLOCK_H_
+
+#include "dmm_pause.h"
+
+typedef struct
+{
+ volatile int lock;
+} dmm_spinlock_t;
+
+inline static void
+dmm_spin_init (dmm_spinlock_t * spinlock)
+{
+ spinlock->lock = 0;
+}
+
+inline static void
+dmm_spin_lock (dmm_spinlock_t * spinlock)
+{
+ while (0 != __sync_lock_test_and_set (&spinlock->lock, 1))
+ {
+ DMM_PAUSE_WHILE (spinlock->lock);
+ }
+}
+
+inline static int
+dmm_spin_trylock (dmm_spinlock_t * spinlock)
+{
+ return 0 == __sync_lock_test_and_set (&spinlock->lock, 1);
+}
+
+inline static void
+dmm_spin_unlock (dmm_spinlock_t * spinlock)
+{
+ spinlock->lock = 0;
+}
+
+#endif /* #ifndef _DMM_SPINLOCK_H_ */
diff --git a/src/framework/include/dmm_config.h b/src/framework/include/dmm_config.h
new file mode 100644
index 0000000..43a06ab
--- /dev/null
+++ b/src/framework/include/dmm_config.h
@@ -0,0 +1,43 @@
+/*
+*
+* 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 _DMM_CONFIG_H_
+#define _DMM_CONFIG_H_
+
+#ifndef DMM_VAR_DIR
+#define DMM_VAR_DIR "/var/run"
+#endif
+
+#ifndef DMM_MAIN_SHARE_TYPE
+#define DMM_MAIN_SHARE_TYPE DMM_SHARE_FSHM /* 1 */
+#endif
+
+#ifndef DMM_MAIN_SHARE_SIZE
+#define DMM_MAIN_SHARE_SIZE 1024 /* Megabyte */
+#endif
+
+#ifndef DMM_SHARE_TYPE
+#define DMM_SHARE_TYPE DMM_SHARE_FSHM /* 1 */
+#endif
+
+#ifndef DMM_SHARE_SIZE
+#define DMM_SHARE_SIZE 16 /* Megabyte */
+#endif
+
+#ifndef DMM_HUGE_DIR
+#define DMM_HUGE_DIR "/mnt/dmm-huge"
+#endif
+
+#endif /* _DMM_CONFIG_H_ */
diff --git a/src/framework/mem/dmm_fshm.c b/src/framework/mem/dmm_fshm.c
new file mode 100644
index 0000000..605c728
--- /dev/null
+++ b/src/framework/mem/dmm_fshm.c
@@ -0,0 +1,144 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "dmm_config.h"
+#include "dmm_share.h"
+#include "dmm_fs.h"
+
+#define DMM_FSHM_FMT "%s/dmm-fshm-%d" /* VAR_DIR pid */
+
+inline static void
+set_fshm_path (struct dmm_share *share)
+{
+ (void) snprintf (share->path, sizeof (share->path), DMM_FSHM_FMT,
+ DMM_VAR_DIR, share->pid);
+}
+
+/*
+input: share->path, share->size, share->pid
+output: share->base
+*/
+int
+dmm_fshm_create (struct dmm_share *share)
+{
+ int fd, ret;
+ void *base;
+
+ set_fshm_path (share);
+
+ fd = open (share->path, O_RDWR | O_CREAT, 0666);
+ if (fd < 0)
+ {
+ return -1;
+ }
+
+ ret = ftruncate (fd, share->size);
+ if (ret < 0)
+ {
+ (void) close (fd);
+ return -1;
+ }
+
+ base = mmap (NULL, share->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
+ if (base == MAP_FAILED)
+ {
+ (void) close (fd);
+ return -1;
+ }
+
+ share->base = base;
+
+ (void) close (fd);
+ return 0;
+}
+
+int
+dmm_fshm_delete (struct dmm_share *share)
+{
+ (void) munmap (share->base, share->size);
+ (void) unlink (share->path);
+
+ return 0;
+}
+
+/*
+input: share->path, share->size, share->base(OPT)
+output: share->base(if-null)
+*/
+int
+dmm_fshm_attach (struct dmm_share *share)
+{
+ int fd;
+ void *base;
+
+ if (share->type != DMM_SHARE_FSHM)
+ {
+ return -1;
+ }
+
+ fd = open (share->path, O_RDWR);
+ if (fd < 0)
+ {
+ return -1;
+ }
+
+ if (share->size <= 0)
+ {
+ share->size = dmm_file_size (fd);
+ if (share->size == 0)
+ {
+ (void) close (fd);
+ return -1;
+ }
+ }
+
+ base = mmap (share->base, share->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
+ if (base == MAP_FAILED)
+ {
+ (void) close (fd);
+ return -1;
+ }
+
+ if (NULL == share->base)
+ {
+ share->base = base;
+ }
+ else if (base != share->base)
+ {
+ (void) munmap (base, share->size);
+ (void) close (fd);
+ return -1;
+ }
+
+ (void) close (fd);
+ return 0;
+}
+
+int
+dmm_fshm_detach (struct dmm_share *share)
+{
+ (void) munmap (share->base, share->size);
+
+ return 0;
+}
diff --git a/src/framework/mem/dmm_group.c b/src/framework/mem/dmm_group.c
new file mode 100644
index 0000000..35e6100
--- /dev/null
+++ b/src/framework/mem/dmm_group.c
@@ -0,0 +1,185 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+//#include "dmm_memory.h"
+#include "dmm_config.h"
+#include "dmm_group.h"
+#include "dmm_pause.h"
+
+#define DMM_GROUP_ACTIVE 0x55D5551
+#define DMM_GROUP_GLOBAL "global"
+#define DMM_GROUP_ENV "DMM_GROUP"
+#define DMM_GROUP_FMT "%s/dmm-group-%s" /* VAR_DIR group-name */
+
+static struct flock group_lock = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = sizeof (struct dmm_group),
+};
+
+static int group_fd = -1;
+struct dmm_group *main_group = NULL;
+
+inline static const char *
+get_group_path ()
+{
+ static char group_path[PATH_MAX] = "";
+
+ if (!group_path[0])
+ {
+ const char *group = getenv (DMM_GROUP_ENV);
+
+ if (!group || !group[0])
+ group = DMM_GROUP_GLOBAL;
+
+ (void) snprintf (group_path, sizeof (group_path), DMM_GROUP_FMT,
+ DMM_VAR_DIR, group);
+ group_path[sizeof (group_path) - 1] = 0;
+ }
+
+ return group_path;
+}
+
+void
+dmm_group_active ()
+{
+ main_group->group_init = DMM_GROUP_ACTIVE;
+}
+
+int
+dmm_group_create_main ()
+{
+ int ret;
+ const char *path = get_group_path ();
+
+ group_fd = open (path, O_RDWR | O_CREAT, 0664);
+ if (group_fd < 0)
+ {
+ return -1;
+ }
+
+ ret = ftruncate (group_fd, sizeof (struct dmm_group));
+ if (ret < 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ ret = fcntl (group_fd, F_SETLK, &group_lock);
+ if (ret < 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group),
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ group_fd, 0);
+
+ if (main_group == MAP_FAILED)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+dmm_group_delete_main ()
+{
+ if (main_group)
+ {
+ (void) munmap (main_group, sizeof (struct dmm_group));
+ main_group = NULL;
+ }
+
+ if (group_fd >= 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ }
+
+ (void) unlink (get_group_path ());
+
+ return 0;
+}
+
+int
+dmm_group_attach_main ()
+{
+ const char *path = get_group_path ();
+
+ group_fd = open (path, O_RDONLY);
+ if (group_fd < 0)
+ {
+ return -1;
+ }
+
+ main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group *),
+ PROT_READ, MAP_SHARED, group_fd, 0);
+ if (main_group == MAP_FAILED)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ while (main_group->group_init != DMM_GROUP_ACTIVE)
+ {
+ dmm_pause ();
+ }
+
+ if (kill (main_group->share.pid, 0))
+ {
+ (void) munmap (main_group->share.base, main_group->share.size);
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+dmm_group_detach_main ()
+{
+ if (main_group)
+ {
+ (void) munmap (main_group, sizeof (struct dmm_group));
+ main_group = NULL;
+ }
+
+ if (group_fd >= 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ }
+
+ return 0;
+}
diff --git a/src/framework/mem/dmm_group.h b/src/framework/mem/dmm_group.h
new file mode 100644
index 0000000..b11a22b
--- /dev/null
+++ b/src/framework/mem/dmm_group.h
@@ -0,0 +1,36 @@
+/*
+*
+* 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 _DMM_GROUP_H_
+#define _DMM_GROUP_H_
+
+#include "dmm_share.h"
+
+struct dmm_group
+{
+ volatile int group_init;
+ struct dmm_share share;
+};
+
+extern struct dmm_group *main_group;
+
+void dmm_group_active ();
+int dmm_group_create_main ();
+int dmm_group_delete_main ();
+int dmm_group_attach_main ();
+int dmm_group_detach_main ();
+
+#endif /* _DMM_GROUP_H_ */
diff --git a/src/framework/mem/dmm_heap.c b/src/framework/mem/dmm_heap.c
new file mode 100644
index 0000000..bc966ef
--- /dev/null
+++ b/src/framework/mem/dmm_heap.c
@@ -0,0 +1,83 @@
+/*
+*
+* 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 <sys/types.h>
+
+#include "dmm_config.h"
+#include "dmm_share.h"
+
+struct heap_path
+{
+ void *base;
+ size_t size;
+};
+
+int
+dmm_heap_create (struct dmm_share *share)
+{
+ share->base = malloc (share->size);
+
+ if (share->base)
+ {
+ struct heap_path *hp = (struct heap_path *) share->path;
+ hp->base = share->base;
+ hp->size = share->size;
+ return 0;
+ }
+
+ return -1;
+}
+
+int
+dmm_heap_delete (struct dmm_share *share)
+{
+ free (share->base);
+ return 0;
+}
+
+int
+dmm_heap_attach (struct dmm_share *share)
+{
+ struct heap_path *hp = (struct heap_path *) share->path;
+
+ if (share->base)
+ {
+ if (hp->base != share->base)
+ return -1;
+ }
+ else
+ {
+ share->base = hp->base;
+ }
+
+ if (share->size)
+ {
+ if (share->size != hp->size)
+ return -1;
+ }
+ else
+ {
+ share->size = hp->size;
+ }
+
+ return 0;
+}
+
+int
+dmm_heap_detach (struct dmm_share *share)
+{
+ return 0;
+}
diff --git a/src/framework/mem/dmm_huge.c b/src/framework/mem/dmm_huge.c
new file mode 100644
index 0000000..735c507
--- /dev/null
+++ b/src/framework/mem/dmm_huge.c
@@ -0,0 +1,53 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "dmm_config.h"
+#include "dmm_share.h"
+
+#define DMM_HUGE_FMT "%s/dmm-%d-%d" /* HUGE_DIR pid index */
+
+inline static void
+huge_set_path (struct dmm_share *share, int index)
+{
+ (void) snprintf (share->path, sizeof (share->path), DMM_HUGE_FMT,
+ DMM_HUGE_DIR, share->pid, index);
+}
+
+int
+dmm_huge_create (struct dmm_share *share)
+{
+ return -1;
+}
+
+int
+dmm_huge_delete (struct dmm_share *share)
+{
+ return -1;
+}
+
+int
+dmm_huge_attach (struct dmm_share *share)
+{
+ return -1;
+}
+
+int
+dmm_huge_detach (struct dmm_share *share)
+{
+ return -1;
+}
diff --git a/src/framework/mem/dmm_memory.c b/src/framework/mem/dmm_memory.c
new file mode 100644
index 0000000..0352432
--- /dev/null
+++ b/src/framework/mem/dmm_memory.c
@@ -0,0 +1,133 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "dmm_config.h"
+#include "dmm_memory.h"
+#include "dmm_group.h"
+
+#define DMM_MEGABYTE (1024 * 1024)
+
+/* shared from main process */
+static struct dmm_share *main_share = NULL;
+struct dmm_segment *main_seg = NULL;
+
+/* shared by process tree */
+static struct dmm_share base_share = { 0 };
+
+struct dmm_segment *base_seg = NULL;
+
+int
+dmm_mem_main_init ()
+{
+ int ret;
+
+ ret = dmm_group_create_main ();
+ if (ret)
+ {
+ return -1;
+ }
+
+ main_share = &main_group->share;
+ main_share->type = DMM_MAIN_SHARE_TYPE;
+ main_share->size = DMM_MAIN_SHARE_SIZE * DMM_MEGABYTE;
+ main_share->base = NULL;
+ main_share->pid = getpid ();
+ ret = dmm_share_create (main_share);
+ if (ret)
+ {
+ return -1;
+ }
+
+ main_seg = dmm_seg_create (main_share->base, main_share->size);
+ if (!main_seg)
+ {
+ return -1;
+ }
+
+ dmm_group_active ();
+
+ return 0;
+}
+
+int
+dmm_mem_main_exit ()
+{
+ dmm_group_delete_main ();
+ return 0;
+}
+
+int
+dmm_mem_app_init ()
+{
+ int ret;
+
+ ret = dmm_group_attach_main ();
+ if (0 == ret)
+ {
+ main_share = &main_group->share;
+ ret = dmm_share_attach (main_share);
+ if (ret)
+ {
+ return -1;
+ }
+
+ main_seg = dmm_seg_attach (main_share->base, main_share->size);
+ if (!main_seg)
+ {
+ return -1;
+ }
+
+ /* now share main process share-memory */
+ base_seg = main_seg;
+ }
+ else
+ {
+ base_share.type = DMM_SHARE_TYPE;
+ base_share.size = DMM_SHARE_SIZE * DMM_MEGABYTE;
+ base_share.base = NULL;
+ base_share.pid = getpid ();
+ ret = dmm_share_create (&base_share);
+ if (ret)
+ {
+ return -1;
+ }
+
+ base_seg = dmm_seg_create (base_share.base, base_share.size);
+ if (!base_seg)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+dmm_mem_app_exit ()
+{
+ dmm_group_detach_main ();
+
+ if (base_share.base)
+ dmm_share_delete (&base_share);
+
+ base_share.base = NULL;
+ base_seg = NULL;
+ main_seg = NULL;
+
+ return 0;
+}
diff --git a/src/framework/mem/dmm_memory.h b/src/framework/mem/dmm_memory.h
new file mode 100644
index 0000000..2fac118
--- /dev/null
+++ b/src/framework/mem/dmm_memory.h
@@ -0,0 +1,78 @@
+/*
+*
+* 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 _DMM_MEMORY_H_
+#define _DMM_MEMORY_H_
+#include <stdio.h>
+#include <stdarg.h>
+#include "dmm_share.h"
+#include "dmm_segment.h"
+
+int dmm_mem_main_init ();
+int dmm_mem_main_exit ();
+
+int dmm_mem_app_init ();
+int dmm_mem_app_exit ();
+
+extern struct dmm_segment *main_seg;
+extern struct dmm_segment *base_seg;
+
+inline static void *
+dmm_map (size_t size, const char name[DMM_MEM_NAME_SIZE])
+{
+ return dmm_mem_map (base_seg, size, name);
+}
+
+inline static void *
+dmm_mapv (size_t size, const char *name_fmt, ...)
+{
+ int len;
+ char name[DMM_MEM_NAME_SIZE];
+ va_list ap;
+
+ va_start (ap, name_fmt);
+ len = vsnprintf (name, DMM_MEM_NAME_SIZE, name_fmt, ap);
+ va_end (ap);
+
+ if (len >= DMM_MEM_NAME_SIZE)
+ return NULL;
+
+ return dmm_map (size, name);
+}
+
+inline static void *
+dmm_lookup (const char name[DMM_MEM_NAME_SIZE])
+{
+ return dmm_mem_lookup (base_seg, name);
+}
+
+inline static void *
+dmm_lookupv (const char *name_fmt, ...)
+{
+ int len;
+ char name[DMM_MEM_NAME_SIZE];
+ va_list ap;
+
+ va_start (ap, name_fmt);
+ len = vsnprintf (name, DMM_MEM_NAME_SIZE, name_fmt, ap);
+ va_end (ap);
+
+ if (len >= DMM_MEM_NAME_SIZE)
+ return NULL;
+
+ return dmm_mem_lookup (base_seg, name);
+}
+
+#endif /* _DMM_MEMORY_H_ */
diff --git a/src/framework/mem/dmm_segment.c b/src/framework/mem/dmm_segment.c
new file mode 100644
index 0000000..6358506
--- /dev/null
+++ b/src/framework/mem/dmm_segment.c
@@ -0,0 +1,543 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "dmm_rwlock.h"
+#include "dmm_segment.h"
+#include "nstack_log.h"
+
+#define SECTION_SIZE 64 /* cache line size */
+
+#define FIRST_NAME "FIRST SECTION FOR SEGMENT"
+#define LAST_NAME "LAST SECTION FOR FREE HEAD"
+
+#define MEM_ERR(fmt, ...) \
+ NS_LOGPID(LOGFW, "DMM-MEM", NSLOG_ERR, fmt, ##__VA_ARGS__)
+
+/*
+init create:
+ \--total number
+ /--head no align \ can be used \--tail no align
+ / ___________________/\___________________ \
+/\/ \/\
+__<F>{S}[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]<L>__
+^ \ /\ /\____________ ________________/\ /
+| | | \ / |
+| | +--the segment | +--last section(free:0 used:0)
+| +--first section(prev_rel:0 used:2 free:11 req_size:sizeof(dmm_segment))
++--base address
+
+init: <F>{S}[ ]<L>
+alloc A: <F>{S}[ ]<A>#########<L>
+alloc B: <F>{S}[ ]<B>#########<A>#########<L>
+free A: <F>{S}[ ]<B>#########[ ]<L>
+alloc C: <F>{S}[ ]<C>###<B>#########[ ]<L>
+*/
+
+typedef struct dmm_section
+{
+ int prev_rel;
+ int used_num;
+ int free_num;
+ int __flags; /* reserved */
+ size_t req_size; /* in bytes */
+ int less_rel; /* for free list */
+ int more_rel; /* for free list */
+ char name[DMM_MEM_NAME_SIZE];
+} __attribute__ ((__aligned__ (SECTION_SIZE))) section_t;
+SIZE_OF_TYPE_EQUAL_TO (section_t, SECTION_SIZE);
+
+struct dmm_segment
+{
+ void *base; /* base address(maybe not align) */
+ size_t size; /* full size */
+ section_t *first; /* aligned 64 */
+ section_t *last; /* last section used to handle free list */
+ dmm_rwlock_t lock;
+ int total_num; /* MAX:2147483647 ==> MAX size: 128M-64 */
+ int used_num;
+ int sec_num;
+ size_t used_size; /* real alloc size bytes */
+};
+
+/* calculate segment number, auto align 64, include 1 section_t */
+inline static int
+CALC_NUM (size_t size)
+{
+ if (size)
+ {
+ const size_t MASK = SECTION_SIZE - 1;
+ return (size + MASK) / SECTION_SIZE + 1;
+ }
+
+ return 2; /* if size is 0, then alloc 1 block */
+}
+
+inline static int
+SEC_REL (const section_t * base, const section_t * sec)
+{
+ return sec - base;
+}
+
+section_t *
+REL_SEC (section_t * base, int rel)
+{
+ return base + rel;
+}
+
+inline static int
+SEC_INDEX (struct dmm_segment *seg, section_t * sec)
+{
+ return SEC_REL (seg->first, sec);
+}
+
+inline static section_t *
+LESS_SEC (section_t * sec)
+{
+ return sec + sec->less_rel;
+}
+
+inline static section_t *
+MORE_SEC (section_t * sec)
+{
+ return sec + sec->more_rel;
+}
+
+inline static section_t *
+PREV_SEC (section_t * sec)
+{
+ return sec + sec->prev_rel;
+}
+
+inline static section_t *
+NEXT_SEC (section_t * sec)
+{
+ return sec + (sec->free_num + sec->used_num);
+}
+
+inline static int
+CHECK_ADDR (struct dmm_segment *seg, void *mem)
+{
+ if (mem < (void *) seg->first)
+ return -1;
+ if (mem > (void *) seg->last)
+ return -1;
+ if ((long) mem & (SECTION_SIZE - 1))
+ return -1;
+
+ return 0;
+}
+
+inline static section_t *
+mem_lookup (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE])
+{
+ section_t *sec;
+
+ /* caller ensures the validity of the name */
+
+ for (sec = seg->last; sec != seg->first; sec = PREV_SEC (sec))
+ {
+ if (sec->name[0] == 0)
+ continue;
+ if (0 == strcmp (sec->name, name))
+ return sec;
+ }
+
+ return NULL;
+}
+
+static section_t *
+mem_alloc (struct dmm_segment *seg, size_t size)
+{
+ const int num = CALC_NUM (size);
+ section_t *sec, *pos, *next, *less, *more;
+
+ if (num > seg->total_num - seg->used_num)
+ {
+ /* no enough memory */
+ return NULL;
+ }
+
+ /* find enough free space */
+ pos = seg->last;
+ do
+ {
+ pos = MORE_SEC (pos);
+ if (pos == seg->last)
+ {
+ /* no enough memory */
+ return NULL;
+ }
+ }
+ while (num > pos->free_num);
+
+ /* allocate pos pos section tail */
+
+ /* change next section's prev possion */
+ next = NEXT_SEC (pos);
+ next->prev_rel = -num;
+
+ /* create new section */
+ sec = PREV_SEC (next);
+ sec->prev_rel = SEC_REL (sec, pos);
+ sec->used_num = num;
+ sec->req_size = size;
+ sec->free_num = 0; /* no free space */
+ sec->less_rel = 0;
+ sec->more_rel = 0;
+ sec->name[0] = 0;
+
+ /* adjust pos */
+ pos->free_num -= num;
+
+ less = LESS_SEC (pos);
+ more = MORE_SEC (pos);
+
+ /* remove pos free list */
+ less->more_rel = SEC_REL (less, more);
+ more->less_rel = SEC_REL (more, less);
+ pos->more_rel = 0;
+ pos->less_rel = 0;
+
+ /* find position */
+ while (less != seg->last)
+ {
+ if (pos->free_num >= less->free_num)
+ break;
+ less = LESS_SEC (less);
+ }
+
+ /* insert into free list */
+ more = MORE_SEC (less);
+ less->more_rel = SEC_REL (less, pos);
+ more->less_rel = SEC_REL (more, pos);
+ pos->more_rel = SEC_REL (pos, more);
+ pos->less_rel = SEC_REL (pos, less);
+
+ /* adjust segment */
+ seg->used_size += size;
+ seg->used_num += num;
+ seg->sec_num++;
+
+ /* victory */
+ return sec;
+}
+
+static void
+mem_free (struct dmm_segment *seg, section_t * sec)
+{
+ const int num = sec->used_num + sec->free_num;
+ section_t *next = NEXT_SEC (sec);
+ section_t *prev = PREV_SEC (sec);
+ section_t *more, *less;
+
+ /* adjust next section's prev */
+ next->prev_rel = SEC_REL (next, prev);
+
+ if (sec->free_num)
+ {
+ /* remove from free list */
+ more = MORE_SEC (sec);
+ less = LESS_SEC (sec);
+ more->less_rel = SEC_REL (more, less);
+ less->more_rel = SEC_REL (less, more);
+ }
+
+ if (prev->free_num)
+ {
+ /* remove from free list */
+ more = MORE_SEC (prev);
+ less = LESS_SEC (prev);
+ more->less_rel = SEC_REL (more, less);
+ less->more_rel = SEC_REL (less, more);
+ }
+ else
+ {
+ more = MORE_SEC (seg->last);
+ }
+
+ /* put the space to prev's free space */
+ prev->free_num += num;
+
+ while (more != seg->last)
+ {
+ if (prev->free_num <= more->free_num)
+ break;
+ more = MORE_SEC (more);
+ }
+ less = LESS_SEC (more);
+
+ /* insert */
+ less->more_rel = SEC_REL (less, prev);
+ more->less_rel = SEC_REL (more, prev);
+ prev->more_rel = SEC_REL (prev, more);
+ prev->less_rel = SEC_REL (prev, less);
+
+ /* adjust segment */
+ seg->used_size -= sec->req_size;
+ seg->used_num -= sec->used_num;
+ seg->sec_num--;
+}
+
+void
+dmm_seg_dump (struct dmm_segment *seg)
+{
+ section_t *sec;
+
+ dmm_read_lock (&seg->lock);
+
+ (void) printf ("---- segment:%p base:%p size:%lu --------------\n"
+ " first[%d]:%p last[%d]:%p total_num:%d used_num:%d\n"
+ " sec_num:%d used_size:%lu use%%:%lu%% free%%:%lu%%\n",
+ seg, seg->base, seg->size,
+ SEC_INDEX (seg, seg->first), seg->first,
+ SEC_INDEX (seg, seg->last), seg->last,
+ seg->total_num, seg->used_num,
+ seg->sec_num, seg->used_size,
+ seg->used_size * 100 / seg->size,
+ (seg->total_num -
+ seg->used_num) * SECTION_SIZE * 100 / seg->size);
+
+ (void) printf ("----------------------------------------\n"
+ "%18s %9s %9s %9s %9s %10s %9s %9s %s\n",
+ "PHYSICAL-ORDER", "section", "prev_rel", "used_num",
+ "free_num", "req_size", "less_rel", "more_rel", "name");
+
+ sec = seg->first;
+ while (1)
+ {
+ (void) printf ("%18p %9d %9d %9d %9d %10lu %9d %9d '%s'\n",
+ sec, SEC_INDEX (seg, sec),
+ sec->prev_rel, sec->used_num, sec->free_num,
+ sec->req_size, sec->less_rel, sec->more_rel, sec->name);
+ if (sec == seg->last)
+ break;
+ sec = NEXT_SEC (sec);
+ }
+
+ (void) printf ("----------------------------------------\n"
+ "%18s %9s %9s\n", "FREE-ORDER", "section", "free_num");
+ for (sec = MORE_SEC (seg->last); sec != seg->last; sec = MORE_SEC (sec))
+ {
+ (void) printf ("%18p %9d %9d\n",
+ sec, SEC_INDEX (seg, sec), sec->free_num);
+ }
+
+ (void) printf ("----------------------------------------\n");
+
+ dmm_read_unlock (&seg->lock);
+}
+
+inline static int
+align_section (void *base, size_t size, section_t ** first)
+{
+ const long MASK = ((long) SECTION_SIZE - 1);
+ const int SEG_NUM = CALC_NUM (sizeof (struct dmm_segment));
+
+ const long align = (long) base;
+ const long addr = (align + MASK) & (~MASK);
+ const size_t total = (size - (addr - align)) / SECTION_SIZE;
+
+ if (total > 0x7fffFFFF)
+ return -1;
+ if (total < SEG_NUM + 1) /* first+segment + last */
+ return -1;
+
+ *first = (section_t *) addr;
+ return (int) total;
+}
+
+struct dmm_segment *
+dmm_seg_create (void *base, size_t size)
+{
+ const int SEG_NUM = CALC_NUM (sizeof (struct dmm_segment));
+ section_t *first, *last;
+ struct dmm_segment *seg;
+ int total = align_section (base, size, &first);
+
+ if (total <= 0)
+ return NULL;
+
+ last = first + (total - 1);
+
+ /* first section */
+ first->prev_rel = 0;
+ first->used_num = SEG_NUM;
+ first->req_size = sizeof (struct dmm_segment);
+ first->free_num = total - (SEG_NUM + 1);
+ first->less_rel = SEC_REL (first, last);
+ first->more_rel = SEC_REL (first, last);
+ first->name[0] = 0;
+ (void) strncpy (&first->name[1], FIRST_NAME, sizeof (first->name) - 1);
+
+ /* last section */
+ last->prev_rel = SEC_REL (last, first);
+ last->used_num = 0;
+ last->req_size = 0;
+ last->free_num = 0;
+ last->less_rel = SEC_REL (last, first);
+ last->more_rel = SEC_REL (last, first);
+ last->name[0] = 0;
+ (void) strncpy (&last->name[1], LAST_NAME, sizeof (first->name) - 1);
+
+ /* segment */
+ seg = (struct dmm_segment *) (first + 1);
+ dmm_rwlock_init (&seg->lock);
+ seg->base = base;
+ seg->size = size;
+ seg->first = first;
+ seg->last = last;
+ seg->total_num = total;
+ seg->sec_num = 2;
+ seg->used_size = sizeof (struct dmm_segment);
+ seg->used_num = first->used_num;
+
+ return seg;
+}
+
+struct dmm_segment *
+dmm_seg_attach (void *base, size_t size)
+{
+ section_t *first, *last;
+ struct dmm_segment *seg;
+ int total = align_section (base, size, &first);
+
+ if (total <= 0)
+ return NULL;
+
+ last = first + (total - 1);
+ seg = (struct dmm_segment *) (first + 1);
+
+ if (seg->base != base)
+ return NULL;
+ if (seg->size != size)
+ return NULL;
+ if (seg->total_num != total)
+ return NULL;
+
+ if (seg->first != first)
+ return NULL;
+ if (first->name[0] != 0)
+ return NULL;
+ if (strncmp (&first->name[1], FIRST_NAME, sizeof (first->name) - 1))
+ return NULL;
+
+ if (seg->last != last)
+ return NULL;
+ if (last->name[0] != 0)
+ return NULL;
+ if (strncmp (&last->name[1], LAST_NAME, sizeof (last->name) - 1))
+ return NULL;
+
+ return seg;
+}
+
+void *
+dmm_mem_alloc (struct dmm_segment *seg, size_t size)
+{
+ section_t *sec;
+
+ dmm_write_lock (&seg->lock);
+ sec = mem_alloc (seg, size);
+ dmm_write_unlock (&seg->lock);
+
+ return sec ? sec + 1 : NULL;
+}
+
+int
+dmm_mem_free (struct dmm_segment *seg, void *mem)
+{
+ if (CHECK_ADDR (seg, mem))
+ {
+ MEM_ERR ("Invalid address:%p", mem);
+ return -1;
+ }
+
+ dmm_write_lock (&seg->lock);
+ mem_free (seg, ((section_t *) mem) - 1);
+ dmm_write_unlock (&seg->lock);
+
+ return 0;
+}
+
+void *
+dmm_mem_lookup (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE])
+{
+ section_t *sec;
+
+ if (!name || !name[0])
+ return NULL;
+
+ dmm_read_lock (&seg->lock);
+ sec = mem_lookup (seg, name);
+ dmm_read_unlock (&seg->lock);
+
+ return sec ? sec + 1 : NULL;
+}
+
+void *
+dmm_mem_map (struct dmm_segment *seg, size_t size,
+ const char name[DMM_MEM_NAME_SIZE])
+{
+ void *mem;
+ section_t *sec;
+
+ if (!name || !name[0] || strlen (name) >= DMM_MEM_NAME_SIZE)
+ return NULL;
+
+ dmm_write_lock (&seg->lock);
+
+ sec = mem_lookup (seg, name);
+ if (sec)
+ {
+ MEM_ERR ("Map '%s' exist", name);
+ mem = NULL;
+ }
+ else if (!(sec = mem_alloc (seg, size)))
+ {
+ MEM_ERR ("alloc '%s' failed for size %lu", name, size);
+ mem = NULL;
+ }
+ else
+ {
+ (void) strncpy (sec->name, name, sizeof (sec->name));
+ mem = sec + 1;
+ }
+
+ dmm_write_unlock (&seg->lock);
+
+ return mem;
+}
+
+int
+dmm_mem_unmap (struct dmm_segment *seg, const char name[DMM_MEM_NAME_SIZE])
+{
+ section_t *sec;
+
+ if (!name || !name[0])
+ return -1;
+
+ dmm_write_lock (&seg->lock);
+
+ sec = mem_lookup (seg, name);
+ if (sec)
+ mem_free (seg, sec);
+
+ dmm_write_unlock (&seg->lock);
+
+ return sec != NULL ? 0 : -1;
+}
diff --git a/src/framework/mem/dmm_segment.h b/src/framework/mem/dmm_segment.h
new file mode 100644
index 0000000..135f347
--- /dev/null
+++ b/src/framework/mem/dmm_segment.h
@@ -0,0 +1,35 @@
+/*
+*
+* 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 _DMM_SEGMENT_H_
+#define _DMM_SEGMENT_H_
+
+#define DMM_MEM_NAME_SIZE 32
+
+struct dmm_segment *dmm_seg_create (void *base, size_t size);
+struct dmm_segment *dmm_seg_attach (void *base, size_t size);
+void dmm_seg_dump (struct dmm_segment *seg);
+
+void *dmm_mem_alloc (struct dmm_segment *seg, size_t size);
+int dmm_mem_free (struct dmm_segment *seg, void *mem);
+
+void *dmm_mem_lookup (struct dmm_segment *seg,
+ const char name[DMM_MEM_NAME_SIZE]);
+void *dmm_mem_map (struct dmm_segment *seg, size_t size,
+ const char name[DMM_MEM_NAME_SIZE]);
+int dmm_mem_unmap (struct dmm_segment *seg,
+ const char name[DMM_MEM_NAME_SIZE]);
+
+#endif /* #ifndef _DMM_SEGMENT_H_ */
diff --git a/src/framework/mem/dmm_share.h b/src/framework/mem/dmm_share.h
new file mode 100644
index 0000000..0d0ff8f
--- /dev/null
+++ b/src/framework/mem/dmm_share.h
@@ -0,0 +1,114 @@
+/*
+*
+* 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 _DMM_SHARE_H_
+#define _DMM_SHARE_H_
+
+#define DMM_SHARE_PATH_MAX 100
+
+enum dmm_share_type
+{
+ DMM_SHARE_HEAP,
+ DMM_SHARE_FSHM,
+ DMM_SHARE_HUGE,
+
+ DMM_SHARE_ANY = -1
+};
+
+struct dmm_share
+{
+ int type; /* share type enum dmm_share_type */
+ pid_t pid; /* owner/creator pid */
+ void *base; /* base logical address */
+ size_t size; /* memory size */
+ char path[DMM_SHARE_PATH_MAX]; /* share path */
+};
+
+int dmm_heap_create (struct dmm_share *share);
+int dmm_heap_delete (struct dmm_share *share);
+int dmm_heap_attach (struct dmm_share *share);
+int dmm_heap_detach (struct dmm_share *share);
+
+int dmm_fshm_create (struct dmm_share *share);
+int dmm_fshm_delete (struct dmm_share *share);
+int dmm_fshm_attach (struct dmm_share *share);
+int dmm_fshm_detach (struct dmm_share *share);
+
+int dmm_huge_create (struct dmm_share *share);
+int dmm_huge_delete (struct dmm_share *share);
+int dmm_huge_attach (struct dmm_share *share);
+int dmm_huge_detach (struct dmm_share *share);
+
+#define DMM_SHARE_DISPATCH(share, action) \
+({ \
+ int _r; \
+ switch (share->type) \
+ { \
+ case DMM_SHARE_HEAP: \
+ _r = dmm_heap_##action(share); \
+ break; \
+ case DMM_SHARE_FSHM: \
+ _r = dmm_fshm_##action(share); \
+ break; \
+ case DMM_SHARE_HUGE: \
+ _r = dmm_huge_##action(share); \
+ break; \
+ default: \
+ _r = -1; \
+ } \
+ _r; \
+})
+
+/* create share memory
+input: share->type, share->size, share->pid
+output: share->base, share->path
+*/
+inline static int
+dmm_share_create (struct dmm_share *share)
+{
+ return DMM_SHARE_DISPATCH (share, create);
+}
+
+/* delete share memory
+input: share->type, share->base, share->size, share->path
+*/
+inline static int
+dmm_share_delete (struct dmm_share *share)
+{
+ return DMM_SHARE_DISPATCH (share, delete);
+}
+
+/* attach share memory
+input: share->type share->path [share->size] [share->base]
+output: share->base, share->size
+*/
+inline static int
+dmm_share_attach (struct dmm_share *share)
+{
+ return DMM_SHARE_DISPATCH (share, attach);
+}
+
+/* attach share memory
+input: share->type share->size share->base
+*/
+inline static int
+dmm_share_detach (struct dmm_share *share)
+{
+ return DMM_SHARE_DISPATCH (share, detach);
+}
+
+#undef DMM_SHARE_DISPATCH
+
+#endif /* #ifndef _DMM_SHARE_H_ */