Begin implementation of using memory-mapped files for shared memory

svn path=/trunk/boinc/; revision=13467
This commit is contained in:
Charlie Fenton 2007-08-27 09:17:38 +00:00
parent bebcb0ef61
commit 5cd7cdbc04
8 changed files with 136 additions and 12 deletions

View File

@ -167,12 +167,21 @@ static int setup_shared_mem() {
delete app_client_shm;
app_client_shm = NULL;
}
#else
#ifdef USE_FILE_MAPPED_SHMEM
if (create_shmem(
MMAPPED_FILE_NAME, sizeof(SHARED_MEM), (void**)&app_client_shm->shm
)) {
delete app_client_shm;
app_client_shm = NULL;
}
#else
if (attach_shmem(aid.shmem_seg_name, (void**)&app_client_shm->shm)) {
delete app_client_shm;
app_client_shm = NULL;
}
#endif
#endif // ! USE_FILE_MAPPED_SHMEM
#endif // ! _WIN32
if (app_client_shm == NULL) return -1;
return 0;
}

View File

@ -17,7 +17,12 @@ extern void boinc_app_key_release(int, int);
//
extern void boinc_graphics_loop(int, char**);
extern void* boinc_graphics_make_shmem(char*, int);
#ifdef USE_FILE_MAPPED_SHMEM
// Use boinc_graphics_make_shmem() instead of boinc_graphics_get_shmem()
#else
extern void* boinc_graphics_get_shmem(char*);
#endif
// Implementation stuff
//

View File

