Initial commit
This commit is contained in:
760
backends/platform/psp/tests.cpp
Normal file
760
backends/platform/psp/tests.cpp
Normal file
@@ -0,0 +1,760 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 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);
|
||||
delete[] buffer;
|
||||
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);
|
||||
delete[] buffer;
|
||||
delete wrStream;
|
||||
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);
|
||||
delete[] buffer;
|
||||
delete wrStream;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete wrStream;
|
||||
|
||||
PSP_INFO_PRINT("reading...\n");
|
||||
|
||||
rdStream = file.createReadStream();
|
||||
if (!rdStream) {
|
||||
PSP_ERROR("%s couldn't be created.\n", path);
|
||||
delete[] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
// seek to beginning
|
||||
if (!rdStream->seek(0, SEEK_SET)) {
|
||||
PSP_ERROR("couldn't seek to the beginning after writing the file\n");
|
||||
delete[] buffer;
|
||||
delete rdStream;
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the contents
|
||||
char *readBuffer = new char[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");
|
||||
delete[] buffer;
|
||||
delete rdStream;
|
||||
delete[] readBuffer;
|
||||
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]);
|
||||
delete[] buffer;
|
||||
delete rdStream;
|
||||
delete[] readBuffer;
|
||||
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[] buffer;
|
||||
delete rdStream;
|
||||
delete[] readBuffer;
|
||||
|
||||
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);
|
||||
delete wrStream;
|
||||
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]();
|
||||
|
||||
if ((ret = rdStream->read(readPhrase, phraseLen) != phraseLen)) {
|
||||
PSP_ERROR("read error on phrase. Got %d instead of %d\n", ret, phraseLen);
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
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]);
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check for exceeding
|
||||
if (readPhrase[i] != 0) {
|
||||
PSP_ERROR("found excessive copy in phrase. %c at %d\n", readPhrase[i], i);
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
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");
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
return false;
|
||||
};
|
||||
|
||||
// try to read
|
||||
if (rdStream->read(readPhrase, 2) || !rdStream->eos()) {
|
||||
PSP_ERROR("was able to read at end of file\n");
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete rdStream;
|
||||
delete[] readPhrase;
|
||||
|
||||
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) */
|
||||
Reference in New Issue
Block a user