diff options
Diffstat (limited to 'src/framework/mem')
23 files changed, 3229 insertions, 1270 deletions
diff --git a/src/framework/mem/basic_mem/dmm_fshm.c b/src/framework/mem/basic_mem/dmm_fshm.c new file mode 100644 index 0000000..ab8665f --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_fshm.c @@ -0,0 +1,200 @@ +/* +* +* 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 <errno.h> + +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_base_linux_api.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(char path[DMM_SHARE_PATH_MAX], pid_t pid) +{ + (void) snprintf_s(path, DMM_SHARE_PATH_MAX, DMM_SHARE_PATH_MAX - 1, + DMM_FSHM_FMT, DMM_VAR_DIR, pid); + + path[DMM_SHARE_PATH_MAX - 1] = 0; +} + +/* +input: share->path, share->size, share->pid +output: share->base +*/ +int dmm_fshm_create(struct dmm_share *share) +{ + int fd, ret; + void *base, *hint = (void *) DMM_MAIN_SHARE_BASE; + + if (share->type != DMM_SHARE_FSHM) + { + NSFW_LOGERR("type error, type:%d", share->type); + return -1; + } + + set_fshm_path(share->path, share->pid); + + NSFW_LOGINF("Start create share memory, path:'%s' size:%lu", + share->path, share->size); + + fd = open(share->path, O_RDWR | O_CREAT, 0666); + if (fd < 0) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + return -1; + } + + ret = ftruncate(fd, (off_t) share->size); + if (ret < 0) + { + NSFW_LOGERR("Set file size failed, path:'%s', errno=%d", + share->path, errno); + (void) nsfw_base_close(fd); + return -1; + } + + base = mmap(hint, share->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (base == MAP_FAILED) + { + NSFW_LOGERR("Map failed, path:'%s' size:%lu, errno=%d", + share->path, share->size, errno); + (void) nsfw_base_close(fd); + return -1; + } + else if (hint && hint != MAP_FAILED && base != hint) + { + NSFW_LOGERR + ("Map address failed, path:'%s' hint:%p size:%lu, base:%p", + share->path, hint, share->size, base); + (void) munmap(base, share->size); + (void) nsfw_base_close(fd); + return -1; + } + + share->base = base; + + NSFW_LOGINF("Share memory created, size:%lu, base=%p", share->size, base); + + (void) nsfw_base_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; + + NSFW_LOGINF("Start attach, share:%p" + " {type:%d pid:%d base:%p size:%lu path:'%s'}", + share, share->type, share->pid, + share->base, share->size, share->path); + + if (share->type != DMM_SHARE_FSHM) + { + NSFW_LOGERR("type error, type:%d", share->type); + return -1; + } + + char *real_path = realpath(share->path, NULL); + if (NULL == real_path) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + return -1; + } + fd = open(real_path, O_RDWR); + if (fd < 0) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + (void) free(real_path); + return -1; + } + + if (share->size <= 0) + { + share->size = dmm_file_size(fd); + if (share->size == 0) + { + NSFW_LOGERR("No file size '%s'", share->path); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + } + + base = mmap(share->base, share->size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (base == MAP_FAILED) + { + NSFW_LOGERR("Map failed, path:'%s' base:%p size:%lu, errno=%d", + share->path, share->base, share->size, errno); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + + if (NULL == share->base) + { + share->base = base; + } + else if (base != share->base) + { + NSFW_LOGERR("Map address error, path:'%s' share->base:%p, base:%p", + share->path, share->base, base); + (void) munmap(base, share->size); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + + NSFW_LOGINF("Memory attached, base=%p", base); + + (void) nsfw_base_close(fd); + (void) free(real_path); + return 0; +} + +int dmm_fshm_detach(struct dmm_share *share) +{ + (void) munmap(share->base, share->size); + + return 0; +} diff --git a/src/framework/mem/basic_mem/dmm_group.c b/src/framework/mem/basic_mem/dmm_group.c new file mode 100644 index 0000000..8a2d318 --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_group.c @@ -0,0 +1,212 @@ +/* +* +* 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 <errno.h> +#include <unistd.h> +#include <limits.h> +#include <sys/types.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include "nsfw_base_linux_api.h" +#include "nstack_log.h" +#include "dmm_config.h" +#include "dmm_group.h" +#include "dmm_pause.h" +#include "nstack_securec.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_s(group_path, sizeof(group_path), + sizeof(group_path) - 1, 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; + NSFW_LOGINF("main group actived"); +} + +int dmm_group_create_main() +{ + int ret; + const char *path = get_group_path(); + + NSFW_LOGINF("start create main group '%s'", path); + + group_fd = open(path, O_RDWR | O_CREAT, 0600); + if (group_fd < 0) + { + NSFW_LOGERR("open file failed, path:'%s', errno=%d", path, errno); + return -1; + } + + ret = ftruncate(group_fd, sizeof(struct dmm_group)); + if (ret < 0) + { + NSFW_LOGERR("set size failed, path:'%s' size:%lu, errno=%d", + path, sizeof(struct dmm_group), errno); + (void) nsfw_base_close(group_fd); + group_fd = -1; + return -1; + } + + ret = fcntl(group_fd, F_SETLK, &group_lock); + if (ret < 0) + { + NSFW_LOGERR("lock file failed, path:'%s', errno=%d", path, errno); + (void) nsfw_base_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) + { + NSFW_LOGERR("mmap failed, path:'%s' size:%lu, errno:%d", + path, sizeof(struct dmm_group), errno); + (void) nsfw_base_close(group_fd); + group_fd = -1; + return -1; + } + + NSFW_LOGINF("main group created, main_group:%p size:%lu", + main_group, sizeof(struct dmm_group)); + + 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) nsfw_base_close(group_fd); + group_fd = -1; + } + + (void) unlink(get_group_path()); + + return 0; +} + +int dmm_group_attach_main() +{ + const char *path = get_group_path(); + + NSFW_LOGINF("Start attach main group '%s'", path); + + group_fd = open(path, O_RDONLY); + if (group_fd < 0) + { + //NSFW_LOGERR ("open group file failed, path:'%s', errno=%d", + //path, errno); + 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) + { + NSFW_LOGERR("mmap failed, path:'%s', errno=%d", path, errno); + (void) nsfw_base_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)) + { + NSFW_LOGERR + ("main group process not exist, path:'%s' pid:%d errno=%d", path, + main_group->share.pid, errno); + (void) munmap(main_group->share.base, main_group->share.size); + (void) nsfw_base_close(group_fd); + (void) unlink(path); + group_fd = -1; + return -1; + } + + NSFW_LOGINF("main group attached, main_group=%p" + " {type=%d pid=%d base=%p size=%zd path='%s'}", + main_group, main_group->share.type, main_group->share.pid, + main_group->share.base, main_group->share.size, + main_group->share.path); + + 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) nsfw_base_close(group_fd); + group_fd = -1; + } + + return 0; +} diff --git a/src/framework/mem/dmm_group.h b/src/framework/mem/basic_mem/dmm_group.h index b11a22b..a07c8d6 100644 --- a/src/framework/mem/dmm_group.h +++ b/src/framework/mem/basic_mem/dmm_group.h @@ -21,16 +21,16 @@ struct dmm_group { - volatile int group_init; - struct dmm_share share; + 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 (); +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/basic_mem/dmm_heap.c b/src/framework/mem/basic_mem/dmm_heap.c new file mode 100644 index 0000000..0efd0b4 --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_heap.c @@ -0,0 +1,82 @@ +/* +* +* 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) +{ + void *point = share->base; + share->base = NULL; + free(point); + 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/basic_mem/dmm_huge.c b/src/framework/mem/basic_mem/dmm_huge.c new file mode 100644 index 0000000..6267b6c --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_huge.c @@ -0,0 +1,192 @@ +/* +* +* 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 <errno.h> + +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_base_linux_api.h" + +#include "dmm_config.h" +#include "dmm_share.h" +#include "dmm_fs.h" + +#define DMM_HUGE_FMT "%s/dmm-%d-%d" /* HUGE_DIR/dmm-pid-index */ + +inline static void +huge_set_path(char path[DMM_SHARE_PATH_MAX], pid_t pid, int index) +{ + (void) snprintf_s(path, DMM_SHARE_PATH_MAX, DMM_SHARE_PATH_MAX - 1, + DMM_HUGE_FMT, DMM_HUGE_DIR, pid, index); + path[DMM_SHARE_PATH_MAX - 1] = 0; +} + +int dmm_huge_create(struct dmm_share *share) +{ + int fd, ret; + void *base, *hint = (void *) DMM_MAIN_SHARE_BASE; + + if (share->type != DMM_SHARE_HUGE) + { + NSFW_LOGERR("Type error, type:%d", share->type); + return -1; + } + + huge_set_path(share->path, share->pid, 0); + + NSFW_LOGINF("Start create share memory, path:'%s' size:%lu", + share->path, share->size); + + fd = open(share->path, O_RDWR | O_CREAT, 0666); + if (fd < 0) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + return -1; + } + + ret = ftruncate(fd, (off_t) share->size); + if (ret < 0) + { + NSFW_LOGERR("Set file size failed, path:'%s', errno=%d", + share->path, errno); + (void) nsfw_base_close(fd); + return -1; + } + + base = mmap(hint, share->size, PROT_READ | PROT_WRITE, + MAP_HUGETLB | MAP_SHARED | MAP_POPULATE, fd, 0); + if (base == MAP_FAILED) + { + NSFW_LOGERR("Map failed, path:'%s' size:%lu, errno=%d", + share->path, share->size, errno); + (void) nsfw_base_close(fd); + return -1; + } + else if (hint && hint != MAP_FAILED && hint != base) + { + NSFW_LOGERR + ("Map address failed, path:'%s' hint:%p size:%lu, base:%p", + share->path, hint, share->size, base); + (void) munmap(base, share->size); + (void) nsfw_base_close(fd); + return -1; + } + + share->base = base; + + NSFW_LOGINF("Share memory created, size:%lu, base=%p", share->size, base); + + (void) nsfw_base_close(fd); + return 0; +} + +int dmm_huge_delete(struct dmm_share *share) +{ + (void) munmap(share->base, share->size); + (void) unlink(share->path); + + return 0; +} + +int dmm_huge_attach(struct dmm_share *share) +{ + int fd; + void *base; + + NSFW_LOGINF("Start attach, share:%p" + " {type:%d pid:%d base:%p size:%lu path:'%s'}", + share, share->type, share->pid, + share->base, share->size, share->path); + + if (share->type != DMM_SHARE_HUGE) + { + NSFW_LOGERR("Type error, type:%d", share->type); + return -1; + } + + char *real_path = realpath(share->path, NULL); + if (NULL == real_path) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + return -1; + } + fd = open(real_path, O_RDWR); + if (fd < 0) + { + NSFW_LOGERR("Open file failed, path:'%s', errno=%d", + share->path, errno); + (void) free(real_path); + return -1; + } + + if (share->size <= 0) + { + share->size = dmm_file_size(fd); + if (share->size == 0) + { + NSFW_LOGERR("No file size '%s'", share->path); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + } + + base = mmap(share->base, share->size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (base == MAP_FAILED) + { + NSFW_LOGERR("mmap failed, path:'%s' base:%p size:%lu, errno=%d", + share->path, share->base, share->size, errno); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + + if (NULL == share->base) + { + share->base = base; + } + else if (base != share->base) + { + NSFW_LOGERR("mmap address error, path:'%s' share->base:%p, base:%p", + share->path, share->base, base); + (void) munmap(base, share->size); + (void) nsfw_base_close(fd); + (void) free(real_path); + return -1; + } + + NSFW_LOGINF("Memory attached, base=%p", base); + + (void) nsfw_base_close(fd); + (void) free(real_path); + return 0; +} + +int dmm_huge_detach(struct dmm_share *share) +{ + (void) munmap(share->base, share->size); + + return 0; +} diff --git a/src/framework/mem/basic_mem/dmm_memory.c b/src/framework/mem/basic_mem/dmm_memory.c new file mode 100644 index 0000000..affa0f6 --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_memory.c @@ -0,0 +1,284 @@ +/* +* +* 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 <stdlib.h> + +#include "types.h" +#include "dmm_config.h" +#include "dmm_memory.h" +#include "dmm_group.h" + +#include "nsfw_init_api.h" +#include "nsfw_mgr_com_api.h" +#include "nstack_log.h" +#include "nsfw_mem_api.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; + 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; + } + + base_seg = main_seg; + + 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) + { + NSFW_LOGERR + ("share attach failed, type:%d pid:%d base:%p size:%lu path:%s", + main_share->type, main_share->pid, main_share->base, + main_share->size, main_share->path); + return -1; + } + + main_seg = dmm_seg_attach(main_share->base, main_share->size); + if (!main_seg) + { + NSFW_LOGERR("segment attach failed, base:%p size:%lu", + main_share->base, main_share->size); + return -1; + } + + /* now share main process share-memory */ + base_seg = main_seg; + } + else + { + base_share.type = DMM_SHARE_TYPE; + base_share.size = 128 * 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; +} + +void dmm_share_destroy() +{ + (void) dmm_share_delete(&base_share); + return; +} + +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; +} + +struct dmm_ring *dmm_create_ring(int num, int flag, + const char name[DMM_MEM_NAME_SIZE]) +{ + struct dmm_ring *ring; + const size_t bufsize = dmm_ring_bufsize(num); + + dmm_lock_map(); + + ring = dmm_map(bufsize, name); + + if (ring) + { + if (0 != dmm_ring_init(ring, num, 0, flag, NSFW_SHMEM)) + { + (void) dmm_unmap(ring); + ring = NULL; + } + } + + dmm_unlock_map(); + + return ring; +} + +struct dmm_ring *dmm_attach_ring(const char name[DMM_MEM_NAME_SIZE]) +{ + return (struct dmm_ring *) dmm_lookup(name); +} + +struct dmm_ring *dmm_malloc_ring(int num, int flag) +{ + const size_t size = dmm_ring_bufsize(num); + if (0 == size) + { + return NULL; + } + struct dmm_ring *ring = malloc(size); + + if (!ring) + return NULL; + + if (0 != dmm_ring_init(ring, num, 0, flag, NSFW_NSHMEM)) + { + free(ring); + return NULL; + } + + return ring; +} + +struct dmm_ring *dmm_create_pool(size_t elt_size, int num, int flag, + const char name[DMM_MEM_NAME_SIZE]) +{ + struct dmm_ring *pool; + const size_t pool_size = dmm_pool_bufsize(num, elt_size); + + dmm_lock_map(); + + pool = dmm_map(pool_size, name); + + if (pool) + { + if (0 != dmm_pool_init(pool, elt_size, num, flag, NSFW_SHMEM)) + { + (void) dmm_unmap(pool); + pool = NULL; + } + } + + dmm_unlock_map(); + + return pool; +} + +struct dmm_ring *dmm_attach_pool(const char name[DMM_MEM_NAME_SIZE]) +{ + return (struct dmm_ring *) dmm_lookup(name); +} + +struct dmm_ring *dmm_malloc_pool(size_t elt_size, int num, int flag) +{ + const size_t size = dmm_pool_bufsize(num, elt_size); + + if (0 == size) + { + return NULL; + } + struct dmm_ring *pool = malloc(size); + + if (!pool) + { + return NULL; + } + + if (0 != dmm_pool_init(pool, elt_size, num, flag, NSFW_NSHMEM)) + { + free(pool); + return NULL; + } + + return pool; +} + +int dmm_mem_module_init(void *param) +{ + int ret; + const u32 proc_type = (u32) ((long) param); + + NSFW_LOGINF("dmm mem module init]type=%u", proc_type); + + switch (proc_type) + { + case NSFW_PROC_MAIN: + ret = dmm_mem_main_init(); + break; + case NSFW_PROC_NULL: + ret = 0; + break; + default: + ret = dmm_mem_app_init(); + break; + } + + return ret; +} + +/* *INDENT-OFF* */ +//NSFW_MODULE_NAME (DMM_MEMORY_MODULE) +//NSFW_MODULE_PRIORITY (10) +//NSFW_MODULE_INIT (dmm_mem_module_init) +/* *INDENT-ON* */ diff --git a/src/framework/mem/basic_mem/dmm_memory.h b/src/framework/mem/basic_mem/dmm_memory.h new file mode 100644 index 0000000..6fc6a24 --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_memory.h @@ -0,0 +1,126 @@ +/* +* +* 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" +#include "dmm_ring.h" +#include "nstack_securec.h" + +#define DMM_MEMORY_MODULE "DMM_MEMORY_MODULE" + +extern struct dmm_segment *main_seg; +extern struct dmm_segment *base_seg; + +inline static void dmm_lock_map() +{ + dmm_seg_lock(base_seg); +} + +inline static void dmm_unlock_map() +{ + dmm_seg_unlock(base_seg); +} + +inline static int dmm_unmap(void *mem) +{ + return dmm_mem_unmap(base_seg, mem); +} + +inline static void *dmm_locked_map(size_t size, + const char name[DMM_MEM_NAME_SIZE]) +{ + void *mem; + dmm_lock_map(); + mem = dmm_mem_map(base_seg, size, name); + dmm_unlock_map(); + return mem; +} + +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_s(name, DMM_MEM_NAME_SIZE, DMM_MEM_NAME_SIZE - 1, 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_s(name, DMM_MEM_NAME_SIZE, DMM_MEM_NAME_SIZE - 1, name_fmt, + ap); + va_end(ap); + + if (len >= DMM_MEM_NAME_SIZE) + return NULL; + + return dmm_mem_lookup(base_seg, name); +} + +int dmm_mem_main_init(); +int dmm_mem_main_exit(); +int dmm_mem_app_init(); +int dmm_mem_app_exit(); + +struct dmm_ring *dmm_create_ring(int num, int flag, + const char name[DMM_MEM_NAME_SIZE]); + +struct dmm_ring *dmm_attach_ring(const char name[DMM_MEM_NAME_SIZE]); + +struct dmm_ring *dmm_malloc_ring(int num, int flag); + +struct dmm_ring *dmm_create_pool(size_t elt_size, int num, int flag, + const char name[DMM_MEM_NAME_SIZE]); + +struct dmm_ring *dmm_attach_pool(const char name[DMM_MEM_NAME_SIZE]); + +/* allocate pool from heap */ +struct dmm_ring *dmm_malloc_pool(size_t elt_size, int num, int flag); + +int dmm_mem_module_init(void *param); + +void dmm_share_destroy(); + +#endif /* _DMM_MEMORY_H_ */ diff --git a/src/framework/mem/basic_mem/dmm_segment.c b/src/framework/mem/basic_mem/dmm_segment.c new file mode 100644 index 0000000..3b92a55 --- /dev/null +++ b/src/framework/mem/basic_mem/dmm_segment.c @@ -0,0 +1,536 @@ +/* +* +* 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 <limits.h> +#include "dmm_common.h" +#include "dmm_rwlock.h" +#include "dmm_segment.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +#define BLOCK_SIZE 64 /* cache line size */ +#define BLOCK_MASK (BLOCK_SIZE - 1) + +#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__) + +typedef struct +{ + char _dummy_block_size[BLOCK_SIZE]; +} _dmm_packed __BLOCK; + +/* +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]; +} _dmm_cache_aligned section_t; + +/* dmm_section struct hold blocks number */ +#define SECTION_HOLD ((sizeof(struct dmm_section) + (BLOCK_SIZE - 1)) / BLOCK_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) + { + return SECTION_HOLD + (size + BLOCK_MASK) / BLOCK_SIZE; + } + + return SECTION_HOLD + 1; /* if size is 0, then alloc 1 block */ +} + +inline static int SEC_REL(const section_t * base, const section_t * sec) +{ + return (__BLOCK *) sec - (__BLOCK *) base; +} + +section_t *REL_SEC(section_t * base, int rel) +{ + return (section_t *) ((__BLOCK *) 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 REL_SEC(sec, sec->less_rel); +} + +inline static section_t *MORE_SEC(section_t * sec) +{ + return REL_SEC(sec, sec->more_rel); +} + +inline static section_t *PREV_SEC(section_t * sec) +{ + return REL_SEC(sec, sec->prev_rel); +} + +inline static section_t *NEXT_SEC(section_t * sec) +{ + return REL_SEC(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 & BLOCK_MASK) + 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 from pos section's 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 section */ + pos->free_num -= num; + + less = LESS_SEC(pos); + more = MORE_SEC(pos); + + /* remove from 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_lock(struct dmm_segment *seg) +{ + dmm_write_lock(&seg->lock); +} + +void dmm_seg_unlock(struct dmm_segment *seg) +{ + dmm_write_unlock(&seg->lock); +} + +void dmm_seg_dump(struct dmm_segment *seg) +{ + section_t *sec; + + dmm_read_lock(&seg->lock); + + NSFW_LOGINF + ("---- segment:%p base:%p size:%lu ---- BS:%u SS:%lu SH:%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, BLOCK_SIZE, sizeof(struct dmm_section), + SECTION_HOLD, 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) * (BLOCK_SIZE * 100) / seg->size); + + NSFW_LOGINF("----------------------------------------\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) + { + NSFW_LOGINF("%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); + } + + NSFW_LOGINF("----------------------------------------\n" + "%18s %9s %9s\n", "FREE-ORDER", "section", "free_num"); + for (sec = MORE_SEC(seg->last); sec != seg->last; sec = MORE_SEC(sec)) + { + NSFW_LOGINF("%18p %9d %9d\n", + sec, SEC_INDEX(seg, sec), sec->free_num); + } + + NSFW_LOGINF("----------------------------------------\n"); + + dmm_read_unlock(&seg->lock); + +} + +inline static int align_section(void *base, size_t size, section_t ** first) +{ + const int SEG_NUM = CALC_NUM(sizeof(struct dmm_segment)); + + const long align = (long) base; + const long addr = (align + BLOCK_MASK) & (~BLOCK_MASK); + const size_t total = (size - (addr - align)) / BLOCK_SIZE; + + if (total > INT_MAX) + return -1; + if (total < SEG_NUM + SECTION_HOLD) /* first+segment + last */ + return -1; + + *first = (section_t *) addr; + return (int) total; +} + +struct dmm_segment *dmm_seg_create(void *base, size_t size) +{ + section_t *first, *last; + struct dmm_segment *seg; + const int total = align_section(base, size, &first); + const int SEG_NUM = CALC_NUM(sizeof(struct dmm_segment)); + + if (total <= 0) + return NULL; + + last = first + (total - SECTION_HOLD); + + /* first section */ + first->prev_rel = 0; + first->used_num = SEG_NUM; + first->req_size = sizeof(struct dmm_segment); + first->free_num = total - (SEG_NUM + SECTION_HOLD); + first->less_rel = SEC_REL(first, last); + first->more_rel = SEC_REL(first, last); + first->name[0] = 0; + (void) strncpy_s(&first->name[1], DMM_MEM_NAME_SIZE, 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_s(&last->name[1], DMM_MEM_NAME_SIZE, 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; /* first and tail */ + seg->used_size = sizeof(struct dmm_segment); + seg->used_num = first->used_num + SECTION_HOLD; + + return seg; +} + +struct dmm_segment *dmm_seg_attach(void *base, size_t size) +{ + section_t *first, *last; + struct dmm_segment *seg; + const int total = align_section(base, size, &first); + + if (total <= 0) + return NULL; + + last = first + (total - SECTION_HOLD); + 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_seg_lock(seg); + sec = mem_alloc(seg, size); + dmm_seg_unlock(seg); + + 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_seg_lock(seg); + mem_free(seg, ((section_t *) mem) - 1); + dmm_seg_unlock(seg); + + 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; + + sec = mem_lookup(seg, name); + if (sec) + { + MEM_ERR("Map '%s' exist", name); + mem = NULL; + } + else if (NULL != (sec = mem_alloc(seg, size))) + { + (void) strncpy_s(sec->name, DMM_MEM_NAME_SIZE, name, + sizeof(sec->name) - 1); + mem = sec + 1; + } + else + { + MEM_ERR("alloc '%s' failed for size %lu", name, size); + mem = NULL; + } + + return mem; +} + +int dmm_mem_unmap(struct dmm_segment *seg, void *mem) +{ + if (CHECK_ADDR(seg, mem)) + { + MEM_ERR("Invalid address:%p", mem); + return -1; + } + + mem_free(seg, ((section_t *) mem) - 1); + + return 0; +} diff --git a/src/framework/mem/dmm_segment.h b/src/framework/mem/basic_mem/dmm_segment.h index 135f347..f8b3dca 100644 --- a/src/framework/mem/dmm_segment.h +++ b/src/framework/mem/basic_mem/dmm_segment.h @@ -13,23 +13,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _DMM_SEGMENT_H_ #define _DMM_SEGMENT_H_ +#include <stdlib.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); +struct dmm_segment; + +void dmm_seg_lock(struct dmm_segment *seg); +void dmm_seg_unlock(struct dmm_segment *seg); + +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_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]); +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, void *mem); #endif /* #ifndef _DMM_SEGMENT_H_ */ diff --git a/src/framework/mem/dmm_share.h b/src/framework/mem/basic_mem/dmm_share.h index 0d0ff8f..8db19fc 100644 --- a/src/framework/mem/dmm_share.h +++ b/src/framework/mem/basic_mem/dmm_share.h @@ -13,43 +13,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _DMM_SHARE_H_ #define _DMM_SHARE_H_ +#include <sys/types.h> +#include <unistd.h> +#include <stdlib.h> + #define DMM_SHARE_PATH_MAX 100 enum dmm_share_type { - DMM_SHARE_HEAP, - DMM_SHARE_FSHM, - DMM_SHARE_HUGE, + DMM_SHARE_HEAP, + DMM_SHARE_FSHM, + DMM_SHARE_HUGE, - DMM_SHARE_ANY = -1 + 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 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_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_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); +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) \ ({ \ @@ -75,38 +80,34 @@ int dmm_huge_detach (struct dmm_share *share); input: share->type, share->size, share->pid output: share->base, share->path */ -inline static int -dmm_share_create (struct dmm_share *share) +inline static int dmm_share_create(struct dmm_share *share) { - return DMM_SHARE_DISPATCH (share, create); + 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) +inline static int dmm_share_delete(struct dmm_share *share) { - return DMM_SHARE_DISPATCH (share, delete); + 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) +inline static int dmm_share_attach(struct dmm_share *share) { - return DMM_SHARE_DISPATCH (share, attach); + 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) +inline static int dmm_share_detach(struct dmm_share *share) { - return DMM_SHARE_DISPATCH (share, detach); + return DMM_SHARE_DISPATCH(share, detach); } #undef DMM_SHARE_DISPATCH diff --git a/src/framework/mem/dmm_fshm.c b/src/framework/mem/dmm_fshm.c deleted file mode 100644 index 605c728..0000000 --- a/src/framework/mem/dmm_fshm.c +++ /dev/null @@ -1,144 +0,0 @@ -/* -* -* 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 deleted file mode 100644 index 35e6100..0000000 --- a/src/framework/mem/dmm_group.c +++ /dev/null @@ -1,185 +0,0 @@ -/* -* -* 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_heap.c b/src/framework/mem/dmm_heap.c deleted file mode 100644 index bc966ef..0000000 --- a/src/framework/mem/dmm_heap.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -* -* 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 deleted file mode 100644 index 735c507..0000000 --- a/src/framework/mem/dmm_huge.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -* -* 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 deleted file mode 100644 index 0352432..0000000 --- a/src/framework/mem/dmm_memory.c +++ /dev/null @@ -1,133 +0,0 @@ -/* -* -* 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 deleted file mode 100644 index 2fac118..0000000 --- a/src/framework/mem/dmm_memory.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* -* 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_nshmem_mng.c b/src/framework/mem/dmm_nshmem_mng.c new file mode 100644 index 0000000..515975c --- /dev/null +++ b/src/framework/mem/dmm_nshmem_mng.c @@ -0,0 +1,126 @@ +/* +* +* 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 "nsfw_mem_api.h" +#include "dmm_ring.h" +#include "dmm_memory.h" +#include "dmm_nshmem_mng.h" + +i32 dmm_nshmem_init(nsfw_mem_para * para) +{ + return NSFW_MEM_OK; +} + +/* + * memory destory + */ +void dmm_nshmem_destory(void) +{ + return; +} + +mzone_handle dmm_nshmem_create(nsfw_mem_zone * pinfo) +{ + if (!pinfo->lenth) + { + return NULL; + } + return calloc(1, pinfo->lenth); +} + +mring_handle dmm_nshmem_spcreate(nsfw_mem_sppool * pmpinfo) +{ + struct dmm_ring *ring; + + ring = + dmm_malloc_pool(pmpinfo->useltsize, (int) pmpinfo->usnum, + DMM_RING_INIT_MPMC); + if (ring == NULL) + { + NSSOC_LOGERR("nshmem sp create faild num:%u eltsize:%u", + pmpinfo->usnum, pmpinfo->useltsize); + return NULL; + } + return (mring_handle) (ring); +} + +i32 dmm_nshmem_sprelease(nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +mring_handle dmm_nshmem_ringcreate(nsfw_mem_mring * pringinfo) +{ + struct dmm_ring *ring = NULL; + + ring = dmm_malloc_ring((int) pringinfo->usnum, DMM_RING_INIT_MPMC); + if (ring == NULL) + { + NSSOC_LOGERR("nshmem ring create faild num:%u", pringinfo->usnum); + return NULL; + } + return (mring_handle) (ring); +} + +i32 dmm_nshmem_ringrelease(nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +ssize_t dmm_nshmem_sppool_statics(mring_handle sppool) +{ + size_t size = 0; + struct dmm_ring *ring = (struct dmm_ring *) sppool; + if (ring == NULL) + { + NSSOC_LOGERR("nshmem sppool stat para errer"); + return 0; + } + + size = dmm_ring_bufsize(ring->size - 1); + size = size + dmm_pool_arraysize((ring->size - 1), ring->eltsize); + + return size; +} + +ssize_t dmm_nshmem_ring_statics(mring_handle handle) +{ + struct dmm_ring *ring = (struct dmm_ring *) handle; + if (ring == NULL) + { + NSSOC_LOGERR("nshmem ring stat para errer"); + return 0; + } + + return dmm_ring_bufsize(ring->size - 1); +} + +ssize_t dmm_nshmem_stactic(void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return -1; + case NSFW_MEM_SPOOL: + return dmm_nshmem_sppool_statics(handle); + case NSFW_MEM_RING: + return dmm_nshmem_ring_statics(handle); + default: + break; + } + return -1; +} diff --git a/src/framework/mem/dmm_nshmem_mng.h b/src/framework/mem/dmm_nshmem_mng.h new file mode 100644 index 0000000..d25c365 --- /dev/null +++ b/src/framework/mem/dmm_nshmem_mng.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_NSHMEM_MNG_H +#define _DMM_NSHMEM_MNG_H + +#include "nsfw_mem_api.h" +#include "types.h" +#include <unistd.h> + +i32 dmm_nshmem_init(nsfw_mem_para * para); +void dmm_nshmem_destory(void); +mzone_handle dmm_nshmem_create(nsfw_mem_zone * pinfo); +mring_handle dmm_nshmem_spcreate(nsfw_mem_sppool * pmpinfo); +i32 dmm_nshmem_sprelease(nsfw_mem_name * pname); +mring_handle dmm_nshmem_ringcreate(nsfw_mem_mring * pringinfo); +i32 dmm_nshmem_ringrelease(nsfw_mem_name * pname); +ssize_t dmm_nshmem_sppool_statics(mring_handle sppool); +ssize_t dmm_nshmem_ring_statics(mring_handle handle); +ssize_t dmm_nshmem_stactic(void *handle, nsfw_mem_struct_type type); + +#endif diff --git a/src/framework/mem/dmm_segment.c b/src/framework/mem/dmm_segment.c deleted file mode 100644 index 6358506..0000000 --- a/src/framework/mem/dmm_segment.c +++ /dev/null @@ -1,543 +0,0 @@ -/* -* -* 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_shmem_mng.c b/src/framework/mem/dmm_shmem_mng.c new file mode 100644 index 0000000..7dee6dc --- /dev/null +++ b/src/framework/mem/dmm_shmem_mng.c @@ -0,0 +1,287 @@ +/* +* +* 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 "dmm_memory.h" +#include "dmm_ring.h" +#include "dmm_shmem_mng.h" +#include "nstack_securec.h" + +/* + *share memory mng module init + * + */ +i32 dmm_shmem_init(nsfw_mem_para * para) +{ + i32 iret = NSFW_MEM_OK; + + NSSOC_LOGINF("shmem init begin"); + + if (NSFW_PROC_APP != para->enflag) + { + NSSOC_LOGERR("shmem init with error proc type"); + return NSFW_MEM_ERR; + } + else + { + iret = dmm_mem_module_init((void *) ((u64) (para->enflag))); + } + + if (NSFW_MEM_OK != iret) + { + NSSOC_LOGERR("shmem init fail]ret=0x%x", iret); + return NSFW_MEM_RTP_FAIL; + } + + NSRTP_LOGINF("shmem init end]flag=%d", para->enflag); + return NSFW_MEM_OK; +} + +/* + *module destroy + */ +void dmm_shmem_destroy(void) +{ + (void) dmm_share_destroy(); + + return; +} + +/* + * create a shared memory + * nsfw_mem_zone::stname memory name + * nsfw_mem_zone::isize + */ +mzone_handle dmm_shmem_create(nsfw_mem_zone * pinfo) +{ + return dmm_locked_map(pinfo->lenth, pinfo->stname.aname); +} + +/* + *create some memory + *inum must be equal iarray_num + */ +i32 dmm_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + return NSFW_MEM_OK; +} + +mzone_handle dmm_shmem_lookup(nsfw_mem_name * pname) +{ + return dmm_lookup(pname->aname); +} + +i32 dmm_shmem_release(nsfw_mem_name * pname) +{ + void *ptr = NULL; + + ptr = dmm_lookup(pname->aname); + if (ptr == NULL) + { + NSSOC_LOGERR("shmem[%s] release fail", pname->aname); + return NSFW_MEM_ERR; + } + + return dmm_unmap(ptr); +} + +mpool_handle dmm_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo) +{ + return NULL; +} + +/* + *create some mbuf pools + */ +i32 dmm_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + return 0; +} + +mpool_handle dmm_shmem_mbfmplookup(nsfw_mem_name * pmbfname) +{ + return NULL; +} + +i32 dmm_shmem_mbfmprelease(nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +mring_handle dmm_shmem_spcreate(nsfw_mem_sppool * pmpinfo) +{ + struct dmm_ring *ring; + + ring = + dmm_create_pool(pmpinfo->useltsize, (int) pmpinfo->usnum, + DMM_RING_INIT_MPMC, pmpinfo->stname.aname); + if (ring == NULL) + { + NSSOC_LOGERR("shmem sp create faild num:%u eltsize:%u", + pmpinfo->usnum, pmpinfo->useltsize); + return NULL; + } + + return (mring_handle) (ring); +} + +i32 dmm_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + return NSFW_MEM_OK; +} + +i32 dmm_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + i32 i = 0; + size_t eltsize = 0; + mring_handle ring = NULL; + size_t ring_size = 0; + nsfw_mem_sppool mpinfo; + char *pool = NULL; + + eltsize = dmm_ring_bufsize((int) prpoolinfo->usnum); + mpinfo.useltsize = eltsize; + mpinfo.usnum = iringnum; + (void) strncpy_s(mpinfo.stname.aname, sizeof(mpinfo.stname.aname), + prpoolinfo->stname.aname, + sizeof(mpinfo.stname.aname) - 1); + + ring = dmm_shmem_spcreate(&mpinfo); + if (ring == NULL) + { + NSSOC_LOGERR("shmem spring create faild num:%u eltsize:%u", + mpinfo.usnum, mpinfo.useltsize); + return NSFW_MEM_ERR; + } + + ring_size = dmm_ring_bufsize(iringnum); + pool = (char *) ring + ring_size; + for (i = 0; i < iringnum; i++) + { + pringhandle_array[i] = pool; + if (0 != + dmm_ring_init((struct dmm_ring *) pringhandle_array[i], + (int) prpoolinfo->usnum, eltsize, + DMM_RING_INIT_MPMC, NSFW_SHMEM)) + { + NSSOC_LOGERR("ring init faild index:%d", i); + return NSFW_MEM_ERR; + } + pool = pool + eltsize; + } + + return NSFW_MEM_OK; +} + +i32 dmm_shmem_sprelease(nsfw_mem_name * pname) +{ + return dmm_shmem_release(pname); +} + +mring_handle dmm_shmem_sp_lookup(nsfw_mem_name * pname) +{ + return dmm_lookup(pname->aname); +} + +mring_handle dmm_shmem_ringcreate(nsfw_mem_mring * pringinfo) +{ + struct dmm_ring *ring; + + ring = + dmm_create_ring((int) pringinfo->usnum, DMM_RING_INIT_MPMC, + pringinfo->stname.aname); + + return (mring_handle) (ring); +} + +mring_handle dmm_shmem_ring_lookup(nsfw_mem_name * pname) +{ + return dmm_lookup(pname->aname); +} + +i32 dmm_shmem_ringrelease(nsfw_mem_name * pname) +{ + return dmm_shmem_release(pname); +} + +size_t dmm_shmem_sppool_statics(mring_handle sppool) +{ + size_t size = 0; + struct dmm_ring *ring = (struct dmm_ring *) sppool; + if (ring == NULL) + { + NSSOC_LOGERR("shmem sppool stat para errer"); + return 0; + } + + size = dmm_ring_bufsize(ring->size - 1); + size = size + dmm_pool_arraysize((ring->size - 1), ring->eltsize); + + return size; +} + +size_t dmm_shmem_ring_statics(mring_handle handle) +{ + struct dmm_ring *ring = (struct dmm_ring *) handle; + if (ring == NULL) + { + NSSOC_LOGERR("shmem ring stat para errer"); + return 0; + } + + return dmm_ring_bufsize(ring->size - 1); +} + +ssize_t dmm_shmem_stactic(void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return 0; + case NSFW_MEM_SPOOL: + return dmm_shmem_sppool_statics(handle); + case NSFW_MEM_RING: + return dmm_shmem_ring_statics(handle); + default: + break; + } + return -1; +} + +i32 dmm_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + return 0; +} + +void *dmm_shmem_shddr_to_laddr(void *addr) +{ + return addr; +} + +uint64_t dmm_shmem_laddr_to_shddr(void *addr) +{ + return (uint64_t) (addr); +} + +int dmm_attach_core_id(nsfw_mem_name * name) +{ + return 0; +} diff --git a/src/framework/mem/dmm_shmem_mng.h b/src/framework/mem/dmm_shmem_mng.h new file mode 100644 index 0000000..c267858 --- /dev/null +++ b/src/framework/mem/dmm_shmem_mng.h @@ -0,0 +1,54 @@ +/* +* +* 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_SHMEM_MNG_H +#define _DMM_SHMEM_MNG_H + +#include <unistd.h> +#include <stdlib.h> +#include "nsfw_mem_api.h" +#include "types.h" + +i32 dmm_shmem_init(nsfw_mem_para * para); +void dmm_shmem_destroy(void); +mzone_handle dmm_shmem_create(nsfw_mem_zone * pinfo); +i32 dmm_shmem_createv(nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); +mzone_handle dmm_shmem_lookup(nsfw_mem_name * pname); +i32 dmm_shmem_release(nsfw_mem_name * pname); +mpool_handle dmm_shmem_mbfmpcreate(nsfw_mem_mbfpool * pbufinfo); +i32 dmm_shmem_mbfmpcreatev(nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num); +mpool_handle dmm_shmem_mbfmplookup(nsfw_mem_name * pmbfname); +i32 dmm_shmem_mbfmprelease(nsfw_mem_name * pname); +i32 dmm_shmem_spcreatev(nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num); +i32 dmm_shmem_sp_ringcreate(nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum); +i32 dmm_shmem_sprelease(nsfw_mem_name * pname); +mring_handle dmm_shmem_sp_lookup(nsfw_mem_name * pname); +mring_handle dmm_shmem_ringcreate(nsfw_mem_mring * pringinfo); +mring_handle dmm_shmem_ring_lookup(nsfw_mem_name * pname); +i32 dmm_shmem_ringrelease(nsfw_mem_name * pname); +size_t dmm_shmem_sppool_statics(mring_handle sppool); +size_t dmm_shmem_ring_statics(mring_handle handle); +ssize_t dmm_shmem_stactic(void *handle, nsfw_mem_struct_type type); +i32 dmm_shmem_sp_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +void *dmm_shmem_shddr_to_laddr(void *addr); +uint64_t dmm_shmem_laddr_to_shddr(void *addr); +int dmm_attach_core_id(nsfw_mem_name * name); +#endif diff --git a/src/framework/mem/nsfw_mem_api.c b/src/framework/mem/nsfw_mem_api.c new file mode 100644 index 0000000..7517faa --- /dev/null +++ b/src/framework/mem/nsfw_mem_api.c @@ -0,0 +1,932 @@ +/* +* +* 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 <dlfcn.h> +#include "nsfw_mem_api.h" +#include "nstack_securec.h" +#include "nsfw_ring_data.h" +#include "nsfw_init_api.h" + +#define MEM_OP_CALL_OK_RET(mtype, fun, para) { \ + if (g_nsfw_mem_ops[mtype].stmemop->fun) \ + { \ + return g_nsfw_mem_ops[mtype].stmemop->fun para; \ + } \ + } +#define NSFW_MEM_NAME_CHECK_RET_ERR(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]desc=%s,pname=%p,mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_NAME_CHECK_RET_NULL(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]desc=%s,pname=%p,mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NULL; \ + } \ + } + +#define NSFW_MEM_RING_CHECK_RET(pringinfo, pringhandle_array, iringnum) {\ + if ((NULL == pringinfo) || (NULL == pringhandle_array) || (pringinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]pringinfo=%p,iringnum=%d,pringhandle_array=%p,mtype=%d", \ + pringinfo, iringnum, pringhandle_array, pringinfo ? pringinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_RINGV_CHECK_RET(pmpinfo, inum, pringhandle_array, iarray_num) { \ + if ((NULL == pmpinfo) || (NULL == pringhandle_array) \ + || (inum != iarray_num) || (inum <= 0) || (pmpinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSRTP_LOGERR("input para error]pmpinfo=%p,inum=%d,pringhandle_array=%p,iarray_num=%d,entype=%d", \ + pmpinfo, inum, pringhandle_array, iarray_num, pmpinfo ? pmpinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#ifndef FOR_ATTACH_COREID +/* + * attach core id when malloc resource + */ +static int nsfw_attach_core_id(nsfw_mem_name * name) +{ + MEM_OP_CALL_OK_RET(NSFW_SHMEM, mem_ops_attach_core_id, (name)); + NSRTP_LOGINF + ("nsfw_attach_core_id failed]field mem_ops_attach_core_id is NULL"); + return -1; +} +#endif + +i32 nsfw_mem_init(void *para) +{ + nsfw_mem_para *ptempara = NULL; + i32 iret = NSFW_MEM_OK; + i32 icount = 0; + i32 iindex = 0; + + if (NULL == para) + { + NSRTP_LOGERR("ns mem init input error"); + return NSFW_MEM_ERR; + } + + ptempara = (nsfw_mem_para *) para; + + if (ptempara->enflag >= NSFW_PROC_MAX) + { + NSRTP_LOGERR("ns mem init input enflag invalid]enflag=%d", + ptempara->enflag); + return NSFW_MEM_ERR; + } + + NSRTP_LOGINF("ns mem init begin]enflag=%d,iargsnum=%d", ptempara->enflag, + ptempara->iargsnum); + + for (iindex = 0; iindex < ptempara->iargsnum; iindex++) + { + NSRTP_LOGINF("%s", ptempara->pargs[iindex]); + } + + for (icount = 0; icount < g_mem_type_num; icount++) + { + if ((NULL != g_nsfw_mem_ops[icount].stmemop) + && (NULL != g_nsfw_mem_ops[icount].stmemop->mem_ops_init)) + { + iret = g_nsfw_mem_ops[icount].stmemop->mem_ops_init(ptempara); + + if (NSFW_MEM_OK != iret) + { + NSRTP_LOGERR("mem init failed]index=%d,memtype=%d", icount, + g_nsfw_mem_ops[icount].entype); + break; + } + } + } + + /* if some module init fail, destory the modules that succeeded */ + if (icount < g_mem_type_num) + { + for (iindex = 0; iindex < icount; iindex++) + { + if (g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy) + { + g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy(); + } + } + + return iret; /* return errcode to caller */ + } + + NSRTP_LOGINF("mem init end"); + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_create +* Description : create a block memory with name +* nsfw_mem_zone::stname +* nsfw_mem_zone::isize +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pinfo +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +*****************************************************************************/ +mzone_handle nsfw_mem_zone_create(nsfw_mem_zone * pinfo) +{ + if ((NULL == pinfo) || (pinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR("zone create input para error] pinfo=%p, mtype=%d", + pinfo, pinfo ? pinfo->stname.entype : (-1)); + return NULL; + } + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(&pinfo->stname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pinfo->stname.entype, mem_ops_zone_creae, (pinfo)); + NSRTP_LOGINF("mem create fail] memtype=%d, name=%s, size=%zu", + pinfo->stname.entype, pinfo->stname.aname, pinfo->lenth); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_createv +* Description : create some memory blocks +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pmeminfo +* i32 inum +* mzone_handle* paddr_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_zone_createv(nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + if ((NULL == pmeminfo) || (NULL == paddr_array) + || (inum != iarray_num) || (inum <= 0) + || (pmeminfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR + ("input para error] pmeminfo=%p, inum=%d, paddr_array=%p, iarray_num=%d, mtype=%d", + pmeminfo, inum, paddr_array, iarray_num, + pmeminfo ? pmeminfo[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + +#ifndef FOR_ATTACH_COREID + i32 i; + for (i = 0; i < inum; ++i) + { + if (nsfw_attach_core_id(&pmeminfo[i].stname) != 0) + { + return NSFW_MEM_ERR; + } + } +#endif + + MEM_OP_CALL_OK_RET(pmeminfo[0].stname.entype, mem_ops_zone_createv, + (pmeminfo, inum, paddr_array, iarray_num)); + NSRTP_LOGINF("mem create fail] memtype=%d", pmeminfo[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_lookup +* Description : look up a memory +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by daemon-stack, +* end with none created by nStackMaster, and end with _<pid> created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by daemon-stack and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +*****************************************************************************/ +mzone_handle nsfw_mem_zone_lookup(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL(pname, "mem zone look up"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_zone_lookup, (pname)); + NSRTP_LOGERR("mem lookup fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NULL; +} + +i32 nsfw_mem_zone_release(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR(pname, "mem zone release"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NSFW_MEM_ERR; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_mzone_release, (pname)); + NSRTP_LOGERR("mem release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_create +* Description : create a mbuf pool +* Input : nsfw_mem_mbfpool* pbufinfo +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +*****************************************************************************/ +mpool_handle nsfw_mem_mbfmp_create(nsfw_mem_mbfpool * pbufinfo) +{ + if ((NULL == pbufinfo) || (pbufinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR("input para error] pbufinfo=%p, mtype=%d", pbufinfo, + pbufinfo ? pbufinfo->stname.entype : (-1)); + return NULL; + } + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(&pbufinfo->stname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pbufinfo->stname.entype, mem_ops_mbfmp_create, + (pbufinfo)); + NSRTP_LOGERR("mbufmp create fail] memtype=%d, name=%s ", + pbufinfo->stname.entype, pbufinfo->stname.aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_createv +* Description : create some mbuf pools +* 1. the name of lenth must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mbfpool* pmbfname +* i32 inum +* mpool_handle* phandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_mbfmp_createv(nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + if ((NULL == pmbfname) || (NULL == phandle_array) + || (inum != iarray_num) || (inum <= 0) + || (pmbfname[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR + ("input para error] pmbfname=%p, inum=%d, phandle_array=%p, iarray_num=%d,entype=%d", + pmbfname, inum, phandle_array, iarray_num, + pmbfname ? pmbfname[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + +#ifndef FOR_ATTACH_COREID + i32 i; + for (i = 0; i < inum; ++i) + { + if (nsfw_attach_core_id(&pmbfname[i].stname) != 0) + { + return NSFW_MEM_ERR; + } + } +#endif + + MEM_OP_CALL_OK_RET(pmbfname[0].stname.entype, mem_ops_mbfmp_createv, + (pmbfname, inum, phandle_array, iarray_num)); + NSRTP_LOGERR("mbufmp createv fail] memtype=%d", + pmbfname[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_lookup +* Description : look up mbuf mpool +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by daemon-stack, +* end with none created by nStackMaster, and end with _<pid> created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by daemon-stack and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pmbfname +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +*****************************************************************************/ +mpool_handle nsfw_mem_mbfmp_lookup(nsfw_mem_name * pmbfname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL(pmbfname, "mbuf pool look up"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pmbfname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pmbfname->entype, mem_ops_mbfmp_lookup, (pmbfname)); + NSRTP_LOGERR("mbufmp lookup fail] memtype=%d, name=%s ", + pmbfname->entype, pmbfname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_release +* Description : release mbuf pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_mbfmp_release(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR(pname, "mbuf mp release"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NSFW_MEM_ERR; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_mbfmp_release, (pname)); + NSRTP_LOGERR("mbfmp release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_create +* Description : create a simple pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_mem_sp_create(nsfw_mem_sppool * pmpinfo) +{ + if ((NULL == pmpinfo) || (pmpinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR("input para error] pmpinfo=%p, mtype=%d", pmpinfo, + pmpinfo ? pmpinfo->stname.entype : (-1)); + return NULL; + } + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(&pmpinfo->stname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pmpinfo->stname.entype, mem_ops_sp_create, (pmpinfo)); + NSRTP_LOGERR("sp create fail] memtype=%d, name=%s ", + pmpinfo->stname.entype, pmpinfo->stname.aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_createv +* Description : create some simple pools one time +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* i32 inum +* mring_handle* pringhandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_sp_createv(nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_MEM_RINGV_CHECK_RET(pmpinfo, inum, pringhandle_array, iarray_num); + +#ifndef FOR_ATTACH_COREID + i32 i; + for (i = 0; i < inum; ++i) + { + if (nsfw_attach_core_id(&pmpinfo[i].stname) != 0) + { + return NSFW_MEM_ERR; + } + } +#endif + + MEM_OP_CALL_OK_RET(pmpinfo[0].stname.entype, mem_ops_sp_createv, + (pmpinfo, inum, pringhandle_array, iarray_num)); + NSRTP_LOGERR("sp createv fail] memtype=%d", pmpinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_ring_create +* Description : create a simple pool with many rings +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mring* pringinfo +* mring_handle* pringhandle_array +* i32 iringnum +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_sp_ring_create(nsfw_mem_mring * pringinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + NSFW_MEM_RING_CHECK_RET(pringinfo, pringhandle_array, iringnum); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(&pringinfo->stname) != 0) + { + return NSFW_MEM_ERR; + } +#endif + + MEM_OP_CALL_OK_RET(pringinfo[0].stname.entype, mem_ops_spring_create, + (pringinfo, pringhandle_array, iringnum)); + NSRTP_LOGERR("mppool spring creat fail] memtype=%d", + pringinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_release +* Description : release a simple mempool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_sp_release(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR(pname, "sp release"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NSFW_MEM_ERR; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_sp_release, (pname)); + NSRTP_LOGERR("sp release fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_lookup +* Description : look up a simpile ring +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by daemon-stack, +* end with none created by nStackMaster, and end with _<pid> created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by daemon-stack and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_mem_sp_lookup(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL(pname, "sp look up"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_sp_lookup, (pname)); + NSRTP_LOGERR("sp lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_create +* Description : create a ring +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. shared memory ring (NSFW_SHMEM) just can put a pointor into the queue, the queue also point to a shared block memory. +* no shared memory ring(NSFW_NSHMEM) is other wise. +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_mem_ring_create(nsfw_mem_mring * pringinfo) +{ + if ((NULL == pringinfo) || (pringinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSRTP_LOGERR("input para error] pmpinfo=%p, mtype=%d", pringinfo, + pringinfo ? pringinfo->stname.entype : (-1)); + return NULL; + } + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(&pringinfo->stname) != 0) + { + NSRTP_LOGERR + ("nsfw_attach_core_id failed] type=%d, owner=%d, name=%s", + pringinfo->stname.entype, pringinfo->stname.enowner, + pringinfo->stname.aname); + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pringinfo->stname.entype, mem_ops_ring_create, + (pringinfo)); + NSRTP_LOGERR("ring create fail] memtype=%d, name=%s ", + pringinfo->stname.entype, pringinfo->stname.aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_lookup +* Description : look up a ring by name +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note: +* 1. when calling any shared memory create inferface, the name of memory end with _0 created by daemon-stack, +* end with none created by nStackMaster, and end with _<pid> created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by daemon-stack and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle nsfw_mem_ring_lookup(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL(pname, "ring lookup"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NULL; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_ring_lookup, (pname)); + NSRTP_LOGERR("ring lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_reset +* Description : reset the number of producer and consumer, also, the +* state of ring reset to empty +* notes : must be called before doing any operations base on the ring +* Input : mring_handle mhandle +* nsfw_mpool_type entype +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void nsfw_mem_ring_reset(mring_handle mhandle, nsfw_mpool_type entype) +{ + u32 loop = 0; + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) mhandle; + + if (!ring) + { + return; + } + + ring->prod.head = 0; + ring->cons.tail = 0; + ring->ringflag = (u8) entype; + + /*init Ring */ + for (loop = 0; loop < ring->size; loop++) + { + /* + for a empty ring, version is the mapping head val - size + so the empty ring's ver is loop-size; + */ + ring->ring[loop].data_s.ver = (loop - ring->size); + ring->ring[loop].data_s.val = 0; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_free_count +* Description : get the free number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +*****************************************************************************/ +u32 nsfw_mem_ring_free_count(mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + u32 using_count = 0; + if (NULL == mhandle) + { + NSRTP_LOGERR("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + + /* avoid multi-thread issue, here we should get cons.tail firstly, get prod.head later + because tail and head is always ++ */ + /* optimize nsfw_mem_ring_using_count(), avoid return abnormal value */ + ttail = temp->cons.tail; + thead = temp->prod.head; + + using_count = thead - ttail; + if (using_count > temp->size) + { + /* nsfw_mem_ring_using_count will return abnormal lagre value */ + using_count = 0; + } + + return temp->size - (using_count); +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_using_count +* Description : get the in using number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +*****************************************************************************/ +u32 nsfw_mem_ring_using_count(mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + u32 using_count = 0; + if (NULL == mhandle) + { + NSRTP_LOGERR("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + /* avoid multi-thread issue, here we should get cons.tail firstly, get prod.head later + because tail and head is always ++ */ + /* optimize nsfw_mem_ring_using_count(), avoid return abnormal value */ + + ttail = temp->cons.tail; + thead = temp->prod.head; + + using_count = thead - ttail; + if (using_count > temp->size) + { + /* nsfw_mem_ring_using_count will return abnormal lagre value */ + using_count = 0; + } + + return using_count; +} + +u32 nsfw_mem_ring_size(mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + + if (NULL == mhandle) + { + NSRTP_LOGERR("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + + return temp->size; +} + +i32 nsfw_mem_ring_release(nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR(pname, "ring release"); + +#ifndef FOR_ATTACH_COREID + if (nsfw_attach_core_id(pname) != 0) + { + return NSFW_MEM_ERR; + } +#endif + + MEM_OP_CALL_OK_RET(pname->entype, mem_ops_ring_release, (pname)); + NSRTP_LOGERR("ring release fail] name=%s, type=%d", pname->aname, + pname->entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_get_len +* Description : statics mbufpool, sppool, ring mem size. +* return: <=0, err happen, >0 mem size +* NSFW_MEM_MZONE: not surport because you already know the lenth when create +* Input : void * handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_mem_get_len(void *handle, nsfw_mem_struct_type type) +{ + if (NULL == handle) + { + NSRTP_LOGERR("input para error] handle=%p", handle); + return -1; + } + if ((NSFW_MEM_SPOOL == type) || (NSFW_MEM_RING == type)) + { + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + if (ring->memtype >= NSFW_MEM_TYPEMAX) + { + NSRTP_LOGERR("invalid ring] ring type=%u ,handle=%p", + ring->memtype, handle); + return -1; + } + MEM_OP_CALL_OK_RET(ring->memtype, mem_ops_mem_statics, + (handle, type)); + } + else + { + MEM_OP_CALL_OK_RET(NSFW_SHMEM, mem_ops_mem_statics, (handle, type)); + } + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_iterator +* Description : spool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 nsfw_mem_sp_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET(NSFW_SHMEM, mem_ops_sp_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +i32 nsfw_mem_mbuf_iterator(mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET(NSFW_SHMEM, mem_ops_mbuf_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +i32 nsfw_mem_ring_iterator(mpool_handle handle, nsfw_mem_item_fun fun, + void *argv) +{ + MEM_OP_CALL_OK_RET(NSFW_SHMEM, mem_ops_ring_iterator, + (handle, fun, argv)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_get_health_info +* Description : get overflow flag and other info +* Input : mring_handle mhandle +* Output : None +* Return Value : +* Calls : +* Called By : +*****************************************************************************/ +nsfw_mem_ring_health_info nsfw_mem_get_health_info(mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = (struct nsfw_mem_ring *) mhandle; + nsfw_mem_ring_health_info ring_health_info; + + ring_health_info.overflow_count = 0; + ring_health_info.overflow_time.tv_sec = 0; + ring_health_info.overflow_time.tv_usec = 0; + + ring_health_info.prod.head = 0; + ring_health_info.prod.tail = 0; + + ring_health_info.cons.head = 0; + ring_health_info.cons.tail = 0; + + ring_health_info.size = 0; + ring_health_info.mask = 0; + + if (NULL == temp) + { + NSRTP_LOGERR("invalid parameter]"); + return ring_health_info; + } + ring_health_info.overflow_count = temp->overflow_count; + ring_health_info.overflow_time = temp->overflow_time; + ring_health_info.prod.head = temp->prod.head; + ring_health_info.prod.tail = temp->prod.tail; + + ring_health_info.cons.head = temp->cons.head; + ring_health_info.cons.tail = temp->cons.tail; + + ring_health_info.size = temp->size; + ring_health_info.mask = temp->mask; + + return ring_health_info; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME(NSFW_MEM_MGR_MODULE) +NSFW_MODULE_PRIORITY(10) +NSFW_MODULE_INIT(nsfw_mem_init) +/* *INDENT-ON* */ diff --git a/src/framework/mem/nsfw_mem_desc.c b/src/framework/mem/nsfw_mem_desc.c new file mode 100644 index 0000000..ddb9c94 --- /dev/null +++ b/src/framework/mem/nsfw_mem_desc.c @@ -0,0 +1,104 @@ +/* +* +* 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 "nsfw_mem_api.h" +#include "dmm_shmem_mng.h" +#include "dmm_nshmem_mng.h" +#include "dmm_ring.h" + +/* *INDENT-OFF* */ +/*the inferaces accessing memory*/ +static nsfw_mem_ops dmm_shmem_ops = +{ + dmm_shmem_init, + dmm_shmem_destroy, + dmm_shmem_create, + NULL,//nsfw_shmem_createv, + dmm_shmem_lookup, + dmm_shmem_release, + NULL,//dmm_shmem_mbfmpcreate, + NULL,//dmm_shmem_mbfmpcreatev, + NULL,//dmm_shmem_mbfmplookup, + NULL,//dmm_shmem_mbfmprelease, + NULL,//dmm_shmem_spcreate, + NULL,//dmm_shmem_spcreatev, + dmm_shmem_sp_ringcreate, + dmm_shmem_sprelease, + dmm_shmem_sp_lookup, + dmm_shmem_ringcreate, + dmm_shmem_ring_lookup, + dmm_shmem_ringrelease, + dmm_shmem_stactic, + NULL,//dmm_shmem_sp_iterator, + NULL,//nsfw_shmem_mbuf_iterator, + NULL,//nsfw_shmem_ring_iterator, + dmm_shmem_shddr_to_laddr, + dmm_shmem_laddr_to_shddr, + dmm_attach_core_id +}; + +/*no share memory access inferface*/ +static nsfw_mem_ops dmm_nshmem_ops = +{ + dmm_nshmem_init, + dmm_nshmem_destory, + dmm_nshmem_create, + NULL, + NULL,//nsfw_nshmem_lookup, + NULL,//nsfw_nshmem_release, + NULL, + NULL, + NULL, + NULL, + dmm_nshmem_spcreate, + NULL, + NULL, + dmm_nshmem_sprelease, + NULL,//nsfw_nshmem_sp_lookup, + dmm_nshmem_ringcreate, + NULL, + dmm_nshmem_ringrelease, + dmm_nshmem_stactic, + //NULL, + NULL,/*mem_ops_sp_iterator*/ + NULL,/*mem_ops_mbuf_iterator*/ +}; + +/*the order you add must be NSFW_SHMEM, NSFW_NSHMEM*/ +nsfw_mem_attr g_nsfw_mem_ops[] = +{ + {NSFW_SHMEM, &dmm_shmem_ops}, + {NSFW_NSHMEM, &dmm_nshmem_ops} +}; +/* *INDENT-ON* */ + +i32 g_mem_type_num = sizeof(g_nsfw_mem_ops) / sizeof(nsfw_mem_attr); + +nsfw_ring_ops g_ring_ops_arry[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX] = { + { + [NSFW_MRING_MPMC] = { + .ring_ops_enqueue = dmm_mem_enqueue, + .ring_ops_dequeue = dmm_mem_dequeue} + } + , + { + [NSFW_MRING_MPMC] = { + .ring_ops_enqueue = dmm_mem_enqueue, + .ring_ops_dequeue = dmm_mem_dequeue} + } +}; |