Exemple #1
0
void checkIo(int doDispatch) {
	char temp[128];
	SceUID fd = sceIoOpen("dispatch.prx", PSP_O_RDONLY, 0777);
	dispatchCheckpoint("sceIoOpen: %08x", fd >= 0 ? 1 : fd);
	dispatchCheckpoint("sceIoRead: %08x", sceIoRead(fd, temp, sizeof(temp)));
	dispatchCheckpoint("sceIoClose: %08x", sceIoClose(fd));

	int state;
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	fd = sceIoOpen("dispatch.prx", PSP_O_RDONLY, 0777);
	dispatchCheckpoint("sceIoOpen: %08x", fd >= 0 ? 1 : fd);
	dispatchCheckpoint("sceIoRead: %08x", sceIoRead(fd, temp, sizeof(temp)));
	dispatchCheckpoint("sceIoClose: %08x", sceIoClose(fd));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}

	SceInt64 res = -1;
	int result = -1;
	fd = sceIoOpenAsync("dispatch.prx", PSP_O_RDONLY, 0777);
	dispatchCheckpoint("sceIoOpenAsync: %08x", fd >= 0 ? 1 : fd);
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	result = sceIoPollAsync(fd, &res);
	dispatchCheckpoint("sceIoPollAsync: %08x / %016llx", result, res >= 0 ? 1LL : res);
	result = sceIoGetAsyncStat(fd, 1, &res);
	dispatchCheckpoint("sceIoGetAsyncStat: %08x / %016llx", result, res >= 0 ? 1LL : res);
	result = sceIoGetAsyncStat(fd, 0, &res);
	dispatchCheckpoint("sceIoGetAsyncStat: %08x / %016llx", result, res >= 0 ? 1LL : res);
	result = sceIoWaitAsync(fd, &res);
	dispatchCheckpoint("sceIoWaitAsync: %08x / %016llx", result, res >= 0 ? 1LL : res);
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	result = sceIoWaitAsync(fd, &res);
	dispatchCheckpoint("sceIoWaitAsync: %08x / %016llx", result, res >= 0 ? 1LL : res);
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	dispatchCheckpoint("sceIoRead: %08x", sceIoRead(fd, temp, sizeof(temp)));
	dispatchCheckpoint("sceIoWrite: %08x", sceIoWrite(1, "Hello.", sizeof("Hello.")));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	dispatchCheckpoint("sceIoCloseAsync: %08x", sceIoCloseAsync(fd));
	result = sceIoWaitAsync(fd, &res);
	dispatchCheckpoint("sceIoWaitAsync: %08x / %016llx", result, res);
}
Exemple #2
0
void checkSema(int doDispatch) {
	SceUID sema = sceKernelCreateSema("sema", 0, 0, 1, NULL);
	dispatchCheckpoint("sceKernelCreateSema: %08x", sema >= 0 ? 1 : sema);
	dispatchCheckpoint("sceKernelSignalSema: %08x", sceKernelSignalSema(sema, 1));
	dispatchCheckpoint("sceKernelWaitSema: %08x", sceKernelWaitSema(sema, 1, NULL));
	dispatchCheckpoint("sceKernelWaitSema too much: %08x", sceKernelWaitSema(sema, 9, NULL));
	dispatchCheckpoint("sceKernelDeleteSema: %08x", sceKernelDeleteSema(sema));
	sema = sceKernelCreateSema("test", 0, 1, 2, NULL);
	dispatchCheckpoint("sceKernelCreateSema: %08x", sema >= 0 ? 1 : sema);
	startLockThreadSema(sema);
	int state;
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	SceUInt timeout = 300;
	dispatchCheckpoint("sceKernelWaitSema: %08x", sceKernelWaitSema(sema, 1, &timeout));
	dispatchCheckpoint("sceKernelSignalSema: %08x", sceKernelSignalSema(sema, 1));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	endLockThreadSema(sema);
	dispatchCheckpoint("sceKernelPollSema: %08x", sceKernelPollSema(sema, 1));
	dispatchCheckpoint("sceKernelDeleteSema: %08x", sceKernelDeleteSema(sema));
}
Exemple #3
0
void checkDispatchCases(const char *name, void (*testfunc)(int)) {
	int state;

	dispatchCheckpoint("%s without changes:", name);
	testfunc(0);
	flushschedf();
	
	didResched = 0;
	schedf("\n");
	dispatchCheckpoint("%s with short dispatch suspend:", name);
	testfunc(1);
	flushschedf();

	didResched = 0;
	schedf("\n");
	dispatchCheckpoint("%s while dispatch suspended:", name);
	// Starting a thread apparently resumes the dispatch thread.
	++ignoreResched;
	state = sceKernelSuspendDispatchThread();
	dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	testfunc(0);
	dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
	--ignoreResched;
	flushschedf();

	didResched = 0;
	schedf("\n");
	dispatchCheckpoint("%s while intr suspended:", name);
	state = sceKernelCpuSuspendIntr();
	dispatchCheckpoint("sceKernelCpuSuspendIntr: %08x", state);
	testfunc(1);
	dispatchCheckpoint("sceKernelCpuResumeIntr: %08x", sceKernelCpuResumeIntr(state));
	flushschedf();
}
Exemple #4
0
void checkEventFlag(int doDispatch) {
	SceUID flag = sceKernelCreateEventFlag("eventflag", 0, 0xFFFFFFFF, NULL);
	dispatchCheckpoint("sceKernelCreateEventFlag: %08x", flag >= 0 ? 1 : flag);
	dispatchCheckpoint("sceKernelClearEventFlag: %08x", sceKernelClearEventFlag(flag, 1));
	dispatchCheckpoint("sceKernelWaitEventFlag: %08x", sceKernelWaitEventFlag(flag, 1, PSP_EVENT_WAITAND, NULL, NULL));
	dispatchCheckpoint("sceKernelWaitEventFlag invalid: %08x", sceKernelWaitEventFlag(flag, 0, 0, NULL, NULL));
	dispatchCheckpoint("sceKernelDeleteEventFlag: %08x", sceKernelDeleteEventFlag(flag));
	flag = sceKernelCreateEventFlag("test", 0, 0xFFFFFFFF, NULL);
	dispatchCheckpoint("sceKernelCreateEventFlag: %08x", flag >= 0 ? 1 : flag);
	startLockThreadEventFlag(flag);
	int state;
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	SceUInt timeout = 300;
	dispatchCheckpoint("sceKernelWaitEventFlag: %08x", sceKernelWaitEventFlag(flag, 1, PSP_EVENT_WAITAND, NULL, &timeout));
	dispatchCheckpoint("sceKernelClearEventFlag: %08x", sceKernelClearEventFlag(flag, 1));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	endLockThreadEventFlag(flag);
	dispatchCheckpoint("sceKernelPollEventFlag: %08x", sceKernelPollEventFlag(flag, 1, PSP_EVENT_WAITAND, NULL));
	dispatchCheckpoint("sceKernelDeleteEventFlag: %08x", sceKernelDeleteEventFlag(flag));
}
Exemple #5
0
void checkLwMutex(int doDispatch) {
	SceLwMutexWorkarea workarea;
	dispatchCheckpoint("sceKernelCreateLwMutex: %08x", sceKernelCreateLwMutex(&workarea, "lwmutex", 0, 1, NULL));
	dispatchCheckpoint("sceKernelUnlockLwMutex: %08x", sceKernelUnlockLwMutex(&workarea, 1));
	dispatchCheckpoint("sceKernelLockLwMutex: %08x", sceKernelLockLwMutex(&workarea, 1, NULL));
	dispatchCheckpoint("sceKernelLockLwMutex invalid: %08x", sceKernelLockLwMutex(&workarea, -1, NULL));
	dispatchCheckpoint("sceKernelDeleteLwMutex: %08x", sceKernelDeleteLwMutex(&workarea));
	dispatchCheckpoint("sceKernelCreateLwMutex: %08x", sceKernelCreateLwMutex(&workarea, "lwmutex", 0, 1, NULL));
	startLockThreadLwMutex(&workarea);
	int state;
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	SceUInt timeout = 300;
	dispatchCheckpoint("sceKernelLockLwMutex: %08x", sceKernelLockLwMutex(&workarea, 1, &timeout));
	dispatchCheckpoint("sceKernelUnlockLwMutex: %08x", sceKernelUnlockLwMutex(&workarea, 1));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	endLockThreadLwMutex(&workarea);
	dispatchCheckpoint("sceKernelTryLockLwMutex: %08x", sceKernelTryLockLwMutex_600(&workarea, 1));
	dispatchCheckpoint("sceKernelDeleteLwMutex: %08x", sceKernelDeleteLwMutex(&workarea));
}
Exemple #6
0
void checkMutex(int doDispatch) {
	SceUID mutex = sceKernelCreateMutex("mutex", 0, 1, NULL);
	dispatchCheckpoint("sceKernelCreateMutex: %08x", mutex >= 0 ? 1 : mutex);
	dispatchCheckpoint("sceKernelUnlockMutex: %08x", sceKernelUnlockMutex(mutex, 1));
	dispatchCheckpoint("sceKernelLockMutex: %08x", sceKernelLockMutex(mutex, 1, NULL));
	dispatchCheckpoint("sceKernelLockMutex invalid: %08x", sceKernelLockMutex(mutex, -1, NULL));
	dispatchCheckpoint("sceKernelDeleteMutex: %08x", sceKernelDeleteMutex(mutex));
	mutex = sceKernelCreateMutex("test", 0, 1, NULL);
	dispatchCheckpoint("sceKernelCreateMutex: %08x", mutex >= 0 ? 1 : mutex);
	startLockThreadMutex(mutex);
	int state;
	if (doDispatch) {
		++ignoreResched;
		state = sceKernelSuspendDispatchThread();
		dispatchCheckpoint("sceKernelSuspendDispatchThread: %08x", state);
	}
	SceUInt timeout = 300;
	dispatchCheckpoint("sceKernelLockMutex: %08x", sceKernelLockMutex(mutex, 1, &timeout));
	dispatchCheckpoint("sceKernelUnlockMutex: %08x", sceKernelUnlockMutex(mutex, 1));
	if (doDispatch) {
		dispatchCheckpoint("sceKernelResumeDispatchThread: %08x", sceKernelResumeDispatchThread(state));
		--ignoreResched;
	}
	endLockThreadMutex(mutex);
	dispatchCheckpoint("sceKernelTryLockMutex: %08x", sceKernelTryLockMutex(mutex, 1));
	dispatchCheckpoint("sceKernelDeleteMutex: %08x", sceKernelDeleteMutex(mutex));
}
Exemple #7
0
void checkDispatchInterrupt() {
	dispatchCheckpoint("Interrupts while dispatch disabled:");

	sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, &vblankCallback, NULL);
	sceKernelEnableSubIntr(PSP_VBLANK_INT, 0);

	++ignoreResched;
	int state = sceKernelSuspendDispatchThread();

	int base = sceDisplayGetVcount();
	int i, j;
	for (i = 0; i < 1000; ++i) {
		if (sceDisplayGetVcount() > base + 3) {
			break;
		}
		for (j = 0; j < 10000; ++j)
			continue;
	}

	dispatchCheckpoint("vblanks=%d", sceDisplayGetVcount() - base);

	sceKernelResumeDispatchThread(state);
	--ignoreResched;

	base = sceDisplayGetVcount();
	for (i = 0; i < 1000; ++i) {
		if (sceDisplayGetVcount() > base + 3) {
			break;
		}
		for (j = 0; j < 10000; ++j)
			continue;
	}
	
	dispatchCheckpoint("vblanks=%d", sceDisplayGetVcount() - base);

	sceKernelDisableSubIntr(PSP_VBLANK_INT, 0);
	sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT, 0);
	flushschedf();
}
Exemple #8
0
void dispatchCheckpoint(const char *format, ...) {
	int state = sceKernelSuspendDispatchThread();
	sceKernelResumeDispatchThread(state);

	schedf("[%s/%s] ", ignoreResched == 0 ? (didResched ? "r" : "x") : "?", state == 1 ? "y" : "n");

	if (ignoreResched == 0) {
		sceKernelTerminateThread(reschedThread);
	}

	va_list args;
	va_start(args, format);
	schedfBufferPos += vsprintf(schedfBuffer + schedfBufferPos, format, args);
	// This is easier to debug in the emulator, but printf() reschedules on the real PSP.
	//vprintf(format, args);
	va_end(args);

	schedf("\n");
	didResched = 0;
	if (ignoreResched == 0) {
		sceKernelStartThread(reschedThread, 0, NULL);
	}
}
int main(int argc, char *argv[])
{
    SceCtrlData pad;
    int oldButtons = 0;
#define SECOND	   1000000
#define REPEAT_START (1 * SECOND)
#define REPEAT_DELAY (SECOND / 5)
    struct timeval repeatStart;
    struct timeval repeatDelay;

    repeatStart.tv_sec = 0;
    repeatStart.tv_usec = 0;
    repeatDelay.tv_sec = 0;
    repeatDelay.tv_usec = 0;

    pspDebugScreenInit();
    pspDebugScreenPrintf("Press Cross to start the Task Scheduler Test\n");
    pspDebugScreenPrintf("Press Circle to start the CpuSuspendIntr/CpuResumeIntr Test\n");
    pspDebugScreenPrintf("Press Square to start the Task with thread of same priority\n");
    pspDebugScreenPrintf("Press Left to start the Task Dispatcher Test\n");
    pspDebugScreenPrintf("Press Triangle to Exit\n");

    while(!done)
    {
        sceCtrlReadBufferPositive(&pad, 1);
        int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons;

        if (pad.Buttons == oldButtons)
        {
            struct timeval now;
            gettimeofday(&now, NULL);
            if (repeatStart.tv_sec == 0)
            {
                repeatStart.tv_sec = now.tv_sec;
                repeatStart.tv_usec = now.tv_usec;
                repeatDelay.tv_sec = 0;
                repeatDelay.tv_usec = 0;
            }
            else
            {
                long usec = (now.tv_sec - repeatStart.tv_sec) * SECOND;
                usec += (now.tv_usec - repeatStart.tv_usec);
                if (usec >= REPEAT_START)
                {
                    if (repeatDelay.tv_sec != 0)
                    {
                        usec = (now.tv_sec - repeatDelay.tv_sec) * SECOND;
                        usec += (now.tv_usec - repeatDelay.tv_usec);
                        if (usec >= REPEAT_DELAY)
                        {
                            repeatDelay.tv_sec = 0;
                        }
                    }

                    if (repeatDelay.tv_sec == 0)
                    {
                        buttonDown = pad.Buttons;
                        repeatDelay.tv_sec = now.tv_sec;
                        repeatDelay.tv_usec = now.tv_usec;
                    }
                }
            }
        }
        else
        {
            repeatStart.tv_sec = 0;
        }

        if (buttonDown & PSP_CTRL_CROSS)
        {
            SceUID lowThid = sceKernelCreateThread("Low Prio Thread", threadLowPrio, 0x70, 0x1000, 0, 0);
            SceUID mediumThid = sceKernelCreateThread("Medium Prio Thread", threadMediumPrio, 0x30, 0x1000, 0, 0);
            SceUID highThid = sceKernelCreateThread("High Prio Thread", threadHighPrio, 0x10, 0x1000, 0, 0);
            SceUID busyThid = sceKernelCreateThread("Busy Thread", threadBusy, 0x30, 0x1000, 0, 0);
            testDone = 0;
            highPrioCounter = 0;
            mediumPrioCounter = 0;
            lowPrioCounter = 0;
            sceKernelStartThread(lowThid, 0, 0);
            sceKernelStartThread(mediumThid, 0, 0);
            sceKernelStartThread(busyThid, 0, 0);
            sceKernelStartThread(highThid, 0, 0);
            int totalDelay = 5000000;
            sceKernelDelayThread(totalDelay);
            testDone = 1;
            sceKernelWaitThreadEnd(busyThid, NULL);
            sceKernelWaitThreadEnd(mediumThid, NULL);
            sceKernelWaitThreadEnd(highThid, NULL);
            sceKernelWaitThreadEnd(lowThid, NULL);
            pspDebugScreenPrintf("Counters: high=%d (%d us), medium=%d, low=%d\n", highPrioCounter, (totalDelay / highPrioCounter), mediumPrioCounter, lowPrioCounter);
        }

        if (buttonDown & PSP_CTRL_CIRCLE)
        {
            msg = buffer;
            strcpy(msg, "");
            SceUID sleepingThid = sceKernelCreateThread("Sleeping Thread", sleepingThread, 0x10, 0x1000, 0, 0);
            sceKernelStartThread(sleepingThid, 0, 0);
            sceKernelDelayThread(100000);
            int intr = sceKernelCpuSuspendIntr();
            sceKernelWakeupThread(sleepingThid);
            strcat(msg, "Main Thread with disabled interrupts\n");
            sceKernelCpuResumeIntr(intr);
            strcat(msg, "Main Thread with enabled interrupts\n");
            pspDebugScreenPrintf("%s", msg);
        }

        if (buttonDown & PSP_CTRL_SQUARE)
        {
            msg = buffer;
            strcpy(msg, "");
            // Two threads having the same priority
            SceUID thread1 = sceKernelCreateThread("Thread 1", threadPrio_1, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0);
            SceUID thread2 = sceKernelCreateThread("Thread 2", threadPrio_2, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0);
            // Test that thread1 will be scheduled before thread2
            sceKernelStartThread(thread1, 0, 0);
            sceKernelStartThread(thread2, 0, 0);
            strcat(msg, "1 ");
            sceKernelDelayThread(10000);
            strcat(msg, "4");
            sceKernelWaitThreadEnd(thread1, NULL);
            sceKernelWaitThreadEnd(thread2, NULL);
            pspDebugScreenPrintf("Starting 2 threads at same priority: %s\n", msg);

            // Now with a different order for create & start
            strcpy(msg, "");
            SceUID thread3 = sceKernelCreateThread("Thread 3", threadPrio_3, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0);
            SceUID thread4 = sceKernelCreateThread("Thread 4", threadPrio_4, sceKernelGetThreadCurrentPriority(), 0x1000, 0, 0);
            // Test that thread4 will be scheduled before thread3
            sceKernelStartThread(thread4, 0, 0);
            sceKernelStartThread(thread3, 0, 0);
            strcat(msg, "1 ");
            sceKernelDelayThread(10000);
            strcat(msg, "4");
            sceKernelWaitThreadEnd(thread3, NULL);
            sceKernelWaitThreadEnd(thread4, NULL);
            pspDebugScreenPrintf("Starting 2 threads with a different order create/start: %s\n", msg);
        }

        if (buttonDown & PSP_CTRL_LEFT)
        {
            msg = buffer;
            strcpy(msg, "");
            int state = sceKernelSuspendDispatchThread();
            // High priority thread
            SceUID thread = sceKernelCreateThread("Thread 1", threadHello, 0x10, 0x1000, 0, 0);
            strcat(msg, "1 ");
            // sceKernelStartThread resumes the thread dispatcher
            sceKernelStartThread(thread, 0, 0);
            strcat(msg, "2 ");
            sceKernelDelayThread(10000);
            strcat(msg, "3 ");
            sceKernelResumeDispatchThread(state);
            sceKernelWaitThreadEnd(thread, NULL);
            pspDebugScreenPrintf("Starting high prio thread with a disabled dispatcher (state=0x%X): %s\n", state, msg);

            msg = buffer;
            strcpy(msg, "");
            state = sceKernelSuspendDispatchThread();
            // Low priority thread
            thread = sceKernelCreateThread("Thread 1", threadHello, 0x70, 0x1000, 0, 0);
            strcat(msg, "1 ");
            // sceKernelStartThread resumes the thread dispatcher
            sceKernelStartThread(thread, 0, 0);
            strcat(msg, "2 ");
            sceKernelDelayThread(10000);
            strcat(msg, "3 ");
            sceKernelResumeDispatchThread(state);
            sceKernelWaitThreadEnd(thread, NULL);
            pspDebugScreenPrintf("Starting low prio thread with a disabled dispatcher (state=0x%X): %s\n", state, msg);
        }

        if (buttonDown & PSP_CTRL_TRIANGLE)
        {
            done = 1;
        }

        oldButtons = pad.Buttons;
    }

    sceGuTerm();

    sceKernelExitGame();
    return 0;
}