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");
    }
}
示例#3
0
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;
        }
    }
}
示例#4
0
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");
            }
        }
    }
}