예제 #1
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Wait several IO(s) completed.
     *
     * @nr number of waiting IO(s).
     * @events event array for temporary use.
     * @aioQueue AioDataPtr of completed IO will be pushed into it.
     */
    void wait(size_t nr, std::queue<AioData>& aioDataQueue) {

        size_t done = 0;
        bool isError = false;
        while (done < nr) {
            int tmpNr = ::io_getevents(ctx_, 1, nr - done, &ioEvents_[done], NULL);
            if (tmpNr < 1) {
                throw std::runtime_error("io_getevents failed.");
            }
            double endTime = getTime();
            for (size_t i = done; i < done + tmpNr; i++) {
                auto* iocb = static_cast<struct iocb *>(ioEvents_[i].obj);
                auto* ptr = static_cast<AioData *>(iocb->data);
                if (ioEvents_[i].res != ptr->iocb.u.c.nbytes) {
                    isError = true;
                }
                ptr->endTime = endTime;
                aioDataQueue.push(*ptr);
            }
            done += tmpNr;
        }
        if (isError) {
            // ::printf("wait error.\n");
            throw EofError();
        }
    }
예제 #2
0
//
// TBuf::AcceptPunct
//
// Calls NextToken, and generates error if not punctuation
//
void TBuf::AcceptPunct()
{
  // Get next token
  switch (NextToken())
  { 
    case TR_OK  :
      ExpectError("punctuation", lastToken);

    case TR_PUN :
      break;

    case TR_EOF :
      EofError("punctuation");
  }
}
예제 #3
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Read data and fill a buffer.
     */
    void read(off_t oft, size_t size, char* buf) {

        if (deviceSize_ < oft + size) { throw EofError(); }
        ::lseek(fd_, oft, SEEK_SET);
        size_t s = 0;
        while (s < size) {
            ssize_t ret = ::read(fd_, &buf[s], size - s);
            if (ret < 0) {
                std::string e("read failed: ");
                e += strerror(errno);
                throw std::runtime_error(e);
            }
            s += ret;
        }
    }
예제 #4
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Write data of a buffer.
     */
    void write(off_t oft, size_t size, char* buf) {

        if (deviceSize_ < oft + size) { throw EofError(); }
        if (mode_ == READ_MODE) { throw std::runtime_error("write is not permitted."); }
        ::lseek(fd_, oft, SEEK_SET);
        size_t s = 0;
        while (s < size) {
            ssize_t ret = ::write(fd_, &buf[s], size - s);
            if (ret < 0) {
                std::string e("write failed: ");
                e += ::strerror(errno);
                throw std::runtime_error(e);
            }
            s += ret;
        }
    }
예제 #5
0
//
// TBuf::AcceptIdent
//
// Calls NextToken, and generates error if punctuation or EOF
//
void TBuf::AcceptIdent()
{
  // Get next token
  switch (NextToken())
  { 
    case TR_OK  :
      break;

    case TR_PUN :
      ExpectError("identifier", lastToken);
      break;

    case TR_EOF :
      EofError("identifier");
      break;
  }
}
예제 #6
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Wait just one IO completed.
     *
     * @return aio data pointer.
     *   This data is available at least before calling
     *   queueSize_ times of prepareWrite/prepareRead.
     */
    AioData* waitOne() {

        auto& event = ioEvents_[0];
        int err = ::io_getevents(ctx_, 1, 1, &event, NULL);
        double endTime = getTime();
        if (err != 1) {
            throw std::runtime_error("io_getevents failed.");
        }
        auto* iocb = static_cast<struct iocb *>(event.obj);
        auto* ptr = static_cast<AioData *>(iocb->data);
        if (event.res != ptr->iocb.u.c.nbytes) {
            // ::printf("waitOne error %lu\n", event.res);
            throw EofError();
        }
        ptr->endTime = endTime;
        return ptr;
    }
예제 #7
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Discard request.
     */
    void discard(off_t oft, size_t size) {

        uint64_t range[2];
        range[0] = oft;
        range[1] = size;

        if (deviceSize_ < oft + size) { throw EofError(); }
        if (mode_ != DISCARD_MODE) {
            throw std::runtime_error("discard is not permitted.");
        }
        int ret = ::ioctl(fd_, BLKDISCARD, &range);
        if (ret) {
            std::string e("discard failed: ");
            e += ::strerror(errno);
            throw std::runtime_error(e);
        }
    }
예제 #8
0
//
// TBuf::Accept
//
// Accept token 'accept', or generate error if different
//
void TBuf::Accept(const char *accept)
{
  ASSERT(accept);
  
  // get next token
  switch (NextToken())
  { 
    case TR_OK  :
    case TR_PUN :
      if (Utils::Strcmp(accept, lastToken))
      {
        TokenError("Expecting '%s' but found '%s'", accept, lastToken);
      }
      break;

    case TR_EOF :
      EofError(accept);
  }
}
예제 #9
0
파일: util.hpp 프로젝트: HackLinux/ioreth
    /**
     * Submit all prepared IO(s).
     */
    void submit() {

        size_t nr = aioQueue_.size();
        if (nr == 0) {
            return;
        }
        assert(iocbs_.size() >= nr);
        double beginTime = getTime();
        for (size_t i = 0; i < nr; i++) {
            auto* ptr = aioQueue_.front();
            aioQueue_.pop();
            iocbs_[i] = &ptr->iocb;
            ptr->beginTime = beginTime;
        }
        assert(aioQueue_.empty());
        int err = ::io_submit(ctx_, nr, &iocbs_[0]);
        if (err != static_cast<int>(nr)) {
            /* ::printf("submit error %d.\n", err); */
            throw EofError();
        }
    }