/**
 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "Fifo.h"

#include <stdlib.h>
#ifdef WIN32
#define valloc malloc
#endif

#include "Logging.h"

// bufferSize is the amount of data to be filled
// singleBufferSize is the maximum size that may be filled during a single write
// (bufferSize + singleBufferSize) will be allocated
Fifo::Fifo(int singleBufferSize, int bufferSize, sem_t* readerSem) {
  mWrite = mRead = mReadCommit = mRaggedEnd = 0;
  mWrapThreshold = bufferSize;
  mSingleBufferSize = singleBufferSize;
  mReaderSem = readerSem;
  mBuffer = (char*)valloc(bufferSize + singleBufferSize);
  mEnd = false;

  if (mBuffer == NULL) {
    logg->logError(__FILE__, __LINE__, "failed to allocate %d bytes", bufferSize + singleBufferSize);
    handleException();
  }

  if (sem_init(&mWaitForSpaceSem, 0, 0)) {
    logg->logError(__FILE__, __LINE__, "sem_init() failed");
    handleException();
  }
}

Fifo::~Fifo() {
  free(mBuffer);
  sem_destroy(&mWaitForSpaceSem);
}

int Fifo::numBytesFilled() const {
  return mWrite - mRead + mRaggedEnd;
}

char* Fifo::start() const {
  return mBuffer;
}

bool Fifo::isEmpty() const {
  return mRead == mWrite && mRaggedEnd == 0;
}

bool Fifo::isFull() const {
  return willFill(0);
}

// Determines if the buffer will fill assuming 'additional' bytes will be added to the buffer
// 'full' means there is less than singleBufferSize bytes available contiguously; it does not mean there are zero bytes available
bool Fifo::willFill(int additional) const {
  if (mWrite > mRead) {
    if (numBytesFilled() + additional < mWrapThreshold) {
      return false;
    }
  } else {
    if (numBytesFilled() + additional < mWrapThreshold - mSingleBufferSize) {
      return false;
    }
  }
  return true;
}

// This function will stall until contiguous singleBufferSize bytes are available
char* Fifo::write(int length) {
  if (length <= 0) {
    length = 0;
    mEnd = true;
  }

  // update the write pointer
  mWrite += length;

  // handle the wrap-around
  if (mWrite >= mWrapThreshold) {
    mRaggedEnd = mWrite;
    mWrite = 0;
  }

  // send a notification that data is ready
  sem_post(mReaderSem);

  // wait for space
  while (isFull()) {
    sem_wait(&mWaitForSpaceSem);
  }

  return &mBuffer[mWrite];
}

void Fifo::release() {
  // update the read pointer now that the data has been handled
  mRead = mReadCommit;

  // handle the wrap-around
  if (mRead >= mWrapThreshold) {
    mRaggedEnd = mRead = mReadCommit = 0;
  }

  // send a notification that data is free (space is available)
  sem_post(&mWaitForSpaceSem);
}

// This function will return null if no data is available
char* Fifo::read(int *const length) {
  // wait for data
  if (isEmpty() && !mEnd) {
    return NULL;
  }

  // obtain the length
  do {
    mReadCommit = mRaggedEnd ? mRaggedEnd : mWrite;
    *length = mReadCommit - mRead;
  } while (*length < 0); // plugs race condition without using semaphores

  return &mBuffer[mRead];
}