@ -35,15 +35,19 @@ void* boinc_graphics_make_shmem(char* prog_name, int size) {
return p;
#else
void* p;
#ifdef USE_FILE_MAPPED_SHMEM
int retval = create_shmem("gfx_mmap_file", size, &p);
#else
key_t key = get_shmem_name(prog_name);
int retval = create_shmem(key, size, 0, &p);
#endif
if (retval) return 0;
return p;
#endif
}
void* boinc_graphics_get_shmem(char* prog_name) {
#ifdef _WIN32
void* boinc_graphics_get_shmem(char* prog_name) {
HANDLE shmem_handle;
char shmem_name[256];
void* p;
@ -51,11 +55,17 @@ void* boinc_graphics_get_shmem(char* prog_name) {
shmem_handle = attach_shmem(shmem_name, &p);
if (shmem_handle == NULL) return 0;
return p;
}
#else
#ifdef USE_FILE_MAPPED_SHMEM
// Use boinc_graphics_make_shmem() instead of boinc_graphics_get_shmem()
#else
void* boinc_graphics_get_shmem(char* prog_name) {
void* p;
key_t key = get_shmem_name(prog_name);
int retval = attach_shmem(key, &p);
if (retval) return 0;
return p;
#endif
}
#endif
#endif

View File

@ -8135,3 +8135,22 @@ Rytis 26 Aug 2007
html/
inc/util.inc
user/team_email_list.php
Charlie 25 Aug 2007
Begin implementation of using memory-mapped files for shared memory.
As a temporary measure during development, the new shared memory logic
is selected by defining USE_FILE_MAPPED_SHMEM. Once the conversion is
complete, we will use these as guideposts to remove the old logic
(using shmget,shmat, shmdt, shmctl, key_t, etc.) and then remove the
references to USE_FILE_MAPPED_SHMEM.
Note: these changes are to the HEAD / trunk only, for version 6.
api/
boinc_api.C
graphics2.h
graphics2_util.C
client/
app.C
app_start.C
lib/
shmem.C,h

View File

@ -184,7 +184,11 @@ void ACTIVE_TASK::cleanup_task() {
int retval;
if (app_client_shm.shm) {
#ifdef USE_FILE_MAPPED_SHMEM
retval = detach_shmem(app_client_shm.shm, sizeof(SHARED_MEM));
#else
retval = detach_shmem(app_client_shm.shm);
#endif
if (retval) {
msg_printf(NULL, MSG_INTERNAL_ERROR,
"Couldn't detach shared memory: %s", boincerror(retval)

View File

@ -575,10 +575,17 @@ int ACTIVE_TASK::start(bool first_time) {
// Set up core/app shared memory seg if needed
//
if (!app_client_shm.shm) {
#ifdef USE_FILE_MAPPED_SHMEM
sprintf(buf, "%s%s", slot_dir, MMAPPED_FILE_NAME);
retval = create_shmem(
buf, sizeof(SHARED_MEM), (void**)&app_client_shm.shm
);
#else
retval = create_shmem(
shmem_seg_name, sizeof(SHARED_MEM), gstate.boinc_project_gid,
(void**)&app_client_shm.shm
);
#endif
if (retval) {
needs_shmem = true;
destroy_shmem(shmem_seg_name); // Don't leave an orphan shmem segment

View File

@ -48,6 +48,12 @@ extern "C" int debug_printf(const char *fmt, ...);
#endif
#endif
#ifdef USE_FILE_MAPPED_SHMEM
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#endif
#include "error_numbers.h"
#include "shmem.h"
@ -159,6 +165,50 @@ int detach_shmem(void* p) {
#else
#ifdef USE_FILE_MAPPED_SHMEM
int create_shmem(char *path, size_t size, void** pp) {
int fd;
// try 0666, then SHM_R|SHM_W
// seems like some platforms require one or the other
// (this may be superstition)
//
// NOTE: in principle it should be 0660, not 0666
// (i.e. Apache should belong to the same group as the
// project admin user, and should therefore be able to access the seg.
// However, this doesn't seem to work on some Linux systems.
// I don't have time to figure this out (31 July 07)
// it's a big headache for anyone it affects,
// and it's not a significant security issue.
//
fd = open(path, O_RDWR | O_CREAT, 0666);
if (fd < 0)
return ERR_SHMGET;
*pp = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
// Now close the file. The kernel doesnÕt use our file descriptor.
close(fd);
if (*pp == MAP_FAILED)
return ERR_SHMGET;
return 0;
}
int destroy_shmem(key_t key){
return 0;
}
int detach_shmem(void* p, size_t size) {
int retval;
retval = shmdt((char *)p);
return retval;
}
#else // USE_FILE_MAPPED_SHMEM
int create_shmem(key_t key, int size, gid_t gid, void** pp) {
int id;
@ -272,12 +322,15 @@ int print_shmem_info(key_t key) {
return 0;
}
#endif // USE_FILE_MAPPED_SHMEM
// For debugging shared memory logic
// For testing on Apple, Linux, UNIX systems with limited number
// of shared memory segments per process and / or system-wide
// Mac OS X has a default limit of 8 segments per process, 32 system-wide
// If
void stress_shmem(short reduce_by) {
#ifndef USE_FILE_MAPPED_SHMEM
int retval;
void * shmaddr[16];
key_t key[] = {
@ -297,8 +350,9 @@ void stress_shmem(short reduce_by) {
retval = shmctl(id, IPC_RMID, 0);
}
}
#endif // !defined(USE_FILE_MAPPED_SHMEM)
}
#endif
#endif // !defined(_WIN32) && !defined(__EMX__)
const char *BOINC_RCSID_f835f078de = "$Id$";

View File

@ -44,16 +44,24 @@ int detach_shmem(HANDLE hSharedMem, void* p);
#else
#ifdef USE_FILE_MAPPED_SHMEM
#define MMAPPED_FILE_NAME "boinc_mmap_file"
// create a shared-memory segment of the given size.
//
extern int create_shmem(char *path, size_t size, void** pp);
// detach from a shared-mem segment
//
extern int detach_shmem(void* p, size_t size);
#else
// create a shared-memory segment of the given size.
//
extern int create_shmem(key_t, int size, gid_t gid, void**);
// Destroy a shared-memory segment.
// If there are attachments to it,
// print a message in a loop until the attachments are gone
//
extern int destroy_shmem(key_t);
// attach to a shared-memory segment
//
extern int attach_shmem(key_t, void**);
@ -64,11 +72,19 @@ extern int detach_shmem(void*);
extern int shmem_info(key_t key);
#endif
// Destroy a shared-memory segment.
// If there are attachments to it,
// print a message in a loop until the attachments are gone
//
extern int destroy_shmem(key_t);
#ifndef __EMX__
// For testing on Apple, Linux, UNIX systems with limited number
// of shared memory segments per process and / or system-wide
void stress_shmem(short reduce_by);
#endif
#endif
#endif
#endif // !defined(_WIN32)
#endif // BOINC_SHMEM_H