scummvm/backends/platform/psp/tests.cpp
Jordi Vilalta Prat 8388e0dfea JANITORAL: Clean trailing whitespaces.
svn-id: r53160
2010-10-12 02:18:11 +00:00

736 lines
21 KiB
C++

/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
*
*/
// 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) */