?? shared_memory.h
字號(hào):
bit_vec(num_of_segments,bit_vector_buff) { // initialize out to end of the bit_vector buffer for (int i=0; i<bit_vec_size; i++) {// shmid[i]=-1;// buffers[i]=0; bit_vector_buff[i]=0; } mem_ptr = 0; // finish initializing the other buffers to num_of_segments// for (int i=bit_vec_size+1; i<num_of_segments; i++) {// shmid[i]=-1;// buffers[i]=0;// } }; // constructor // destructor template<allocator_key_t alloc_key, allocator_addr_t alloc_addr> shared<alloc_key, alloc_addr>::~shared() { // Just the bit_vec should be automatically destroyed. // Opposite of the constructor // Check the reference count on the shared memory segment // If last object referencing shared memory, delete it #ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " ~shared() : mem_ptr : " << mem_ptr << std::endl;#endif // unmap shared memory for(mappings_t::iterator it = mappings.begin(); it != mappings.end(); it++) { // for each segment in the shared object // if it is not referenced, unlink it#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " ~shared() : alloc_addr : " << it->first << std::endl;#endif shared_memory_header_t* smh = static_cast<shared_memory_header_t*>(it->second.first); int ref_count = smh->get_ref_count();#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " ~shared() : ref_count : " << ref_count << std::endl;#endif std::cerr.flush(); if (!ref_count) { smh->~shared_memory_header_t(); int ret_val = munmap(it->second.first, it->second.second.st_size); if (ret_val == -1) { std::clog << "Status: " << __FILE__ << ':' << __LINE__ ; std::clog << ": shared memory munmap: " << strerror(errno) << std::endl; } // unlink shared memory std::clog << "Status: " << __FILE__ << ':' << __LINE__ ; std::clog << ": shared memory shm_unlink called" << std::endl; ret_val = shm_unlink(it->first.data()); if (ret_val == -1) { std::clog << "Status: " << __FILE__ << ':' << __LINE__ ; std::clog << ": shared memory shm_unlink: " << strerror(errno) << std::endl; std::clog << "Shared memory segement: " << it->first.data() << std::endl; }#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " ~shared() deleting shm : " << std::endl;#endif // delete the map key mappings.erase(it); } } }; // destructor // }// std::map<allocator_key_t,// std::pair<void*,struct stat> >::iterator it = mappings.find(alloc_key);// if (it != mappings.end()) {// // Both initialized and mapped. Retrieve pointer and allocation is over.// // first, destroy the locks// } else {// // Other process still pointing to the shared memory. Do not// // remove the shared memory// // Further do not decrement the ref_count. Only those// // functions with actually allocate and deallocate memory from// // the shared memory segment change the reference count.// // Shared creates a segment if it does not exist, and removes// // it when the reference count is zero and it exits.// // Otherwise, the it does not affect the ref_count.// #ifdef DEBUG// std::cerr << __FILE__ << ":" << __LINE__ <<// " ~shared() : decrementing ref_count: " <<// ref_count << std::endl;// #endif// } // copy constructor template<allocator_key_t alloc_key, allocator_addr_t alloc_addr> shared<alloc_key, alloc_addr>::shared(const shared<alloc_key, alloc_addr>& t) : // segment pages have no overhead, they are just space num_of_pages(t.num_of_pages), page_size(t.page_size), segment_size (t.segment_size), bit_vec(t.bit_vec) { mem_ptr = t.mem_ptr; // Most of the important shared::shared attributes are static. // therefore there is only one version of them declared for all // process objects. They are in a sense global, and therefore // need not be copied, as the same verison is accessed by all // objects in the same process. }; // copy constructor // assignment operator template<allocator_key_t alloc_key, allocator_addr_t alloc_addr> shared<alloc_key, alloc_addr>& shared<alloc_key, alloc_addr>::operator=(const shared<alloc_key, alloc_addr>& t) { if (this != &t) { // avoid self assignment: t=t mem_ptr = t.mem_ptr; } return *this; }; // assignment operator //////////////////////////////////////////////////////////////////// ////// shared<>::allocate(const int& proj_id) //////////////////////////////////////////////////////////////////// ////// ////// proj_id - ////// ////// Creates a large allocation of shared memory used by the ////// allocator. Returns a pointer to the newly allocated page, ////// parameter indicates if the page is newly allocated and ////// therefore NOT initialized, or if the page was already in ////// use and simply attached. ////// ////// ////// //////////////////////////////////////////////////////////////////// // void* shared::allocate(allocator_key_t key_val) { template<allocator_key_t alloc_key, allocator_addr_t alloc_addr> memory_index_t shared<alloc_key, alloc_addr>::allocate(const int& proj_id) {// alloc_addr>::allocate() { // alloc_key - string describing key name, identifies which // shared memory segment. // returns a pointer to the newly allocated page, parameter // indicates if the page is newly allocated and therefore NOT // initialized, or if the page was already in use and simply // attached. // All shared memory blocks have the shared memory header class // instantiated at the beginning of their memory space. // Variables // initialized - describes whether share memory segment has // header installed. // mapped - describes whether the process has already mapped // this shared memory segment into its virtual // memory. // Possible senarios at this point: // 1. Brand new shared memory segment, just created for the // first time. Needs to be initiallized and mapped. // 2. Existing shared memory segment: // a. Process has already mapped this segment, retrieve // pointer from stored mapping // b. 1st time process is accessing this shared segment. // The segment needs to be mapped into this process's // shared memory space. void* ptr = (void*) -1; bool initialized = false; struct stat stat; int fd; // open shared memory // first try to open shared memory as if it already exists // if that fails, create the shared memory and initialize it std::stringstream alloc_key_ss; // create the shared segment key alloc_key_ss << alloc_key << "_" << proj_id;#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : alloc_key_ss.str().data() : " << alloc_key_ss.str().data() << std::endl;#endif if ((fd = shm_open(alloc_key_ss.str().data(), O_RDWR, S_IRWXU | S_IRWXG)) == -1) { // Opening existing shared memory failed. Create it. fd = shm_open(alloc_key_ss.str().data(), O_RDWR|O_CREAT, S_IRWXU | S_IRWXG); // now needs to be mapped // truncate it to required size if (ftruncate(fd, (off_t)segment_size) != -1) { // get info on the shared memory segment file descriptor fstat(fd, &stat); // After truncating the file descriptor, see if the shared // memory is already mapped? If so, return a pointer to the // existing mapped shared memory; otherwise, map it. // convert the shared memory's requested address // from its char string to an number. std::string stringval(alloc_addr); std::istringstream sin(stringval); int x; sin >> std::hex >> x; // add an offset based on the proj_id to the memory address x = x + segment_size*(proj_id-1);#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : alloc_addr : " << alloc_addr << std::endl; std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : x : " << std::hex << x << std::dec << std::endl;#endif // map shared memory ptr = mmap((void*) x, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap((void*) x, stat.st_size, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0); if (ptr != MAP_FAILED) { // if (msync((void*) x, stat.st_size, MS_SYNC | MS_INVALIDATE) != -1) { // Install the memory header in the allocated shared memory // ref_count will be set to 0 by the constructor memset(ptr,0,stat.st_size); new(ptr)shared_memory_header_t(num_of_pages, page_size, alloc_key_ss.str().data(), (int) ptr, stat.st_size, proj_id); // shmid // store off the successful mapping for future retrieval#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : " << "Inserting map val alloc_key_ss.str() : " << alloc_key_ss.str() << std::endl;#endif mappings.insert(std::pair<std::string, std::pair<void*,struct stat> >(alloc_key_ss.str(), std::pair<void*,struct stat>(ptr,stat))); } else { // if (ptr != MAP_FAILED) // create an error message to throw with the exception std::stringstream s; s << "Error: " << __FILE__ << ':' << __LINE__ << ':' << " memory map mmap failed : " << strerror(errno) << std::endl; std::clog << s; throw (Alloc_Exception::mmap_exception(s.str())); } // if (ptr != MAP_FAILED) } else { // if (ftruncate(fd, (off_t)segment_size) != -1) // create an error message to throw with the exception std::stringstream s; s << "Error: " << __FILE__ << ':' << __LINE__ << ':' << " shared memory ftruncate: " << strerror(errno) << std::endl; std::clog << s; throw (Alloc_Exception::shm_exception(s.str())); } // if (ftruncate(fd, (off_t)segment_size) != -1) } else { // if ((int fd = shm_open(alloc_key, O_RDWR, S_IRWXU | S_IRWXG)) == -1) // shared memory already exists. See if it has been mapped into // this process's memory? std::map<std::string, std::pair<void*,struct stat> >::iterator it = mappings.find(alloc_key_ss.str()); if (it != mappings.end()) { // shared memory segment has already been mapped into this segment initialized = true; ptr = it->second.first; } else { // if (it != mappings.end()) // shared memory segment has not yet been mapped // memory map it fstat(fd, &stat); // convert the shared memory's requested address // from its char string to an number. std::string stringval(alloc_addr); std::istringstream sin(stringval); int x; sin >> std::hex >> x; // add an offset based on the proj_id to the memory address x = x + segment_size*(proj_id-1);#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : alloc_addr : " << alloc_addr << std::endl; std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : x : " << std::hex << x << std::dec << std::endl;#endif ptr = mmap((void*) x, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap((void*) x, stat.st_size, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { // create an error message to throw with the exception std::stringstream s; s << "Error: " << __FILE__ << ':' << __LINE__ << ':' << " memory map mmap failed : " << strerror(errno) << std::endl; std::clog << s; throw (Alloc_Exception::mmap_exception(s.str())); } // if (ptr == MAP_FAILED) // store off the successful mapping for future retrieval#ifdef DEBUG std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : " << "Inserting map val alloc_key_ss.str().data() : " << alloc_key_ss.str().data() << std::endl;#endif mappings.insert(std::pair<std::string, std::pair<void*,struct stat> >(alloc_key_ss.str(), std::pair<void*,struct stat>(ptr,stat))); // Do not touch the reference count, ref_count. Only objects // which allocate and deallocate memory from the segment to // the allocator touch the reference counter. If the shared // object deconstructs and the ref_count is 0, it takes the // whole segement down with it. Otherwise the segment // persists.#ifdef DEBUG shared_memory_header_t* smh = static_cast<shared_memory_header_t*>(ptr); int ref_count = smh->get_ref_count(); std::cerr << __FILE__ << ":" << __LINE__ << " shared<>::allocate() : ref_count : " << ref_count << std::endl;#endif } // if (it != mappings.end()) } // if ((int fd = shm_open(alloc_key, O_RDWR, S_IRWXU | S_IRWXG)) == -1) mem_ptr = ptr; return memory_index_t(ptr, proj_id, initialized); }; // shared<>::allocate(const int& proj_id) //////////////////////////////////////////////////////////////////// ////// shared<>::free(memory_index_t mem_idx) //////////////////////////////////////////////////////////////////// ////// ////// mem_idx - contains description of shared memory block to ////// be freed by the function. ////// ////// Release allocated shared memory segment ////// ////// ////// //////////////////////////////////////////////////////////////////// // free() template<allocator_key_t alloc_key, allocator_addr_t alloc_addr> bool shared<alloc_key, alloc_addr>::free() { bool return_flag = true;#ifdef DEBUG std::cerr << __FILE__ << ':' << __LINE__ << ": " << "shared<>::free()" << std::endl;#endif return return_flag; }; // bool shared::free(memory_index_t mem_idx)}; // namespace mem_space#endif // SHARED_MEMORY_H
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -