📄 shmem.cc
字号:
/********************************************************************* Description: shmem.cc* C++ file for the Communication Management System (CMS).* Includes member Functions for class SHMEM.* Notes: The class SHMEM should be used by procedures accessing a* shared memory buffer on the same processor.** Derived from a work by Fred Proctor & Will Shackleford** Author:* License: GPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.6 $* $Author: paul_c $* $Date: 2005/06/13 14:38:48 $********************************************************************/#ifdef __cplusplusextern "C" {#endif#include <stdio.h> /* sscanf() */#include <stddef.h> /* size_t */#include <sys/stat.h> /* S_IRUSR, etc. */#include <sys/types.h> /* key_t */#include <errno.h> // errno#include <string.h> /* strchr(), memcpy(), memset() */#include <stdlib.h> /* strtod */#ifdef __cplusplus}#endif#include "rcs_print.hh" /* rcs_print_error() */#include "cms.hh" /* class CMS */#include "shmem.hh" /* class SHMEM */#include "shm.hh" /* class RCS_SHAREDMEM *///#include "sem.hh" /* class RCS_SEMAPHORE */#include "memsem.hh" /* mem_get_access(), mem_release_access() */#include "timer.hh" /* etime(), esleep() *//* Common Definitions. *///#include "autokey.h"/* rw-rw-r-- permissions */#define MODE (0777)static double last_non_zero_x;static double last_x;static int not_zero(volatile double x){ last_x = x; if (x < -1E-6 && last_x < -1E-6) { last_non_zero_x = x; return 1; } if (x > 1E-6 && last_x > 1E-6) { last_non_zero_x = x; return 1; } return 0;}/* SHMEM Member Functions. *//* Constructor for hard coded tests. */SHMEM::SHMEM(char *n, long s, int nt, key_t k, int m):CMS(s){ /* Set pointers to null so only properly opened pointers are closed. */ shm = NULL;// sem = NULL; /* save constructor args */ master = m; key = k; /* open the shared mem buffer and create mutual exclusion semaphore */ open();}/* Constructor for use with cms_config. */SHMEM::SHMEM(char *bufline, char *procline, int set_to_server, int set_to_master):CMS(bufline, procline, set_to_server){ /* Set pointers to null so only properly opened pointers are closed. */ shm = NULL; sem = NULL; sem_delay = 0.00001; char *semdelay_equation; use_os_sem = 1; use_os_sem_only = 1; mutex_type = OS_SEM_MUTEX; bsem_key = -1; second_read = 0; if (status < 0) { rcs_print_error("SHMEM: status = %d\n", status); return; } /* Save parameters from configuration file. */ if (sscanf(bufline, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %d", &key) != 1) { rcs_print_error("SHMEM: Invalid configuration file format.\n"); return; } master = is_local_master; if (1 == set_to_master) { master = 1; } else if (-1 == set_to_master) { master = 0; } if (NULL != (semdelay_equation = strstr(proclineupper, "SEMDELAY="))) { sem_delay = strtod(semdelay_equation + 9, (char **) NULL); } else if (NULL != (semdelay_equation = strstr(buflineupper, "SEMDELAY="))) { sem_delay = strtod(semdelay_equation + 9, (char **) NULL); } if (NULL != (semdelay_equation = strstr(buflineupper, "BSEM="))) { bsem_key = strtol(semdelay_equation + 5, (char **) NULL, 0); } if (NULL != strstr(buflineupper, "MUTEX=NONE")) { mutex_type = NO_MUTEX; use_os_sem = 0; use_os_sem_only = 0; } if (NULL != strstr(buflineupper, "MUTEX=OS_SEM")) { mutex_type = OS_SEM_MUTEX; use_os_sem = 1; use_os_sem_only = 1; } if (NULL != strstr(buflineupper, "MUTEX=NO_INTERRUPTS")) { mutex_type = NO_INTERRUPTS_MUTEX; use_os_sem = 0; use_os_sem_only = 0; } if (NULL != strstr(buflineupper, "MUTEX=NO_SWITCHING")) { mutex_type = NO_SWITCHING_MUTEX; use_os_sem = 0; use_os_sem_only = 0; } if (NULL != strstr(buflineupper, "MUTEX=MAO")) { mutex_type = MAO_MUTEX; use_os_sem = 0; use_os_sem_only = 0; } if (NULL != strstr(buflineupper, "MAO_W_OS_SEM")) { mutex_type = MAO_MUTEX_W_OS_SEM; use_os_sem = 1; use_os_sem_only = 0; } /* Open the shared memory buffer and create mutual exclusion semaphore. */ open();}SHMEM::~SHMEM(){ /* detach from shared memory and semaphores */ close();}/* Open the SHMEM buffer */int SHMEM::open(){ /* Set pointers to NULL incase error occurs. */ sem = NULL; shm = NULL; bsem = NULL; shm_addr_offset = NULL; second_read = 0; autokey_table_size = 0;/*! \todo Another #if 0 */#if 0 // PC Do we need to use autokey ? if (use_autokey_for_connection_number) { autokey_table_size = sizeof(AUTOKEY_TABLE_ENTRY) * total_connections; }#endif /* set up the shared memory address and semaphore, in given state */ if (master) { shm = new RCS_SHAREDMEM(key, size, RCS_SHAREDMEM_CREATE, (int) MODE); if (shm->addr == NULL) { switch (shm->create_errno) { case EACCES: status = CMS_PERMISSIONS_ERROR; break; case EEXIST: status = CMS_RESOURCE_CONFLICT_ERROR; break; case ENOMEM: case ENOSPC: status = CMS_CREATE_ERROR; break; default: status = CMS_MISC_ERROR; } delete shm; shm = NULL; return -1; } if (use_os_sem) { sem = new RCS_SEMAPHORE(key, RCS_SEMAPHORE_CREATE, timeout, (int) MODE, (use_os_sem_only != 0)); if (NULL == sem) { rcs_print_error("CMS: couldn't create RCS_SEMAPHORE.\n"); rcs_print_error(" Possibly out of memory?\n"); status = CMS_CREATE_ERROR; return -1; } if (!sem->valid()) { rcs_print_error("CMS: RCS_SEMAPHORE is invalid.\n"); status = CMS_MISC_ERROR; return -1; } } if (bsem_key > 0) { bsem = new RCS_SEMAPHORE(bsem_key, RCS_SEMAPHORE_CREATE, timeout, (int) MODE, 0); if (NULL == bsem) { rcs_print_error("CMS: couldn't create RCS_SEMAPHORE.\n"); rcs_print_error(" Possibly out of memory?\n"); status = CMS_CREATE_ERROR; return -1; } if (!bsem->valid()) { rcs_print_error("CMS: RCS_SEMAPHORE is invalid.\n"); status = CMS_MISC_ERROR; return -1; } } in_buffer_id = 0; } else { shm = new RCS_SHAREDMEM(key, size, RCS_SHAREDMEM_NOCREATE); if (NULL == shm) { rcs_print_error ("CMS: couldn't create RCS_SHAREDMEM(%d(0x%X), %d(0x%X), RCS_SHAREDMEM_NOCREATE).\n", key, key, size, size); status = CMS_CREATE_ERROR; return -1; } if (shm->addr == NULL) { switch (shm->create_errno) { case EACCES: status = CMS_PERMISSIONS_ERROR; break; case EEXIST: status = CMS_RESOURCE_CONFLICT_ERROR; break; case ENOENT: status = CMS_NO_MASTER_ERROR; break; case ENOMEM: case ENOSPC: status = CMS_CREATE_ERROR; break; default: status = CMS_MISC_ERROR; } delete shm; shm = NULL; return -1; } if (use_os_sem) { sem = new RCS_SEMAPHORE(key, RCS_SEMAPHORE_NOCREATE, timeout); if (NULL == sem) { rcs_print_error("CMS: couldn't create RCS_SEMAPHORE.\n"); rcs_print_error(" Possibly out of memory?\n"); status = CMS_CREATE_ERROR; return -1; } if (!sem->valid()) { rcs_print_error("CMS: RCS_SEMAPHORE is invalid.\n"); status = CMS_MISC_ERROR; return -1; } } if (bsem_key > 0) { bsem = new RCS_SEMAPHORE(bsem_key, RCS_SEMAPHORE_NOCREATE, timeout); if (NULL == bsem) { rcs_print_error("CMS: couldn't create RCS_SEMAPHORE.\n"); rcs_print_error(" Possibly out of memory?\n"); status = CMS_CREATE_ERROR; return -1; } if (!bsem->valid()) { rcs_print_error("CMS: RCS_SEMAPHORE is invalid.\n"); status = CMS_MISC_ERROR; return -1; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -