aboutsummaryrefslogtreecommitdiffstats
path: root/src/framework/mem/dmm_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/framework/mem/dmm_group.c')
-rw-r--r--src/framework/mem/dmm_group.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/framework/mem/dmm_group.c b/src/framework/mem/dmm_group.c
new file mode 100644
index 0000000..35e6100
--- /dev/null
+++ b/src/framework/mem/dmm_group.c
@@ -0,0 +1,185 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+//#include "dmm_memory.h"
+#include "dmm_config.h"
+#include "dmm_group.h"
+#include "dmm_pause.h"
+
+#define DMM_GROUP_ACTIVE 0x55D5551
+#define DMM_GROUP_GLOBAL "global"
+#define DMM_GROUP_ENV "DMM_GROUP"
+#define DMM_GROUP_FMT "%s/dmm-group-%s" /* VAR_DIR group-name */
+
+static struct flock group_lock = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = sizeof (struct dmm_group),
+};
+
+static int group_fd = -1;
+struct dmm_group *main_group = NULL;
+
+inline static const char *
+get_group_path ()
+{
+ static char group_path[PATH_MAX] = "";
+
+ if (!group_path[0])
+ {
+ const char *group = getenv (DMM_GROUP_ENV);
+
+ if (!group || !group[0])
+ group = DMM_GROUP_GLOBAL;
+
+ (void) snprintf (group_path, sizeof (group_path), DMM_GROUP_FMT,
+ DMM_VAR_DIR, group);
+ group_path[sizeof (group_path) - 1] = 0;
+ }
+
+ return group_path;
+}
+
+void
+dmm_group_active ()
+{
+ main_group->group_init = DMM_GROUP_ACTIVE;
+}
+
+int
+dmm_group_create_main ()
+{
+ int ret;
+ const char *path = get_group_path ();
+
+ group_fd = open (path, O_RDWR | O_CREAT, 0664);
+ if (group_fd < 0)
+ {
+ return -1;
+ }
+
+ ret = ftruncate (group_fd, sizeof (struct dmm_group));
+ if (ret < 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ ret = fcntl (group_fd, F_SETLK, &group_lock);
+ if (ret < 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group),
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ group_fd, 0);
+
+ if (main_group == MAP_FAILED)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+dmm_group_delete_main ()
+{
+ if (main_group)
+ {
+ (void) munmap (main_group, sizeof (struct dmm_group));
+ main_group = NULL;
+ }
+
+ if (group_fd >= 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ }
+
+ (void) unlink (get_group_path ());
+
+ return 0;
+}
+
+int
+dmm_group_attach_main ()
+{
+ const char *path = get_group_path ();
+
+ group_fd = open (path, O_RDONLY);
+ if (group_fd < 0)
+ {
+ return -1;
+ }
+
+ main_group = (struct dmm_group *) mmap (NULL, sizeof (struct dmm_group *),
+ PROT_READ, MAP_SHARED, group_fd, 0);
+ if (main_group == MAP_FAILED)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ while (main_group->group_init != DMM_GROUP_ACTIVE)
+ {
+ dmm_pause ();
+ }
+
+ if (kill (main_group->share.pid, 0))
+ {
+ (void) munmap (main_group->share.base, main_group->share.size);
+ (void) close (group_fd);
+ group_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+dmm_group_detach_main ()
+{
+ if (main_group)
+ {
+ (void) munmap (main_group, sizeof (struct dmm_group));
+ main_group = NULL;
+ }
+
+ if (group_fd >= 0)
+ {
+ (void) close (group_fd);
+ group_fd = -1;
+ }
+
+ return 0;
+}