mirror of
https://github.com/RPCS3/ps3autotests.git
synced 2024-11-09 12:22:33 +01:00
Test added: lv2/sys_semaphore
This commit is contained in:
parent
13c026c6cc
commit
c666d59f5a
185
tests/lv2/sys_semaphore/sys_semaphore.cpp
Normal file
185
tests/lv2/sys_semaphore/sys_semaphore.cpp
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <sys/timer.h>
|
||||||
|
#include <sys/sys_time.h>
|
||||||
|
#include <sys/ppu_thread.h>
|
||||||
|
#include <sys/synchronization.h>
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
sys_semaphore_t g_sem;
|
||||||
|
|
||||||
|
void semWait(uint64_t arg) {
|
||||||
|
if (sys_semaphore_wait(g_sem, arg)) {
|
||||||
|
printf("[!] sys_semaphore_wait: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
sys_ppu_thread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semWaitCheck(uint64_t arg) {
|
||||||
|
uint64_t dt;
|
||||||
|
uint64_t t0 = sys_time_get_system_time();
|
||||||
|
if (sys_semaphore_wait(g_sem, arg)) {
|
||||||
|
printf("[!] sys_semaphore_wait: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
dt = sys_time_get_system_time() - t0;
|
||||||
|
if (dt / 1000000 < 1) {
|
||||||
|
printf("[!] sys_semaphore_wait: Woke up too early!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
printf("sys_semaphore_wait: Thread woke up successfully\n");
|
||||||
|
sys_ppu_thread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semTrywait(uint64_t arg) {
|
||||||
|
if (sys_semaphore_trywait(g_sem)) {
|
||||||
|
printf("[!] sys_semaphore_trywait: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
sys_ppu_thread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semPost(uint64_t arg) {
|
||||||
|
sys_timer_sleep(1);
|
||||||
|
if (sys_semaphore_post(g_sem, arg) & ~0x8001000A) {
|
||||||
|
printf("[!] sys_semaphore_post: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
sys_ppu_thread_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int createThreadAndJoin(void (*func)(uint64_t), uint64_t arg=0) {
|
||||||
|
uint64_t val;
|
||||||
|
sys_ppu_thread_t thread;
|
||||||
|
std::size_t stackSize = 4096;
|
||||||
|
if (sys_ppu_thread_create(&thread, func, arg, 1500, stackSize, SYS_PPU_THREAD_CREATE_JOINABLE, "Worker")) {
|
||||||
|
printf("[!] sys_ppu_thread_create: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (sys_ppu_thread_join(thread, &val)) {
|
||||||
|
printf("[!] sys_ppu_thread_join: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int createThread(void (*func)(uint64_t), uint64_t arg=0) {
|
||||||
|
uint64_t val;
|
||||||
|
sys_ppu_thread_t thread;
|
||||||
|
std::size_t stackSize = 4096;
|
||||||
|
if (sys_ppu_thread_create(&thread, func, arg, 1500, stackSize, 0, "Worker")) {
|
||||||
|
printf("[!] sys_ppu_thread_create: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testSysSemaphoreErrors()
|
||||||
|
{
|
||||||
|
sys_semaphore_t sem; // Working semaphore
|
||||||
|
sys_semaphore_t sem_f; // Broken semaphore
|
||||||
|
sys_semaphore_attribute_t attr; // Initialized semaphore attribute
|
||||||
|
sys_semaphore_attribute_t attr_u; // Uninitialized semaphore attribute
|
||||||
|
sys_semaphore_attribute_initialize(attr);
|
||||||
|
sys_semaphore_value_t val;
|
||||||
|
|
||||||
|
// Create the working semaphore
|
||||||
|
if (sys_semaphore_create(&sem, &attr, 0, 1)) {
|
||||||
|
printf("[!] sys_semaphore_create: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error tests
|
||||||
|
printf("[*] Checking sys_semaphore_create errors:\n");
|
||||||
|
printf("sys_semaphore_create: max_val < 0 returns: 0x%x\n", sys_semaphore_create(&sem_f, &attr, 0, -1));
|
||||||
|
printf("sys_semaphore_create: max_val == 0 returns: 0x%x\n", sys_semaphore_create(&sem_f, &attr, 0, 0));
|
||||||
|
printf("sys_semaphore_create: initial_val < 0 returns: 0x%x\n", sys_semaphore_create(&sem_f, &attr, -1, 0));
|
||||||
|
printf("sys_semaphore_create: initial_val > max_val returns: 0x%x\n", sys_semaphore_create(&sem_f, &attr, 2, 1));
|
||||||
|
printf("sys_semaphore_create: &sem == NULL returns: 0x%x\n", sys_semaphore_create(NULL, &attr, 0, 1));
|
||||||
|
printf("sys_semaphore_create: &attr == NULL returns: 0x%x\n", sys_semaphore_create(&sem_f, NULL, 0, 1));
|
||||||
|
printf("sys_semaphore_create: uninitialized attr returns: 0x%x\n", sys_semaphore_create(&sem_f, &attr_u, 0, 1));
|
||||||
|
|
||||||
|
// Error tests
|
||||||
|
printf("\n[*] Checking sys_semaphore_get_value errors:\n");
|
||||||
|
printf("sys_semaphore_get_value: &val == NULL returns: 0x%x\n", sys_semaphore_get_value(sem, NULL));
|
||||||
|
printf("sys_semaphore_get_value: failed semaphore id returns: 0x%x\n", sys_semaphore_get_value(sem_f, &val));
|
||||||
|
printf("sys_semaphore_get_value: invalid semaphore id returns: 0x%x\n", sys_semaphore_get_value(NULL, &val));
|
||||||
|
|
||||||
|
printf("\n[*] Checking sys_semaphore_wait errors:\n");
|
||||||
|
printf("sys_semaphore_wait: short timeout returns: 0x%x\n", sys_semaphore_wait(sem, 1ULL));
|
||||||
|
printf("sys_semaphore_wait: failed semaphore id returns: 0x%x\n", sys_semaphore_wait(sem_f, 0ULL));
|
||||||
|
printf("sys_semaphore_wait: invalid semaphore id returns: 0x%x\n", sys_semaphore_wait(NULL, 0ULL));
|
||||||
|
|
||||||
|
printf("\n[*] Checking sys_semaphore_trywait errors:\n");
|
||||||
|
printf("sys_semaphore_trywait: semaphore value <= 0 returns: 0x%x\n", sys_semaphore_trywait(sem));
|
||||||
|
printf("sys_semaphore_trywait: failed semaphore id returns: 0x%x\n", sys_semaphore_trywait(sem_f));
|
||||||
|
printf("sys_semaphore_trywait: invalid semaphore id returns: 0x%x\n", sys_semaphore_trywait(NULL));
|
||||||
|
|
||||||
|
printf("\n[*] Checking sys_semaphore_post errors:\n");
|
||||||
|
printf("sys_semaphore_post: failed semaphore id returns: 0x%x\n", sys_semaphore_post(sem_f, 0));
|
||||||
|
printf("sys_semaphore_post: invalid semaphore id returns: 0x%x\n", sys_semaphore_post(NULL, 0));
|
||||||
|
printf("sys_semaphore_post: val < 0 returns: 0x%x\n", sys_semaphore_post(sem, -1));
|
||||||
|
printf("sys_semaphore_post: val > max_val returns: 0x%x\n", sys_semaphore_post(sem, 2));
|
||||||
|
|
||||||
|
// Destroy the working semaphore
|
||||||
|
if (sys_semaphore_destroy(sem)) {
|
||||||
|
printf("[!] sys_semaphore_destroy: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// More error tests
|
||||||
|
printf("\n[*] Checking sys_semaphore_destroy errors:\n");
|
||||||
|
printf("sys_semaphore_destroy: failed semaphore id returns: 0x%x\n", sys_semaphore_destroy(sem_f));
|
||||||
|
printf("sys_semaphore_destroy: invalid semaphore id returns: 0x%x\n", sys_semaphore_destroy(NULL));
|
||||||
|
printf("sys_semaphore_destroy: destroyed semaphore id returns: 0x%x\n", sys_semaphore_destroy(sem));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// Check errors on purpose
|
||||||
|
testSysSemaphoreErrors();
|
||||||
|
|
||||||
|
// Create the global semaphore
|
||||||
|
sys_semaphore_attribute_t attr;
|
||||||
|
sys_semaphore_attribute_initialize(attr);
|
||||||
|
if (sys_semaphore_create(&g_sem, &attr, 2, 2)) {
|
||||||
|
printf("[!] sys_semaphore_create: Something went wrong!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement semaphore: 2 -> 1 -> 0
|
||||||
|
sys_semaphore_value_t val;
|
||||||
|
printf("\n[*] Testing sys_semaphore_get_value and sys_semaphore_(try)wait:\n");
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
createThreadAndJoin(semWait, 0ULL);
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
createThreadAndJoin(semTrywait);
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
|
||||||
|
// Create 3 threads and wake 1 of them after 1 second
|
||||||
|
printf("\n[*] Testing sys_semaphore_post and sys_semaphore_wait:\n");
|
||||||
|
createThread(semWaitCheck, 0);
|
||||||
|
createThread(semWaitCheck, 0);
|
||||||
|
createThread(semWaitCheck, 900000000ULL); // 15 min timeout
|
||||||
|
createThreadAndJoin(semPost, 1);
|
||||||
|
sys_timer_sleep(2);
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
|
||||||
|
// Wake the 2 remaining threads after 1 second
|
||||||
|
createThreadAndJoin(semPost, 2);
|
||||||
|
sys_timer_sleep(2);
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
|
||||||
|
// Create 1 threads and post 30 to the semaphore after 1 second (it shouldn't wake up)
|
||||||
|
createThread(semWaitCheck, 0);
|
||||||
|
createThreadAndJoin(semPost, 30);
|
||||||
|
sys_timer_sleep(2);
|
||||||
|
sys_semaphore_get_value(g_sem, &val);
|
||||||
|
printf("sys_semaphore_get_value: 0x%x\n", val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
47
tests/lv2/sys_semaphore/sys_semaphore.expected
Normal file
47
tests/lv2/sys_semaphore/sys_semaphore.expected
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
[*] Checking sys_semaphore_create errors:
|
||||||
|
sys_semaphore_create: max_val < 0 returns: 0x80010002
|
||||||
|
sys_semaphore_create: max_val == 0 returns: 0x80010002
|
||||||
|
sys_semaphore_create: initial_val < 0 returns: 0x80010002
|
||||||
|
sys_semaphore_create: initial_val > max_val returns: 0x80010002
|
||||||
|
sys_semaphore_create: &sem == NULL returns: 0x8001000d
|
||||||
|
sys_semaphore_create: &attr == NULL returns: 0x8001000d
|
||||||
|
sys_semaphore_create: uninitialized attr returns: 0x80010002
|
||||||
|
|
||||||
|
[*] Checking sys_semaphore_get_value errors:
|
||||||
|
sys_semaphore_get_value: &val == NULL returns: 0x8001000d
|
||||||
|
sys_semaphore_get_value: failed semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_get_value: invalid semaphore id returns: 0x80010005
|
||||||
|
|
||||||
|
[*] Checking sys_semaphore_wait errors:
|
||||||
|
sys_semaphore_wait: short timeout returns: 0x8001000b
|
||||||
|
sys_semaphore_wait: failed semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_wait: invalid semaphore id returns: 0x80010005
|
||||||
|
|
||||||
|
[*] Checking sys_semaphore_trywait errors:
|
||||||
|
sys_semaphore_trywait: semaphore value <= 0 returns: 0x8001000a
|
||||||
|
sys_semaphore_trywait: failed semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_trywait: invalid semaphore id returns: 0x80010005
|
||||||
|
|
||||||
|
[*] Checking sys_semaphore_post errors:
|
||||||
|
sys_semaphore_post: failed semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_post: invalid semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_post: val < 0 returns: 0x80010002
|
||||||
|
sys_semaphore_post: val > max_val returns: 0x8001000a
|
||||||
|
|
||||||
|
[*] Checking sys_semaphore_destroy errors:
|
||||||
|
sys_semaphore_destroy: failed semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_destroy: invalid semaphore id returns: 0x80010005
|
||||||
|
sys_semaphore_destroy: destroyed semaphore id returns: 0x80010005
|
||||||
|
|
||||||
|
[*] Testing sys_semaphore_get_value and sys_semaphore_(try)wait:
|
||||||
|
sys_semaphore_get_value: 0x2
|
||||||
|
sys_semaphore_get_value: 0x1
|
||||||
|
sys_semaphore_get_value: 0x0
|
||||||
|
|
||||||
|
[*] Testing sys_semaphore_post and sys_semaphore_wait:
|
||||||
|
sys_semaphore_wait: Thread woke up successfully
|
||||||
|
sys_semaphore_get_value: 0x0
|
||||||
|
sys_semaphore_wait: Thread woke up successfully
|
||||||
|
sys_semaphore_wait: Thread woke up successfully
|
||||||
|
sys_semaphore_get_value: 0x0
|
||||||
|
sys_semaphore_get_value: 0x0
|
BIN
tests/lv2/sys_semaphore/sys_semaphore.ppu.elf
Normal file
BIN
tests/lv2/sys_semaphore/sys_semaphore.ppu.elf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user