Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

tests.cpp

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *
 */

// PSP speed and unit tests. Activate in tests.h
// You may also want to build without any engines.

#include "backends/platform/psp/tests.h"

#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS)

#include "common/scummsys.h"
#include <pspiofilemgr_fcntl.h>
#include <pspiofilemgr_stat.h>
#include <pspiofilemgr.h>
#include <pspthreadman.h>
#include <pspsdk.h>
#include <psprtc.h>
#include <stdlib.h>
#include <stdio.h>
#include <psputils.h>
#include "backends/platform/psp/rtc.h"
#include "backends/platform/psp/thread.h"
#include "backends/platform/psp/memory.h"
#include "common/stream.h"
#include "common/file.h"
#include "common/fs.h"

#define UNCACHED(x)           ((byte *)(((uint32)(x)) | 0x40000000))    /* make an uncached access */
#define CACHED(x)       ((byte *)(((uint32)(x)) & 0xBFFFFFFF))    /* make an uncached access into a cached one */

//#define __PSP_DEBUG_FUNCS__
//#define __PSP_DEBUG_PRINT__

// Results: (333Mhz/222Mhz)
// Getting a tick: 1-2 us
// Getting a time structure: 9/14us
// ie. using a tick and just dividing by 1000 saves us time.

#include "backends/platform/psp/trace.h"

class PspSpeedTests {
public:
      void tickSpeed();
      void getMicrosSpeed();
      void seekSpeed();
      void msReadSpeed();
      void threadFunctionsSpeed();
      void semaphoreSpeed();
      static int threadFunc(SceSize args, void *argp);
      void semaphoreManyThreadSpeed();
      void fastCopySpeed();

private:
      enum {
            MEMCPY_BUFFER_SIZE = 8192
      };
      static PspSemaphore _sem;     // semaphore

      void readAndTime(uint32 bytes, char *buffer, FILE *file);
      void seekAndTime(int bytes, int origin, FILE *file);
      void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes);
      void fastCopyDifferentSizes(byte *dst, byte *src);
      int getThreadIdSpeed();
      void getPrioritySpeed();
      void changePrioritySpeed(int id, int priority);
};

PspSemaphore PspSpeedTests::_sem(0);

