extern "C" int main(int argc, char *argv[]) { SceUID msgpipe = sceKernelCreateMsgPipe("delete", PSP_MEMORY_PARTITION_USER, 0, 0x100, NULL); testDelete("Normal", msgpipe); testDelete("NULL", 0); testDelete("Invalid", 0xDEADBEEF); testDelete("Deleted", msgpipe); { msgpipe = sceKernelCreateMsgPipe("delete", PSP_MEMORY_PARTITION_USER, 0, 0x100, NULL); MsgPipeReceiveWaitThread wait_r1("receiving thread 1", msgpipe, NO_TIMEOUT); MsgPipeReceiveWaitThread wait_r2("receiving thread 2", msgpipe, 10000); checkpoint("With receiving threads: %08x", sceKernelDeleteMsgPipe(msgpipe)); } { msgpipe = sceKernelCreateMsgPipe("delete", PSP_MEMORY_PARTITION_USER, 0, 0x100, NULL); // Send something to fill it up. char msg[256]; sceKernelSendMsgPipe(msgpipe, msg, sizeof(msg), 0, NULL, NULL); MsgPipeSendWaitThread wait_s1("sending thread 1", msgpipe, NO_TIMEOUT); MsgPipeSendWaitThread wait_s2("sending thread 2", msgpipe, 10000); checkpoint("With sending threads: %08x", sceKernelDeleteMsgPipe(msgpipe)); } return 0; }
int _sceTtyProxyDevWrite(SceIoIob *iob, const char *buf, int size) { dbg_printf("Calling %s\n", __FUNCTION__); int oldK1 = pspShiftK1(); int count = 0; int curCnt; int k1 = 0; if (sceIoGetIobUserLevel(iob) != 8) k1 = 24; // 0AC4 pspSetK1(k1); int size2 = g_pipeList[iob->fsNum + 3]; SceUID id = g_pipeList[iob->fsNum + 0]; // 0AE8 do { int minSize = size2; if (size2 >= size) minSize = size; int ret = sceKernelSendMsgPipe(id, (void*)buf, minSize, 0, &curCnt, 0); if (ret < 0) { pspSetK1(oldK1); return ret; } size -= curCnt; count += curCnt; buf += curCnt; } while (size != 0); pspSetK1(oldK1); return count; }
void testMsgPipeWithThreads() { int n; msgpipe = sceKernelCreateMsgPipe("MSGPIPE", 2, 0, sizeof(Message) * msgpipe_capacity, NULL); { // Create acceptor threads, that will receive messages. for (n = 0; n < msgpipe_threadcount; n++) { current_thread_id = n; sceKernelStartThread(sceKernelCreateThread("MSGPIPE_thread", (void *)&testMsgPipeWithThreads_thread, 0x12, 0x10000, 0, NULL), 0, NULL); } // Write all the messages. Message message = {1, 2, -1}; int messageSize; int result; for (n = 0; n < msgpipe_writecount; n++) { message.index = n; result = sceKernelSendMsgPipe(msgpipe, &message, sizeof(Message), 0, &messageSize, NULL); printf("SEND[%d] : %08X, %d, %d, %d\n", n, result, message.value1, message.value2, message.index); } } sceKernelDeleteMsgPipe(msgpipe); }
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; }