Jack2 1.9.6

JackShmMem.cpp

00001 /*
00002  Copyright (C) 2004-2008 Grame
00003  
00004  This program is free software; you can redistribute it and/or modify
00005  it under the terms of the GNU Lesser General Public License as published by
00006  the Free Software Foundation; either version 2.1 of the License, or
00007  (at your option) any later version.
00008  
00009  This program is distributed in the hope that it will be useful,
00010  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  GNU Lesser General Public License for more details.
00013  
00014  You should have received a copy of the GNU Lesser General Public License
00015  along with this program; if not, write to the Free Software 
00016  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  
00018  */
00019 
00020 #include "JackError.h"
00021 #include "JackShmMem.h"
00022 #include <stdio.h>
00023 
00024 namespace Jack
00025 {
00026 
00027 static unsigned int fSegmentNum = 0;
00028 static jack_shm_info_t gInfo;
00029 size_t JackMem::gSize = 0;
00030 
00031 JackShmMem::JackShmMem()
00032 {
00033     JackShmMemAble::Init();
00034     LockMemory();
00035 }
00036     
00037 JackShmMem::~JackShmMem()
00038 {
00039     UnlockMemory();
00040 }
00041 
00042 void JackShmMemAble::Init()
00043 {
00044     fInfo.index = gInfo.index;
00045     fInfo.ptr.attached_at = gInfo.ptr.attached_at;
00046     fInfo.size = gInfo.size;
00047 }
00048     
00049 void* JackShmMem::operator new(size_t size, void* memory)
00050 {
00051     jack_log("JackShmMem::new placement size = %ld", size);
00052     return memory;
00053 }
00054 
00055 void* JackShmMem::operator new(size_t size)
00056 {
00057     jack_shm_info_t info;
00058     JackShmMem* obj;
00059     char name[64];
00060 
00061     snprintf(name, sizeof(name), "/jack_shared%d", fSegmentNum++);
00062 
00063     if (jack_shmalloc(name, size, &info)) {
00064         jack_error("cannot create shared memory segment of size = %d", size, strerror(errno));
00065         goto error;
00066     }
00067 
00068     if (jack_attach_shm(&info)) {
00069         jack_error("cannot attach shared memory segment name = %s err = %s", name, strerror(errno));
00070         jack_destroy_shm(&info);
00071         goto error;
00072     }
00073 
00074     obj = (JackShmMem*)jack_shm_addr(&info);
00075     // It is unsafe to set object fields directly (may be overwritten during object initialization),
00076     // so use an intermediate global data
00077     gInfo.index = info.index;
00078     gInfo.size = size;
00079     gInfo.ptr.attached_at = info.ptr.attached_at;
00080 
00081     jack_log("JackShmMem::new index = %ld attached = %x size = %ld ", info.index, info.ptr.attached_at, size);
00082     return obj;
00083 
00084 error:
00085     jack_error("JackShmMem::new bad alloc", size);
00086     throw std::bad_alloc();
00087 }
00088 
00089 void JackShmMem::operator delete(void* p, size_t size)
00090 {
00091     jack_shm_info_t info;
00092     JackShmMem* obj = (JackShmMem*)p;
00093     info.index = obj->fInfo.index;
00094     info.ptr.attached_at = obj->fInfo.ptr.attached_at;
00095 
00096     jack_log("JackShmMem::delete size = %ld index = %ld", size, info.index);
00097 
00098     jack_release_shm(&info);
00099     jack_destroy_shm(&info);
00100 }
00101 
00102 void JackShmMem::operator delete(void* obj)
00103 {       
00104     if (obj) {
00105         JackShmMem::operator delete(obj, 0);
00106     }
00107 }
00108 
00109 void LockMemoryImp(void* ptr, size_t size)
00110 {
00111     if (CHECK_MLOCK((char*)ptr, size)) {
00112         jack_log("Succeeded in locking %u byte memory area", size);
00113     } else {
00114         jack_error("Cannot lock down memory area (%s)", strerror(errno));
00115     }
00116 }
00117 
00118 void InitLockMemoryImp(void* ptr, size_t size)
00119 {
00120     if (CHECK_MLOCK((char*)ptr, size)) {
00121         memset(ptr, 0, size);
00122         jack_log("Succeeded in locking %u byte memory area", size);
00123     } else {
00124         jack_error("Cannot lock down memory area (%s)", strerror(errno));
00125     }
00126 }
00127 
00128 void UnlockMemoryImp(void* ptr, size_t size)
00129 {
00130     if (CHECK_MUNLOCK((char*)ptr, size)) {
00131         jack_log("Succeeded in unlocking %u byte memory area", size);
00132     } else {
00133         jack_error("Cannot unlock down memory area (%s)", strerror(errno));
00134     }
00135 }
00136 
00137 void LockAllMemory()
00138 {
00139     if (CHECK_MLOCKALL()) {
00140         jack_log("Succeeded in locking all memory");
00141     } else {
00142         jack_error("Cannot lock all memory (%s)", strerror(errno));
00143     }
00144 }
00145 
00146 void UnlockAllMemory()
00147 {
00148     if (CHECK_MUNLOCKALL()) {
00149         jack_log("Succeeded in unlocking all memory");
00150     } else {
00151         jack_error("Cannot unlock all memory (%s)", strerror(errno));
00152     }
00153 }
00154 
00155 
00156 } // end of namespace
00157