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)); }
void simpleTest() { int mutexid; printf("sceKernelCreateMutex:0x%08X\n", mutexid = sceKernelCreateMutex("test", PSP_MUTEX_ATTR_FIFO, 0)); { printf("sceKernelLockMutex:0x%08X\n", sceKernelLockMutex(mutexid, 1, NULL)); printf("sceKernelUnlockMutex:0x%08X\n", sceKernelUnlockMutex(mutexid, 1)); printf("sceKernelUnlockMutex:0x%08X\n", sceKernelUnlockMutex(mutexid, 1)); } printf("sceKernelDeleteMutex:0x%08X\n", sceKernelDeleteMutex(mutexid)); printf("sceKernelDeleteMutex:0x%08X\n", sceKernelDeleteMutex(mutexid)); }
static void client_list_thread_end() { ClientInfo *it, *next; SceUID client_thid; sceKernelLockMutex(client_list_mtx, 1, NULL); it = client_list; /* Iterate over the client list and close their sockets */ while (it) { next = it->next; client_thid = it->thid; /* Shutdown the client's control socket */ sceNetShutdown(it->ctrl_sockfd, PSP2_NET_SHUT_RDWR); /* Wait until the client threads ends */ sceKernelWaitThreadEnd(client_thid, NULL, NULL); it = next; } sceKernelUnlockMutex(client_list_mtx, 1); }
int terminateDeleteAllUserThreads() { SceKernelSemaInfo semaInfo; SceKernelThreadInfo threadInfo; globals_t *globals; int res; globals = getGlobals(); sceKernelLockMutex(globals->threadmgrMutex, 1, NULL); semaInfo.size = sizeof(semaInfo); res = sceKernelGetSemaInfo(globals->threadmgrSema, &semaInfo); if (res) return res; while (semaInfo.currentCount < semaInfo.maxCount) { res = sceKernelGetThreadInfo(globals->threadmgrTable[semaInfo.currentCount].uid, &threadInfo); if (res == 0 && (threadInfo.status == PSP2_THREAD_STOPPED || threadInfo.status == PSP2_THREAD_KILLED)) sceKernelDeleteThread(globals->threadmgrTable[semaInfo.currentCount].uid); else sceKernelNotifyCallback(globals->threadmgrTable[semaInfo.currentCount].exitDeleteCb, 0); semaInfo.currentCount++; } sceKernelUnlockMutex(globals->threadmgrMutex, 1); sceKernelWaitSema(globals->threadmgrSema, MAX_THREADS_NUM, NULL); sceKernelSignalSema(globals->threadmgrSema, MAX_THREADS_NUM); return 0; }
int hook_sceKernelExitDeleteThread(int res) { SceKernelSemaInfo info; globals_t *globals; SceUID uid; int i; globals = getGlobals(); uid = sceKernelGetThreadId(); DEBUG_PRINTF("Exiting thread 0x%08X (res: 0x%08X)", uid, res); sceKernelLockMutex(globals->threadmgrMutex, 1, NULL); info.size = sizeof(info); i = sceKernelGetSemaInfo(globals->threadmgrSema, &info); if (i == 0) { for (i = info.currentCount; i < info.maxCount; i++) { if (globals->threadmgrTable[info.currentCount].uid == uid) { if (i != info.currentCount) memcpy(globals->threadmgrTable + i, globals->threadmgrTable + info.currentCount, sizeof(thInfo_t)); sceKernelSignalSema(globals->threadmgrSema, 1); break; } } } sceKernelUnlockMutex(globals->threadmgrMutex, 1); sceKernelDelayThread(16384); return sceKernelExitDeleteThread(res); }
int lockThreadMutex(SceSize argc, void *argp) { SceUID mutex = *(SceUID *)argp; dispatchCheckpoint("T sceKernelLockMutex: %08x", sceKernelLockMutex(mutex, 2, NULL)); dispatchCheckpoint("T sceKernelDelayThread: %08x", sceKernelDelayThread(3000)); dispatchCheckpoint("T sceKernelUnlockMutex: %08x", sceKernelUnlockMutex(mutex, 1)); return 0; }
void recursiveTest() { int mutexid; printf("sceKernelCreateMutex:0x%08X\n", mutexid = sceKernelCreateMutex("test", PSP_MUTEX_ATTR_FIFO | PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0)); { printf("[0]sceKernelLockMutex:0x%08X\n", sceKernelLockMutex(mutexid, 1, NULL)); { printf("[1]sceKernelLockMutex:0x%08X\n", sceKernelLockMutex(mutexid, 1, NULL)); { printf("[2]sceKernelLockMutex:0x%08X\n", sceKernelLockMutex(mutexid, 1, NULL)); printf("[2]sceKernelUnlockMutex:0x%08X\n", sceKernelUnlockMutex(mutexid, 1)); } printf("[1]sceKernelUnlockMutex:0x%08X\n", sceKernelUnlockMutex(mutexid, 1)); } printf("[0]sceKernelUnlockMutex:0x%08X\n", sceKernelUnlockMutex(mutexid, 1)); } printf("sceKernelDeleteMutex:0x%08X\n", sceKernelDeleteMutex(mutexid)); printf("sceKernelDeleteMutex:0x%08X\n", sceKernelDeleteMutex(mutexid)); }
void console_print(const char *s) { int mtx_err = sceKernelTryLockMutex(console_mtx, 1); netprintf(s); if (mtx_err == SCE_KERNEL_OK) { sceKernelUnlockMutex(console_mtx, 1); } }
static int multipleTestThread(int argsize, void* argdata) { int n = *(int *)argdata; printf("multipleTest_t%d:[0]\n", n); sceKernelWaitSema(semaid, 1, NULL); sceKernelLockMutex(mutexid, 1, NULL); { sceKernelLockMutex(mutexid, 1, NULL); { printf("multipleTest_t%d:[A]\n", n); { sceKernelDelayThread(3000); } printf("multipleTest_t%d:[B]\n", n); } sceKernelUnlockMutex(mutexid, 1); } sceKernelUnlockMutex(mutexid, 1); //printf("multipleTest_t%d:[3]\n", n); return 0; }
SceUID hook_sceKernelCreateThread(const char *name, SceKernelThreadEntry entry, int initPriority, SceSize stackSize, SceUInt attr, int cpuAffinityMask, const SceKernelThreadOptParam *option) { SceKernelSemaInfo info; globals_t *globals; SceUID uid; int res; globals = getGlobals(); sceKernelLockMutexCB(globals->threadmgrMutex, 1, NULL); res = sceKernelPollSema(globals->threadmgrSema, 1); if (res) goto force; info.size = sizeof(info); res = sceKernelGetSemaInfo(globals->threadmgrSema, &info); if (res) goto force; uid = sceKernelCreateThread(name, hookEntry, initPriority, stackSize, attr, cpuAffinityMask, option); if (uid >= 0) { globals->threadmgrTable[info.currentCount].uid = uid; globals->threadmgrTable[info.currentCount].entry = entry; globals->threadmgrTable[info.currentCount].exitDeleteCb = SCE_KERNEL_ERROR_ERROR; } sceKernelUnlockMutex(globals->threadmgrMutex, 1); return uid; force: sceKernelUnlockMutex(globals->threadmgrMutex, 1); return sceKernelCreateThread(name, entry, initPriority, stackSize, attr, cpuAffinityMask, option); }
/*** * Callback the audio thread uses to see if we have enough available data. */ int audio_callback(void *buffer, unsigned int *length, void *userdata) { int i; int len = *length; sceKernelLockMutex(audio_mutex, 1, NULL); // see if we've buffered enough frames if (len <= curr_buffer_frames) { memcpy(buffer, &retro_audio_callback_buffer[0], len * 2 * sizeof(int16_t)); curr_buffer_frames -= len; memmove(&retro_audio_callback_buffer[0], &retro_audio_callback_buffer[len * 2], sizeof(int16_t) * 2 * curr_buffer_frames); sceKernelUnlockMutex(audio_mutex, 1); return len; } else { sceKernelUnlockMutex(audio_mutex, 1); return 0; } }
int sub_1026() { int ret = 0; volatile int* address = (int*)0xbfc00700; if (*address == 0) { ret = sceKernelTryLockMutex(meRpc.mutex, 1);//check to see if the me is in use if (ret >= 0) sceKernelUnlockMutex(meRpc.mutex, 1); } else if (*address != -1) *address = -2; return ret; }
static void client_list_delete(ClientInfo *client) { /* Remove the client from the client list */ sceKernelLockMutex(client_list_mtx, 1, NULL); if (client->prev) { client->prev->next = client->next; } if (client->next) { client->next->prev = client->prev; } sceKernelUnlockMutex(client_list_mtx, 1); }
void console_printf(const char *s, ...) { unsigned int mtx_timeout = 0xFFFFFFFF; sceKernelLockMutex(console_mtx, 1, &mtx_timeout); char buf[256]; va_list argptr; va_start(argptr, s); vsnprintf(buf, sizeof(buf), s, argptr); va_end(argptr); console_print(buf); sceKernelUnlockMutex(console_mtx, 1); }
static int hookEntry(SceSize args, void *argp) { SceKernelSemaInfo info; globals_t *globals; SceUID uid; int res; uid = sceKernelGetThreadId(); globals = getGlobals(); sceKernelLockMutexCB(globals->threadmgrMutex, 1, NULL); info.size = sizeof(info); res = sceKernelGetSemaInfo(globals->threadmgrSema, &info); if (res) goto fail; while (globals->threadmgrTable[info.currentCount].uid != uid) { if (info.currentCount >= info.maxCount) { res = SCE_KERNEL_ERROR_ERROR; goto fail; } info.currentCount++; } globals->threadmgrTable[info.currentCount].exitDeleteCb = sceKernelCreateCallback("vhlUserExitDeleteCb", 0, exitDeleteCb, NULL); sceKernelUnlockMutex(globals->threadmgrMutex, 1); return globals->threadmgrTable[info.currentCount].entry(args, argp); fail: sceKernelUnlockMutex(globals->threadmgrMutex, 1); return res; }
/*** * Audio callback for libretro. */ size_t retro_audio_sample_batch_callback(const int16_t *data, size_t frames) { sceKernelLockMutex(audio_mutex, 1, NULL); // make sure we don't overbuffer if (frames + curr_buffer_frames > AUDIO_SAMPLE_COUNT * 2) { frames = (AUDIO_SAMPLE_COUNT * 2) - curr_buffer_frames; } // store the data in our buffer memcpy(&retro_audio_callback_buffer[curr_buffer_frames * 2], data, frames * 2 * sizeof(int16_t)); curr_buffer_frames += frames; sceKernelUnlockMutex(audio_mutex, 1); return frames; }
static void client_list_add(ClientInfo *client) { /* Add the client at the front of the client list */ sceKernelLockMutex(client_list_mtx, 1, NULL); if (client_list == NULL) { /* List is empty */ client_list = client; client->prev = NULL; client->next = NULL; } else { client->next = client_list; client->next->prev = client; client->prev = NULL; client_list = client; } sceKernelUnlockMutex(client_list_mtx, 1); }
int sub_0x1000020(){ volatile int* address = (int*)0xbfc0070c; int first = *address; int second = *address; int* meTable = (int*)0xbfc00600; meTable[0] = 391;//same as sceMePower_driver_E9F69ACF meTable[2] = (first & 0x1ff0000)>>16; meTable[3] = second & 0x1ff; meTable[4] = 0; meTable[5] = 0; meTable[6] = 0; meTable[7] = 0; meTable[8] = 0; meTable[9] = 0; sceDdrFlush(5); sceSysregInterruptToOther(); sceKernelWaitEventFlag(meRpc.event, 1, SCE_EVENT_WAITCLEAR, 0, 0); sceKernelUnlockMutex(meRpc.mutex, 1); return 0; }
//0x000000F8 s32 sceClockgenSetSpectrumSpreading(s32 mode) { s32 regSS; s32 ret; s32 res; if (mode < 0) { /* Invalid argument, try to restore the initial spread-spectrum state. */ regSS = g_Cy27040.oldReg[PSP_CY27040_REG_SS] & 0x7; ret = mode; if (regSS == (g_Cy27040.curReg[PSP_CY27040_REG_SS] & 0x7)) return ret; } else { /* Choose a value according to the Cy27040 revision. */ switch(g_Cy27040.curReg[PSP_CY27040_REG_REVISION] & 0xF) { case 0x8: case 0xF: case 0x7: case 0x3: case 0x9: case 0xA: if (mode < 2) { regSS = 0; ret = 0; } else if (mode < 7) { regSS = 1; ret = 5; } else if (mode < 15) { regSS = 2; ret = 10; } else if (mode < 25) { regSS = 4; ret = 20; } else { regSS = 6; ret = 30; } break; case 0x4: if (mode < 2) { regSS = 0; ret = 0; } else if (mode < 7) { regSS = 1; ret = 5; } else if (mode < 12) { regSS = 2; ret = 10; } else if (mode < 17) { regSS = 3; ret = 15; } else if (mode < 22) { regSS = 4; ret = 20; } else if (mode < 27) { regSS = 5; ret = 25; } else { regSS = 6; ret = 30; } break; default: return SCE_ERROR_NOT_SUPPORTED; } } /* Try to update the spread-spectrum register. */ res = sceKernelLockMutex(g_Cy27040.mutex, 1, 0); if (res < 0) return res; g_Cy27040.curReg[PSP_CY27040_REG_SS] = (regSS & 7) | (g_Cy27040.curReg[PSP_CY27040_REG_SS] & ~7); res = _cy27040_write_register(PSP_CY27040_REG_SS, g_Cy27040.curReg[PSP_CY27040_REG_SS]); sceKernelUnlockMutex(g_Cy27040.mutex, 1); if (res < 0) return res; return ret; }
int sceKermit_driver_4F75AA05(u8 *data, u32 cmd_mode, u32 cmd, u32 argc, u32 allow_callback, u8 *resp) { /* check if we are not accepting kermit calls */ if (!g_enable_kermit) { /* wait 10ms */ sceKernelDelayThread(10 * 1000); return 0; } /* lock the mutex, no timeout */ sceKernelLockMutex(g_mutex_id, 1, NULL); /* update counter */ g_active_connections++; /* release the mutex */ sceKernelUnlockMutex(g_mutex_id, 1); /* use specific ID on modes KERMIT_MODE_AUDIO and mode 6. This is to improve parallelism and async */ if (cmd_mode == KERMIT_MODE_AUDIO) proc_n = 1; else if (cmd_mode == 6) proc_n = 2; else proc_n = 0; /* construct sema timeout of 5 seconds */ u32 timeout = 5 * 1000 * 1000; /* wait on sema */ int res = sceKernelWaitSema(g_access_sema[proc_n], 1, &timeout); /* check if we error'd */ if (res != 0) { /* go the the clean up code */ goto exit; } /* read the message pipe */ res = sceKernelReceiveMsgPipe(g_pipe_id, &sema_id, sizeof(SceUID), 0, 0, 0); /* check if error occured */ if (res != 0) { /* error, clean up and exit */ goto exit; } /* now set the command number */ g_command[proc_n].cmd_type = (cmd_mode << 16) | cmd; /* DMA align the arg count. Max = 16 args */ u32 packet_size = ((argc + sizeof(u64) + 1) & 0xFFFFFFF8) * sizeof(u64); /* store packet info */ packet.cmd = cmd; packet.sema_id = sema_id; packet.self = packet; /* send data to kermit */ g_command[proc_n].kermit_addr = sub_00000A98(packet, packet_size); /* wait? */ sub_00000908(); /* lock the power, prevent shutdown */ res = sceKernelPowerLock(0); /* check if error occured */ if (res != 0) { /* error, clean up and exit */ goto exit; } /* suspend cpu interrupts */ int intr = sceKernelCpuSuspendIntr(); /* signal low, then high for the process */ PIN_LOW(0xBC300050, proc_n + 4); PIN_HIGH(0xBC300050, proc_n + 4); /* resume the CPU interrupts */ sceKernelCpuResumeIntr(intr); /* check for callback permitting process */ if (allow_callback) sceKernelWaitSemaCB(sema_id, 1, NULL); else sceKernelWaitSema(sema_id, 1, NULL); /* send sema id back into pipe, act as a circular queue */ sceKernelSendMsgPipe(g_pipe_id, &sema_id, sizeof(SceUID), 0, 0, 0); /* now, check if there is a response */ if (resp) { /* copy data from packet to response */ ((u64 *)resp)[0] = ((u64 *)packet)[0]; } /* unlock power */ res = sceKernelPowerUnlock(0); /* exit and cleanup code */ exit: /* lock mutex for exclusive access, no timeout */ sceKernelLockMutex(g_mutex_id, 1, NULL); /* update counter */ g_active_connections--; /* release the mutex */ sceKernelUnlockMutex(g_mutex_id, 1); /* check result */ if (res >= 0) res = 0; /* return result */ return res; }