void PspSpeedTests::tickSpeed() {
      uint32 ticksPerSecond = sceRtcGetTickResolution();
      PSP_INFO_PRINT("ticksPerSecond[%d]\n", ticksPerSecond);

      uint32 currentTicks1[2];
      uint32 currentTicks2[2];

      sceRtcGetCurrentTick((u64 *)currentTicks1);
      sceRtcGetCurrentTick((u64 *)currentTicks2);
      PSP_INFO_PRINT("current tick[%x %x][%u %u]\n", currentTicks1[0], currentTicks1[1], currentTicks1[0], currentTicks1[1]);
      PSP_INFO_PRINT("current tick[%x %x][%u %u]\n", currentTicks2[0], currentTicks2[1], currentTicks2[0], currentTicks2[1]);

      pspTime time;
      sceRtcSetTick(&time, (u64 *)currentTicks2);
      PSP_INFO_PRINT("current tick in time, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time.year, time.month, time.day, time.hour, time.minutes, time.seconds, time.microseconds);

      pspTime time1;
      pspTime time2;
      sceRtcGetCurrentClockLocalTime(&time1);
      sceRtcGetCurrentClockLocalTime(&time2);
      PSP_INFO_PRINT("time1, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time1.year, time1.month, time1.day, time1.hour, time1.minutes, time1.seconds, time1.microseconds);
      PSP_INFO_PRINT("time2, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time2.year, time2.month, time2.day, time2.hour, time2.minutes, time2.seconds, time2.microseconds);
}

void PspSpeedTests::getMicrosSpeed() {
      uint32 time1, time2, time3, time4;
      time1 = PspRtc::instance().getMicros();
      time2 = PspRtc::instance().getMicros();
      time3 = PspRtc::instance().getMicros();
      time4 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("getMicros() times: %d, %d, %d\n", time4-time3, time3-time2, time2-time1);
}

void PspSpeedTests::readAndTime(uint32 bytes, char *buffer, FILE *file) {
      uint32 time1 = PspRtc::instance().getMicros();
      // test minimal read
      fread(buffer, bytes, 1, file);
      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Reading %d byte takes %dus\n", bytes, time2-time1);
}

/*
      333MHz/222MHz
      Reading 1 byte takes 2590us / 3167
      Reading 10 byte takes 8us / 9
      Reading 50 byte takes 8us / 11
      Reading 100 byte takes 8us / 11
      Reading 1000 byte takes 915us / 1131
      Reading 2000 byte takes 1806us / 2,284
      Reading 3000 byte takes 2697us / 3,374
      Reading 5000 byte takes 4551us / 5,544
      Reading 6000 byte takes 5356us / 6,676
      Reading 7000 byte takes 6800us / 8,358
      Reading 8000 byte takes 6794us / 8,454
      Reading 9000 byte takes 6782us / 8,563
      Reading 10000 byte takes 8497us / 10,631
      Reading 30000 byte takes 25995us / 32,473
      Reading 80000 byte takes 68457us / 85,291
      Reading 100000 byte takes 85103us / 106,163
*/
// Function to test the impact of MS reads
// These tests can't be done from shell - the cache screws them up
void PspSpeedTests::msReadSpeed() {
      FILE *file;
      file = fopen("ms0:/psp/music/track1.mp3", "r");

      char *buffer = (char *)malloc(2 * 1024 * 1024);

      readAndTime(1, buffer, file);
      readAndTime(10, buffer, file);
      readAndTime(50, buffer, file);
      readAndTime(100, buffer, file);
      readAndTime(1000, buffer, file);
      readAndTime(2000, buffer, file);
      readAndTime(3000, buffer, file);
      readAndTime(5000, buffer, file);
      readAndTime(6000, buffer, file);
      readAndTime(7000, buffer, file);
      readAndTime(8000, buffer, file);
      readAndTime(9000, buffer, file);
      readAndTime(10000, buffer, file);
      readAndTime(30000, buffer, file);
      readAndTime(50000, buffer, file);
      readAndTime(80000, buffer, file);
      readAndTime(100000, buffer, file);

      fclose(file);
      free(buffer);
}

void PspSpeedTests::seekAndTime(int bytes, int origin, FILE *file) {
      char buffer[1000];

      uint32 time1 = PspRtc::instance().getMicros();
      // test minimal read
      fseek(file, bytes, origin);
      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Seeking %d byte from %d took %dus\n", bytes, origin, time2-time1);

      time1 = PspRtc::instance().getMicros();
      // test minimal read
      fread(buffer, 1000, 1, file);
      time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Reading 1000 bytes took %dus\n", time2-time1);
}

/*
333MHz
Seeking 0 byte from 0 took 946us
Reading 1000 bytes took 1781us
Seeking 5 byte from 0 took 6us
Reading 1000 bytes took 19us
Seeking 1000 byte from 0 took 5us
Reading 1000 bytes took 913us
Seeking 100 byte from 0 took 955us
Reading 1000 bytes took 906us
Seeking 10000 byte from 0 took 963us
Reading 1000 bytes took 905us
Seeking -5 byte from 1 took 1022us
Reading 1000 bytes took 949us
Seeking -100 byte from 1 took 1040us
Reading 1000 bytes took 907us
Seeking 100 byte from 1 took 1044us
Reading 1000 bytes took 930us
Seeking 0 byte from 2 took 7211us
Reading 1000 bytes took 80us
Seeking 10000 byte from 2 took 3636us
Reading 1000 bytes took 110us
*/

void PspSpeedTests::seekSpeed() {
      FILE *file;
      file = fopen("ms0:/psp/music/track1.mp3", "r");

      seekAndTime(0, SEEK_SET, file);
      seekAndTime(5, SEEK_SET, file);
      seekAndTime(1000, SEEK_SET, file);
      seekAndTime(100, SEEK_SET, file);
      seekAndTime(10000, SEEK_SET, file);
      seekAndTime(-5, SEEK_CUR, file);
      seekAndTime(-100, SEEK_CUR, file);
      seekAndTime(100, SEEK_CUR, file);
      seekAndTime(0, SEEK_END, file);
      seekAndTime(-10000, SEEK_END, file);

      fclose(file);
}

// 222: 5-7us
int PspSpeedTests::getThreadIdSpeed() {
      uint32 time1 = PspRtc::instance().getMicros();
      int threadId = sceKernelGetThreadId();
      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Getting thread ID %d took %dus\n", threadId, time2-time1);

      return threadId;
}

// 222: 4-5us
void PspSpeedTests::getPrioritySpeed() {
      uint32 time1 = PspRtc::instance().getMicros();
      int priority = sceKernelGetThreadCurrentPriority();
      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Getting thread priority %d took %dus\n", priority, time2-time1);
}

// 222: 9-10us
void PspSpeedTests::changePrioritySpeed(int id, int priority) {
      uint32 time1 = PspRtc::instance().getMicros();
      sceKernelChangeThreadPriority(id, priority);
      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("Changing thread priority to %d for id %d took %dus\n", priority, id, time2-time1);
}

void PspSpeedTests::threadFunctionsSpeed() {
      // very unscientific -- just ballpark
      int id;
      id = getThreadIdSpeed();
      getThreadIdSpeed();
      getPrioritySpeed();
      getPrioritySpeed();
      changePrioritySpeed(id, 30);
      changePrioritySpeed(id, 35);
      changePrioritySpeed(id, 25);

      // test context switch time
      for (int i=0; i<10; i++) {
            uint time1 = PspRtc::instance().getMicros();
            PspThread::delayMicros(0);
            uint time2 = PspRtc::instance().getMicros();
            PSP_INFO_PRINT("poll %d. context switch Time = %dus\n", i, time2-time1);      // 10-15us
      }
}

void PspSpeedTests::semaphoreSpeed() {
      PspSemaphore sem(1);

      uint32 time1 = PspRtc::instance().getMicros();

      sem.take();

      uint32 time2 = PspRtc::instance().getMicros();

      PSP_INFO_PRINT("taking semaphore took %d us\n", time2-time1);     // 10us

      uint32 time3 = PspRtc::instance().getMicros();

      sem.give();

      uint32 time4 = PspRtc::instance().getMicros();
      PSP_INFO_PRINT("releasing semaphore took %d us\n", time4-time3);  //10us-55us
}

int PspSpeedTests::threadFunc(SceSize args, void *argp) {
      PSP_INFO_PRINT("thread %x created.\n", sceKernelGetThreadId());

      _sem.take();

      PSP_INFO_PRINT("grabbed semaphore. Quitting thread\n");

      return 0;
}

void PspSpeedTests::semaphoreManyThreadSpeed() {

      // create 4 threads
      for (int i=0; i<4; i++) {
            int thid = sceKernelCreateThread("my_thread", PspSpeedTests::threadFunc, 0x18, 0x10000, THREAD_ATTR_USER, NULL);
            sceKernelStartThread(thid, 0, 0);
      }

      PSP_INFO_PRINT("main thread. created threads\n");

      uint32 threads = _sem.numOfWaitingThreads();
      while (threads < 4) {
            threads = _sem.numOfWaitingThreads();
            PSP_INFO_PRINT("main thread: waiting threads[%d]\n", threads);
      }

      PSP_INFO_PRINT("main: semaphore value[%d]\n", _sem.getValue());
      PSP_INFO_PRINT("main thread: waiting threads[%d]\n", _sem.numOfWaitingThreads());

      _sem.give(4);
}

void PspSpeedTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes) {
      uint32 time1, time2;
      uint32 fastcopyTime, memcpyTime;
      const int iterations = 2000;
      int intc;

      intc = pspSdkDisableInterrupts();

      time1 = PspRtc::instance().getMicros();
      for (int i=0; i<iterations; i++) {
            PspMemory::fastCopy(dst, src, bytes);
      }
      time2 = PspRtc::instance().getMicros();

      pspSdkEnableInterrupts(intc);

      fastcopyTime = time2-time1;

      intc = pspSdkDisableInterrupts();

      time1 = PspRtc::instance().getMicros();
      for (int i=0; i<iterations; i++) {
            memcpy(dst, src, bytes);
      }
      time2 = PspRtc::instance().getMicros();

      pspSdkEnableInterrupts(intc);

      memcpyTime = time2-time1;

      PSP_INFO_PRINT("%d bytes. memcpy[%d], fastcopy[%d]\n", bytes, memcpyTime, fastcopyTime);
}

void PspSpeedTests::fastCopyDifferentSizes(byte *dst, byte *src) {
      PSP_INFO_PRINT("\nsrc[%p], dst[%p]\n", src, dst);
      fastCopySpecificSize(dst, src, 1);
      fastCopySpecificSize(dst, src, 2);
      fastCopySpecificSize(dst, src, 3);
      fastCopySpecificSize(dst, src, 4);
      fastCopySpecificSize(dst, src, 5);
      fastCopySpecificSize(dst, src, 8);
      fastCopySpecificSize(dst, src, 10);
      fastCopySpecificSize(dst, src, 16);
      fastCopySpecificSize(dst, src, 32);
      fastCopySpecificSize(dst, src, 50);
      fastCopySpecificSize(dst, src, 100);
      fastCopySpecificSize(dst, src, 500);
      fastCopySpecificSize(dst, src, 1024);
      fastCopySpecificSize(dst, src, 2048);
}

void PspSpeedTests::fastCopySpeed() {
      PSP_INFO_PRINT("running fastCopy speed test\n");

      uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
      uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);

      // fill buffer 1
      for (int i=0; i<MEMCPY_BUFFER_SIZE/4; i++)
            bufferSrc32[i] = i | (((MEMCPY_BUFFER_SIZE/4)-i)<<16);

      // print buffer
      for (int i=0; i<50; i++)
            PSP_INFO_PRINT("%x ", bufferSrc32[i]);
      PSP_INFO_PRINT("\n");

      byte *bufferSrc = ((byte *)bufferSrc32);
      byte *bufferDst = ((byte *)bufferDst32);

      PSP_INFO_PRINT("\n\ndst and src cached: -----------------\n");
      fastCopyDifferentSizes(bufferDst, bufferSrc);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc);

      PSP_INFO_PRINT("\n\ndst cached, src uncached: -----------------\n");
      bufferSrc = UNCACHED(bufferSrc);
      fastCopyDifferentSizes(bufferDst, bufferSrc);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc);

      PSP_INFO_PRINT("\n\ndst uncached, src uncached: --------------\n");
      bufferDst = UNCACHED(bufferDst);
      fastCopyDifferentSizes(bufferDst, bufferSrc);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc);

      PSP_INFO_PRINT("\n\ndst uncached, src cached: -------------------\n");
      bufferSrc = CACHED(bufferSrc);
      fastCopyDifferentSizes(bufferDst, bufferSrc);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc);


      free(bufferSrc32);
      free(bufferDst32);
}

