// alloc_data_area.C #include "common.h" #include "message.h" #include #include #include /* getenv, exit */ #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif int shm_open(const char *, int, mode_t); #ifdef __cplusplus } #endif // only POSIX option is supported for Linux systems which DO support the real time POSIX 4 options #include void * alloc_data_area(int id, int size) { char object_name[16]; size_t shmsize; // segment size in bytes int shmid; void * shmaddress; int shmkey; #ifdef MASTER int i; #endif // obtain shared memory ID - this will create segment if needed // In practice only the MASTER task which starts first will ever create and initialise shmkey = id; shmsize = size; // create a file mapped object (MASTER) or obtain ID of existing object sprintf(object_name,"/SHM_%d", shmkey); #ifdef MASTER shmid = shm_open(object_name, O_RDWR|O_CREAT, (mode_t) -1); #else shmid = shm_open(object_name, O_RDWR, (mode_t) -1); #endif if (shmid == -1) { ReportError(); sprintf(message_buffer, "shm_open failed - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } #ifdef MASTER sprintf(message_buffer, "File mapped object %s of size %lu created", object_name, (unsigned long int)shmsize); #else sprintf(message_buffer, "File mapped object %s accessed", object_name); #endif report_message(MSG_INFORMATION); #ifdef MASTER // size the memory object i = ftruncate(shmid, shmsize); if (i == -1) { ReportError(); sprintf(message_buffer, "ftruncate failed - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } #endif // attach the memory segment sprintf(message_buffer, "Memory mapping %lu bytes", (unsigned long int)shmsize); report_message(MSG_INFORMATION); shmaddress = mmap((caddr_t) NULL, (size_t) shmsize, PROT_READ|PROT_WRITE, MAP_SHARED, shmid, (off_t) 0); if (shmaddress == (void *) MAP_FAILED) { ReportError(); sprintf(message_buffer, "mmap failed - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } // tidy up close(shmid); sprintf(message_buffer, "Shared memory segment located at address %p.", shmaddress); report_message(MSG_INFORMATION); return shmaddress; }