void sim_disk_file::serve(void* buffer, offset_type offset, size_type bytes, request::request_type type) { scoped_mutex_lock fd_lock(fd_mutex); double op_start = timestamp(); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); void* mem = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, file_des, offset); if (mem == MAP_FAILED) { STXXL_THROW_ERRNO (io_error, " mmap() failed." << " Page size: " << sysconf(_SC_PAGESIZE) << " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE))); } else if (mem == 0) { STXXL_THROW_ERRNO(io_error, "mmap() returned NULL"); } else { if (type == request::READ) { memcpy(buffer, mem, bytes); } else { memcpy(mem, buffer, bytes); } STXXL_THROW_ERRNO_NE_0(munmap(mem, bytes), io_error, "munmap() failed"); } double delay = get_delay(offset, bytes); delay = delay - timestamp() + op_start; assert(delay > 0.0); int seconds_to_wait = static_cast<int>(floor(delay)); if (seconds_to_wait) sleep(seconds_to_wait); usleep((useconds_t)((delay - seconds_to_wait) * 1000000.)); }
STXXL_BEGIN_NAMESPACE void mmap_file::serve(void* buffer, offset_type offset, size_type bytes, request::request_type type) { scoped_mutex_lock fd_lock(fd_mutex); //assert(offset + bytes <= _size()); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); int prot = (type == request::READ) ? PROT_READ : PROT_WRITE; void* mem = mmap(NULL, bytes, prot, MAP_SHARED, file_des, offset); // void *mem = mmap (buffer, bytes, prot , MAP_SHARED|MAP_FIXED , file_des, offset); // STXXL_MSG("Mmaped to "<<mem<<" , buffer suggested at "<<buffer); if (mem == MAP_FAILED) { STXXL_THROW_ERRNO(io_error, " mmap() failed." << " path=" << filename << " bytes=" << bytes << " Page size: " << sysconf(_SC_PAGESIZE) << " offset modulo page size " << (offset % sysconf(_SC_PAGESIZE))); } else if (mem == 0) { STXXL_THROW_ERRNO(io_error, "mmap() returned NULL"); } else { if (type == request::READ) { memcpy(buffer, mem, bytes); } else { memcpy(mem, buffer, bytes); } STXXL_THROW_ERRNO_NE_0(munmap(mem, bytes), io_error, "munmap() failed"); } }
STXXL_BEGIN_NAMESPACE void syscall_file::serve(const request* req) throw (io_error) { scoped_mutex_lock fd_lock(fd_mutex); assert(req->get_file() == this); offset_type offset = req->get_offset(); char* buffer = static_cast<char*>(req->get_buffer()); size_type bytes = req->get_size(); request::request_type type = req->get_type(); stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); while (bytes > 0) { off_t rc = ::lseek(file_des, offset, SEEK_SET); if (rc < 0) { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::lseek(fd,offset,SEEK_SET)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " rc=" << rc); } if (type == request::READ) { #if STXXL_MSVC assert(bytes <= std::numeric_limits<unsigned int>::max()); if ((rc = ::read(file_des, buffer, (unsigned int)bytes)) <= 0) #else if ((rc = ::read(file_des, buffer, bytes)) <= 0) #endif { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::read(fd,buffer,bytes)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << "READ" << " rc=" << rc); } bytes -= rc; offset += rc; buffer += rc; if (bytes > 0 && offset == this->_size()) { // read request extends past end-of-file // fill reminder with zeroes memset(buffer, 0, bytes); bytes = 0; } } else { #if STXXL_MSVC assert(bytes <= std::numeric_limits<unsigned int>::max()); if ((rc = ::write(file_des, buffer, (unsigned int)bytes)) <= 0) #else if ((rc = ::write(file_des, buffer, bytes)) <= 0) #endif { STXXL_THROW_ERRNO (io_error, " this=" << this << " call=::write(fd,buffer,bytes)" << " path=" << filename << " fd=" << file_des << " offset=" << offset << " buffer=" << (void*)buffer << " bytes=" << bytes << " type=" << "WRITE" << " rc=" << rc); } bytes -= rc; offset += rc; buffer += rc; } } }
STXXL_BEGIN_NAMESPACE void wincall_file::serve(const request* req) throw (io_error) { scoped_mutex_lock fd_lock(fd_mutex); assert(req->get_file() == this); offset_type offset = req->get_offset(); void* buffer = req->get_buffer(); size_type bytes = req->get_size(); request::request_type type = req->get_type(); if (bytes > 32 * 1024 * 1024) { STXXL_ERRMSG("Using a block size larger than 32 MiB may not work with the " << io_type() << " filetype"); } HANDLE handle = file_des; LARGE_INTEGER desired_pos; desired_pos.QuadPart = offset; if (!SetFilePointerEx(handle, desired_pos, NULL, FILE_BEGIN)) { STXXL_THROW_WIN_LASTERROR(io_error, "SetFilePointerEx in wincall_request::serve()" << " offset=" << offset << " this=" << this << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE")); } else { stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); if (type == request::READ) { DWORD NumberOfBytesRead = 0; assert(bytes <= std::numeric_limits<DWORD>::max()); if (!ReadFile(handle, buffer, (DWORD)bytes, &NumberOfBytesRead, NULL)) { STXXL_THROW_WIN_LASTERROR(io_error, "ReadFile" << " this=" << this << " offset=" << offset << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " NumberOfBytesRead= " << NumberOfBytesRead); } else if (NumberOfBytesRead != bytes) { STXXL_THROW_WIN_LASTERROR(io_error, " partial read: missing " << (bytes - NumberOfBytesRead) << " out of " << bytes << " bytes"); } } else { DWORD NumberOfBytesWritten = 0; assert(bytes <= std::numeric_limits<DWORD>::max()); if (!WriteFile(handle, buffer, (DWORD)bytes, &NumberOfBytesWritten, NULL)) { STXXL_THROW_WIN_LASTERROR(io_error, "WriteFile" << " this=" << this << " offset=" << offset << " buffer=" << buffer << " bytes=" << bytes << " type=" << ((type == request::READ) ? "READ" : "WRITE") << " NumberOfBytesWritten= " << NumberOfBytesWritten); } else if (NumberOfBytesWritten != bytes) { STXXL_THROW_WIN_LASTERROR(io_error, " partial write: missing " << (bytes - NumberOfBytesWritten) << " out of " << bytes << " bytes"); } } } }