//-------Unit Tests -------------------------------

class PspUnitTests {
public:
      void testFastCopy();
      bool testFileSystem();

private:
      enum {
            MEMCPY_BUFFER_SIZE = 8192
      };

      void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap = false);
      void fastCopyDifferentSizes(byte *dst, byte *src, bool swap = false);

};

void PspUnitTests::testFastCopy() {
      PSP_INFO_PRINT("running fastcopy unit test ***********\n");
      PSP_INFO_PRINT("this test requires the test flag to be on in fastCopy\n\n");

      uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
      uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);

      // fill buffer 1
      for (int i=0; i<MEMCPY_BUFFER_SIZE/4; i++)
            bufferSrc32[i] = i | (((MEMCPY_BUFFER_SIZE/4)-i)<<16);

      // print buffer
      for (int i=0; i<50; i++)
            PSP_INFO_PRINT("%x ", bufferSrc32[i]);
      PSP_INFO_PRINT("\n");

      byte *bufferSrc = ((byte *)bufferSrc32);
      byte *bufferDst = ((byte *)bufferDst32);

      fastCopyDifferentSizes(bufferDst, bufferSrc, true);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+2, bufferSrc+2, true);
      fastCopyDifferentSizes(bufferDst+3, bufferSrc+3);
      fastCopyDifferentSizes(bufferDst, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst, bufferSrc+2, true);
      fastCopyDifferentSizes(bufferDst+2, bufferSrc, true);
      fastCopyDifferentSizes(bufferDst, bufferSrc+3);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+2);
      fastCopyDifferentSizes(bufferDst+1, bufferSrc+3);
      fastCopyDifferentSizes(bufferDst+2, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+2, bufferSrc+3);
      fastCopyDifferentSizes(bufferDst+3, bufferSrc+1);
      fastCopyDifferentSizes(bufferDst+3, bufferSrc+2);

      free(bufferSrc32);
      free(bufferDst32);
}

