mirror of https://github.com/BOINC/boinc.git
Begin implementation of using memory-mapped files for shared memory
svn path=/trunk/boinc/; revision=13467
This commit is contained in:
parent
bebcb0ef61
commit
5cd7cdbc04
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
56
lib/shmem.C
56
lib/shmem.C
|
@ -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$";
|
||||
|
|
32
lib/shmem.h
32
lib/shmem.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue