Esempio n. 1
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();
}
Esempio n. 2
0
void displayBuffer(const char *reason) {
	sceKernelDcacheWritebackInvalidateAll();
	sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf));
	sceKernelDcacheWritebackInvalidateAll();
	const u32 *buf = copybuf;

	checkpoint(NULL);
	schedf("%s: ", reason);
	// This prevents drawing to the screen, which makes the test faster.
	HAS_DISPLAY = 0;
	for (int y = 0; y < 1; ++y) {
		for (int x = 0; x < 1; ++x) {
			// For the purposes of this test, ignore alpha.
			schedf("%06x", buf[y * 512 + x] & 0x00FFFFFF);
		}
		schedf("\n");
		flushschedf();
	}
	HAS_DISPLAY = 1;

	// Reset.
	memset(copybuf, 0, sizeof(copybuf));
	sceKernelDcacheWritebackInvalidateAll();
	sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf));
	sceKernelDcacheWritebackInvalidateAll();
}
Esempio n. 3
0
int main(int argc, char **argv) {
	int result;
	int check_not_update_value = 7;
	SceKernelSemaInfo info;
	
	sema = sceKernelCreateSema("sema1", 0, 0, 2, NULL);
	
	sceKernelReferSemaStatus(sema, &info);
	PRINT_SEMAPHORE(sema, info);
	
	threads[0] = sceKernelCreateThread("Thread-0", (void *)&threadFunction, 0x12, 0x10000, 0, NULL);
	threads[1] = sceKernelCreateThread("Thread-1", (void *)&threadFunction, 0x12, 0x10000, 0, NULL);
	threads[2] = sceKernelCreateThread("Thread-2", (void *)&threadFunction, 0x12, 0x10000, 0, NULL);
	threads[3] = sceKernelCreateThread("Thread-3", (void *)&threadFunction, 0x12, 0x10000, 0, NULL);
	threads[4] = sceKernelCreateThread("Thread-4", (void *)&threadFunction2, 0x12, 0x10000, 0, NULL);
	
	schedf("VALUE-INVARIANT:%d\n", check_not_update_value);
	
	sceKernelStartThread(threads[0], 1, (void*)&test[1]);
	sceKernelStartThread(threads[1], 2, NULL);
	sceKernelStartThread(threads[2], 0, (void*)&test[0]);
	sceKernelStartThread(threads[3], sizeof(int), (void*)&test[4]);
	sceKernelStartThread(threads[4], sizeof(int), &check_not_update_value);

	sceKernelDelayThread(10 * 1000);
	
	schedf("---\n");
	sceKernelReferSemaStatus(sema, &info);
	PRINT_SEMAPHORE(sema, info);
	schedf("---\n");
	sceKernelSignalSema(sema, 1);
	
	sceKernelDelayThread(10 * 1000);

	schedf("---\n");
	sceKernelReferSemaStatus(sema, &info);
	PRINT_SEMAPHORE(sema, info);
	schedf("---\n");

	sceKernelSignalSema(sema, 1);
	
	sceKernelDelayThread(10 * 1000);

	schedf("---\n");
	sceKernelReferSemaStatus(sema, &info);
	PRINT_SEMAPHORE(sema, info);
	schedf("---\n");
	
	result = sceKernelDeleteSema(sema);
	schedf("%08X\n", result);
	result = sceKernelDeleteSema(sema);
	schedf("%08X\n", result);
	
	schedf("VALUE-INVARIANT:%d\n", check_not_update_value);
	flushschedf();
	
	return 0;
}
Esempio n. 4
0
int main(int argc, char **argv) {
	SceUID sema = sceKernelCreateSema("wait1", 0, 1, 1, NULL);

	WAIT_TEST_SIMPLE("Signaled", sema, 1);
	WAIT_TEST_SIMPLE("Greater than max", sema, 100);
	WAIT_TEST_SIMPLE("Negative", sema, -1);

	sceKernelSignalSema(sema, 1);
	WAIT_TEST_SIMPLE_TIMEOUT("Signaled", sema, 1, 500);
	WAIT_TEST_SIMPLE_TIMEOUT("Never signaled", sema, 1, 500);
	WAIT_TEST_SIMPLE_TIMEOUT("Greater than max", sema, 100, 500);
	WAIT_TEST_SIMPLE_TIMEOUT("Zero", sema, 0, 500);
	WAIT_TEST_SIMPLE_TIMEOUT("Negative", sema, -1, 500);
	WAIT_TEST_SIMPLE_TIMEOUT("Zero timeout", sema, 1, 0);
	
	// Signaled off thread.
	printf("Wait timeout: ");
	schedulingPlacement = 1;
	SCHED_LOG(A, 1);
	SceUInt timeout = 5000;
	SceUID thread = sceKernelCreateThread("waitTest", (void *)&waitTestFunc, 0x12, 0x10000, 0, NULL);
	sceKernelStartThread(thread, sizeof(int), &sema);
	SCHED_LOG(B, 1);
	int result = sceKernelWaitSema(sema, 1, &timeout);
	SCHED_LOG(E, 1);
	schedf(" (thread=%08X, main=%08X, remaining=%d)\n", schedulingResult, result, timeout / 1000);
	flushschedf();

	sceKernelDeleteSema(sema);

	SceUID deleteThread = CREATE_SIMPLE_THREAD(deleteMeFunc);
	sema = sceKernelCreateSema("wait1", 0, 0, 1, NULL);
	sceKernelStartThread(deleteThread, sizeof(int), &sema);
	sceKernelDelayThread(500);
	sceKernelDeleteSema(sema);
	flushschedf();

	WAIT_TEST_SIMPLE("NULL", 0, 1);
	WAIT_TEST_SIMPLE("Invalid", 0xDEADBEEF, 1);
	WAIT_TEST_SIMPLE("Deleted", sema, 1);
	
	BASIC_SCHED_TEST("NULL",
		result = sceKernelWaitSema(0, 1, NULL);
	);
Esempio n. 5
0
void testDiff() {
	SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, 0, 0x10000, NULL);
	char *data1, *data2, *data3;
	sceKernelTryAllocateVpl(vpl, 0x08, (void **) &data1);
	sceKernelTryAllocateVpl(vpl, 0x10, (void **) &data2);
	sceKernelTryAllocateVpl(vpl, 0x01, (void **) &data3);

	schedf("Three 0x08s: diff=%x, %x\n", data1 - data2, data2 - data3);
	flushschedf();

	sceKernelDeleteVpl(vpl);
}
Esempio n. 6
0
int main(int argc, char **argv) {
	LOCK_TEST("Lock 0 => 0", PSP_MUTEX_ATTR_FIFO, 0, 0);
	LOCK_TEST("Lock 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1);
	LOCK_TEST("Lock 0 => 2", PSP_MUTEX_ATTR_FIFO, 0, 2);
	LOCK_TEST("Lock 0 => -1", PSP_MUTEX_ATTR_FIFO, 0, -1);
	LOCK_TEST("Lock 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1);
	LOCK_TEST("Lock 0 => 2 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 2);
	LOCK_TEST("Lock 0 => -1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, -1);
	LOCK_TEST("Lock 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1);
	LOCK_TEST("Lock 1 => INT_MAX - 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX - 1);
	LOCK_TEST("Lock 1 => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, INT_MAX);
	LOCK_TEST("Lock INT_MAX => INT_MAX (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, INT_MAX, INT_MAX);
	flushschedf();

	SceUID lockThread = CREATE_SIMPLE_THREAD(lockFunc);
	LOCK_TEST_THREAD("Locked 1 => 1", PSP_MUTEX_ATTR_FIFO, 1, 1);
	LOCK_TEST_THREAD("Locked 0 => 1", PSP_MUTEX_ATTR_FIFO, 0, 1);
	LOCK_TEST_THREAD("Locked 1 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 1, 1);
	LOCK_TEST_THREAD("Locked 0 => 1 (recursive)", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, 1);

	// Probably we can't manage to delete it at the same time.
	SceUID deleteThread = CREATE_SIMPLE_THREAD(deleteMeFunc);
	SceLwMutexWorkarea workarea;
	sceKernelCreateLwMutex(&workarea, "lock", 0, 1, NULL);
	void *workareaPtr = &workarea;
	sceKernelStartThread(deleteThread, sizeof(int), &workareaPtr);
	sceKernelDeleteLwMutex(&workarea);
	flushschedf();

	// Crashes.
	//LOCK_TEST_SIMPLE("NULL => 0", 0, 0);
	//LOCK_TEST_SIMPLE("NULL => 1", 0, 1);
	//LOCK_TEST_SIMPLE("Invalid => 1", (void*) 0xDEADBEEF, 1);
	LOCK_TEST_SIMPLE("Deleted => 1", &workarea, 1);
	
	BASIC_SCHED_TEST("Zero",
		result = sceKernelTryLockLwMutex(&workarea2, 0);
	);
Esempio n. 7
0
int main(int argc, char **argv) {
	SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, 0, 0x10000, NULL);
	void *data;

	testTryAlloc("More than free", vpl, 0xFFE1, 1);
	testTryAlloc("0 bytes", vpl, 0, 1);
	testTryAlloc("1 byte", vpl, 1, 1);
	testTryAlloc("-1 bytes", vpl, -1, 1);
	testTryAlloc("16 bytes", vpl, 16, 1);
	testTryAlloc("8 bytes", vpl, 8, 1);

	// Crashes.
	//testTryAlloc("Into NULL", vpl, 8, 0);

	testTryAlloc("Most remaining", vpl, 0xFF00, 1);
	testTryAlloc("More than remaining", vpl, 0xA1, 1);
	testTryAlloc("All remaining", vpl, 0xA0, 1);
	testTryAlloc("All remaining - 7", vpl, 0xA0 - 7, 1);
	testTryAlloc("All remaining - 8", vpl, 0xA0 - 8, 1);
	testTryAlloc("1 byte (none left)", vpl, 1, 1);

	sceKernelDeleteVpl(vpl);

	testTryAlloc("NULL", 0, 0x100, 1);
	testTryAlloc("NULL with invalid", 0, 0, 0);
	testTryAlloc("Invalid", 0xDEADBEEF, 0x100, 1);
	testTryAlloc("Deleted", vpl, 0x100, 1);
	flushschedf();

	testDiff();

	u32 attrs[] = {PSP_VPL_ATTR_FIFO, PSP_VPL_ATTR_PRIORITY, PSP_VPL_ATTR_SMALLEST, PSP_VPL_ATTR_HIGHMEM};
	int i;
	for (i = 0; i < sizeof(attrs) / sizeof(attrs[0]); ++i) {
		schedf("Attr %x:\n", attrs[i]);
		testTryAllocThread("  Alloc 0x20 of 0x00/0xE0", attrs[i], 0x20, 0xE0 - 0x08);
		testTryAllocThread("  Alloc 0x20 of 0x20/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08));
		testTryAllocThread("  Alloc 0x20 of 0x40/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08) * 2);
		schedf("\n");
	}

	BASIC_SCHED_TEST("Zero",
		result = sceKernelTryAllocateVpl(vpl1, 0, &data);
	);
Esempio n. 8
0
void displayBuffer(const char *reason) {
	sceKernelDcacheWritebackInvalidateAll();
	sceDmacMemcpy(copybuf, drawbuf, sizeof(copybuf));
	sceKernelDcacheWritebackInvalidateAll();
	const u32 *buf = copybuf;

	checkpoint(reason);
	// This prevents drawing to the screen, which makes the test faster.
	HAS_DISPLAY = 0;
	for (int y = 0; y < 272; ++y) {
		for (int x = 0; x < 480; ++x) {
			if (buf[y * 512 + x] != 0) {
				schedf("%x", buf[y * 512 + x]);
			} else {
				schedf(" ");
			}
		}
		schedf("\n");
		flushschedf();
	}
	HAS_DISPLAY = 1;
}
Esempio n. 9
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();
}
Esempio n. 10
0
void runReferTests() {
	SceKernelThreadInfo2 info;
	int i;
	SceUID delayThread = sceKernelCreateThread("delay", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, PSP_THREAD_ATTR_VFPU, NULL);
	SceUID deletedThread = sceKernelCreateThread("deleted", &delayFunc, sceKernelGetThreadCurrentPriority(), 0x1000, 0, NULL);
	sceKernelDeleteThread(deletedThread);

	info.size = sizeof(info);

	checkpointNext("Thread IDs:");
	checkpoint("  NULL: %08x", sceKernelReferThreadStatus(0, &info));
	checkpoint("  Current: %08x", sceKernelReferThreadStatus(sceKernelGetThreadId(), &info));
	checkpoint("  Deleted: %08x", sceKernelReferThreadStatus(deletedThread, &info));
	checkpoint("  Invalid: %08x", sceKernelReferThreadStatus(0xDEADBEEF, &info));

	// Crashes.
	//checkpointNext("sceKernelReferThreadStatus info ptr:");
	//checkpoint("  NULL info: %08x", sceKernelReferThreadStatus(0, NULL));

	checkpointNext("Sizes:");
	int sizes[] = {-1, 0, 1, 2, 3, 4, 5, 8, 16, 32, 64, 80, 82, 108, 128, 1024};
	for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
		memset(&info, 0xff, sizeof(info));
		info.size = sizes[i];
		int result = sceKernelReferThreadStatus(0, &info);
		checkpoint("  %d: %08x => %d (exit: %x)", sizes[i], result, info.size, info.exitStatus);
	}

	info.size = sizeof(info);
	sceKernelStartThread(delayThread, 0, NULL);
	sceKernelReferThreadStatus(delayThread, &info);
	checkpointNext("Values:");
	schedfThreadInfo(&info, &delayFunc);

	SceUID slumberThread = sceKernelCreateThread("slumber", &slumberFunc, sceKernelGetThreadCurrentPriority() - 1, 0x1000, 0, NULL);

	checkpoint("  slumber before start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelStartThread(slumberThread, 0, NULL);
	checkpoint("  started slumber");

	checkpoint("  slumber after start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelTerminateThread(slumberThread);
	checkpoint("  terminated slumber");

	checkpoint("  slumber after terminate:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelStartThread(slumberThread, 0, NULL);
	checkpoint("  started slumber");

	checkpoint("  slumber after start:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	checkpoint("  woke slumber: %08x", sceKernelWakeupThread(slumberThread));

	checkpoint("  slumber after wake:");
	sceKernelReferThreadStatus(slumberThread, &info);
	schedfThreadInfo(&info, &slumberFunc);

	sceKernelTerminateDeleteThread(slumberThread);
	checkpoint("  terminated and deleted slumber");

	// TODO: Test more cases.

	flushschedf();
}
Esempio n. 11
0
int main(int argc, char **argv) {
	SceUID vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, 0, 0x10000, NULL);
	void *data;

	schedf("No timeout:\n");
	testAlloc("  More than free", vpl, 0xFFE1, 1);
	testAlloc("  0 bytes", vpl, 0, 1);
	testAlloc("  1 byte", vpl, 1, 1);
	testAlloc("  -1 bytes", vpl, -1, 1);
	testAlloc("  16 bytes", vpl, 16, 1);
	testAlloc("  8 bytes", vpl, 8, 1);

	schedf("\nWith timeout:\n");
	testAllocTimeout("  More than free", vpl, 0xFFE1, 500, 1);
	testAllocTimeout("  0 bytes", vpl, 0, 500, 1);
	testAllocTimeout("  1 byte", vpl, 1, 500, 1);
	testAllocTimeout("  -1 bytes", vpl, -1, 500, 1);
	testAllocTimeout("  16 bytes", vpl, 16, 500, 1);
	testAllocTimeout("  8 bytes", vpl, 8, 500, 1);
	
	schedf("\nErrors:\n");
	// Crashes.
	//testAllocTimeout("Into NULL", vpl, 8, 500, 0);
	testAllocTimeout("  Into NULL", vpl, 0xFFE0, 500, 0);

	testAllocTimeout("  Most remaining", vpl, 0xFF00, 500, 1);
	testAllocTimeout("  More than remaining", vpl, 0xA1, 500, 1);
	testAllocTimeout("  All remaining", vpl, 0x68, 500, 1);
	testAllocTimeout("  All remaining - 7", vpl, 0x68 - 7, 500, 1);
	testAllocTimeout("  All remaining - 8", vpl, 0x68 - 8, 500, 1);
	testAllocTimeout("  1 byte (none left)", vpl, 1, 500, 1);
	testAllocTimeout("  1 byte (none left, 0 timeout)", vpl, 1, 0, 1);

	sceKernelDeleteVpl(vpl);

	testAllocTimeout("  NULL", 0, 0x100, 500, 1);
	testAllocTimeout("  NULL with invalid", 0, 0, 500, 0);
	testAllocTimeout("  Invalid", 0xDEADBEEF, 0x100, 500, 1);
	testAllocTimeout("  Deleted", vpl, 0x100, 500, 1);
	schedf("\n");

	testDiff();

	u32 attrs[] = {PSP_VPL_ATTR_FIFO, PSP_VPL_ATTR_PRIORITY, PSP_VPL_ATTR_SMALLEST, PSP_VPL_ATTR_HIGHMEM};
	int i;
	for (i = 0; i < sizeof(attrs) / sizeof(attrs[0]); ++i) {
		schedf("Attr %x:\n", attrs[i]);
		testAllocThread("  Alloc 0x10 of 0x00/0xE0", attrs[i], 0x20, 0xE0 - 0x08);
		testAllocThread("  Alloc 0x10 of 0x20/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08));
		testAllocThread("  Alloc 0x10 of 0x40/0xE0", attrs[i], 0x20, 0xE0 - 0x08 - (0x20 + 0x08) * 2);
		schedf("\n");
	}
	flushschedf();

	SceUID deleteThread = CREATE_SIMPLE_THREAD(deleteMeFunc);
	vpl = sceKernelCreateVpl("vpl", PSP_MEMORY_PARTITION_USER, 0, 0x10000, NULL);
	sceKernelAllocateVpl(vpl, 0x10000 - 0x20 - 0x08, &data, NULL);
	sceKernelStartThread(deleteThread, sizeof(SceUID), &vpl);
	sceKernelDeleteVpl(vpl);
	flushschedf();

	unsigned int timeout;
	BASIC_SCHED_TEST("Zero",
		timeout = 500;
		result = sceKernelAllocateVpl(vpl1, 0, &data, &timeout);
	);