void PspUnitTests::fastCopyDifferentSizes(byte *dst, byte *src, bool swap) {
      fastCopySpecificSize(dst, src, 1);
      fastCopySpecificSize(dst, src, 2, swap);
      fastCopySpecificSize(dst, src, 4, swap);
      fastCopySpecificSize(dst, src, 6, swap);
      fastCopySpecificSize(dst, src, 8, swap);
      fastCopySpecificSize(dst, src, 9);
      fastCopySpecificSize(dst, src, 10, swap);
      fastCopySpecificSize(dst, src, 11);
      fastCopySpecificSize(dst, src, 12, swap);
      fastCopySpecificSize(dst, src, 13);
      fastCopySpecificSize(dst, src, 14, swap);
      fastCopySpecificSize(dst, src, 15);
      fastCopySpecificSize(dst, src, 16, swap);
      fastCopySpecificSize(dst, src, 17);
      fastCopySpecificSize(dst, src, 18, swap);
      fastCopySpecificSize(dst, src, 19);
      fastCopySpecificSize(dst, src, 20, swap);
      fastCopySpecificSize(dst, src, 32, swap);
      fastCopySpecificSize(dst, src, 33);
      fastCopySpecificSize(dst, src, 34, swap);
      fastCopySpecificSize(dst, src, 35);
      fastCopySpecificSize(dst, src, 36, swap);
      fastCopySpecificSize(dst, src, 50, swap);
      fastCopySpecificSize(dst, src, 100, swap);
      fastCopySpecificSize(dst, src, 500, swap);
      fastCopySpecificSize(dst, src, 1000, swap);
}

void PspUnitTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap) {
      memset(dst, 0, bytes);
      PspMemory::fastCopy(dst, src, bytes);

      if (swap) { // test swap also
            memset(dst, 0, bytes);

            // pixelformat for swap
            PSPPixelFormat format;
            format.set(PSPPixelFormat::Type_4444, true);

            PspMemory::fastSwap(dst, src, bytes, format);
      }
}

// This function leaks. For now I don't care
bool PspUnitTests::testFileSystem() {
      // create memory
      const uint32 BufSize = 32 * 1024;
      char* buffer = new char[BufSize];
      int i;
      Common::WriteStream *wrStream;
      Common::SeekableReadStream *rdStream;

      PSP_INFO_PRINT("testing fileSystem...\n");

      // fill buffer
      for (i=0; i<(int)BufSize; i += 4) {
            buffer[i] = 'A';
            buffer[i + 1] = 'B';
            buffer[i + 2] = 'C';
            buffer[i + 3] = 'D';
      }

      // create a file
      const char *path = "./file.test";
      Common::FSNode file(path);

      PSP_INFO_PRINT("creating write stream...\n");

      wrStream = file.createWriteStream();
      if (!wrStream) {
            PSP_ERROR("%s couldn't be created.\n", path);
            return false;
      }

      // write contents
      char* index = buffer;
      int32 totalLength = BufSize;
      int32 curLength = 50;

      PSP_INFO_PRINT("writing...\n");

      while(totalLength - curLength > 0) {
            if ((int)wrStream->write(index, curLength) != curLength) {
                  PSP_ERROR("couldn't write %d bytes\n", curLength);
                  return false;
            }
            totalLength -= curLength;
            index += curLength;
            //curLength *= 2;
            //PSP_INFO_PRINT("write\n");
      }

      // write the rest
      if ((int)wrStream->write(index, totalLength) != totalLength) {
            PSP_ERROR("couldn't write %d bytes\n", curLength);
            return false;
      }

      delete wrStream;

      PSP_INFO_PRINT("reading...\n");

      rdStream = file.createReadStream();
      if (!rdStream) {
            PSP_ERROR("%s couldn't be created.\n", path);
            return false;
      }

      // seek to beginning
      if (!rdStream->seek(0, SEEK_SET)) {
            PSP_ERROR("couldn't seek to the beginning after writing the file\n");
            return false;
      }

      // read the contents
      char *readBuffer = new char[BufSize + 4];
      memset(readBuffer, 0, (BufSize + 4));
      index = readBuffer;
      while (rdStream->read(index, 100) == 100) {
            index += 100;
      }

      if (!rdStream->eos()) {
            PSP_ERROR("didn't find EOS at end of stream\n");
            return false;
      }

      // compare
      for (i=0; i<(int)BufSize; i++)
            if (buffer[i] != readBuffer[i]) {
                  PSP_ERROR("reading/writing mistake at %x. Got %x instead of %x\n", i, readBuffer[i], buffer[i]);
                  return false;
            }

      // Check for exceeding limit
      for (i=0; i<4; i++) {
            if (readBuffer[BufSize + i]) {
                  PSP_ERROR("read exceeded limits. %d = %x\n", BufSize + i, readBuffer[BufSize + i]);
            }
      }

      delete rdStream;

      PSP_INFO_PRINT("writing...\n");

      wrStream = file.createWriteStream();
      if (!wrStream) {
            PSP_ERROR("%s couldn't be created.\n", path);
            return false;
      }

      const char *phrase = "Jello is really fabulous";
      uint32 phraseLen = strlen(phrase);

      int ret;
      if ((ret = wrStream->write(phrase, phraseLen)) != (int)phraseLen) {
            PSP_ERROR("couldn't write phrase. Got %d instead of %d\n", ret, phraseLen);
            return false;
      }

      PSP_INFO_PRINT("reading...\n");

      delete wrStream;
      rdStream = file.createReadStream();
      if (!rdStream) {
            PSP_ERROR("%s couldn't be created.\n", path);
            return false;
      }

      char *readPhrase = new char[phraseLen + 2];
      memset(readPhrase, 0, phraseLen + 2);

      if ((ret = rdStream->read(readPhrase, phraseLen) != phraseLen)) {
            PSP_ERROR("read error on phrase. Got %d instead of %d\n", ret, phraseLen);
            return false;
      }

      for (i=0; i<(int)phraseLen; i++) {
            if (readPhrase[i] != phrase[i]) {
                  PSP_ERROR("bad read/write in phrase. At %d, %x != %x\n", i, readPhrase[i], phrase[i]);
                  return false;
            }
      }

      // check for exceeding
      if (readPhrase[i] != 0) {
            PSP_ERROR("found excessive copy in phrase. %c at %d\n", readPhrase[i], i);
            return false;
      }

      PSP_INFO_PRINT("trying to read end...\n");

      // seek to end
      if (!rdStream->seek(0, SEEK_END)) {
            PSP_ERROR("couldn't seek to end for append\n");
            return false;
      };

      // try to read
      if (rdStream->read(readPhrase, 2) || !rdStream->eos()) {
            PSP_ERROR("was able to read at end of file\n");
            return false;
      }

      PSP_INFO_PRINT("ok\n");
      return true;
}

void psp_tests() {
      PSP_INFO_PRINT("in tests\n");

#ifdef PSP_ENABLE_SPEED_TESTS
      // Speed tests
      PspSpeedTests speedTests;
      speedTests.tickSpeed();
      speedTests.getMicrosSpeed();
      speedTests.msReadSpeed();
      speedTests.seekSpeed();
      speedTests.msReadSpeed();
      speedTests.threadFunctionsSpeed();
      speedTests.semaphoreSpeed();
      speedTests.semaphoreManyThreadSpeed();
      speedTests.fastCopySpeed();
#endif

#ifdef PSP_ENABLE_UNIT_TESTS
      // Unit tests
      PspUnitTests unitTests;

      //unitTests.testFastCopy();
      unitTests.testFileSystem();
#endif
}

#endif /* (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) */

Generated by  Doxygen 1.6.0   Back to index