Ejemplo n.º 1
0
Error
IOS_DestroySempahore(SemaphoreId id)
{
   auto semaphore = getSemaphore(id);
   if (!semaphore) {
      return Error::Invalid;
   }

   semaphore->count = 0;
   semaphore->maxCount = 0;

   // Add semaphore to the free semaphore linked list.
   auto index = static_cast<int16_t>(semaphore - phys_addrof(sData->semaphores));
   auto prevSemaphoreIndex = sData->lastFreeSemaphoreIndex;

   if (prevSemaphoreIndex >= 0) {
      auto prevSemaphore = phys_addrof(sData->semaphores[sData->lastFreeSemaphoreIndex]);
      prevSemaphore->nextFreeSemaphoreIndex = index;
   }

   semaphore->prevFreeSemaphoreIndex = prevSemaphoreIndex;
   semaphore->nextFreeSemaphoreIndex = int16_t { -1 };

   sData->lastFreeSemaphoreIndex = index;

   if (sData->firstFreeSemaphoreIndex < 0) {
      sData->firstFreeSemaphoreIndex = index;
   }

   internal::wakeupAllThreads(phys_addrof(semaphore->waitThreadQueue),
                              Error::Intr);
   internal::reschedule();
   return Error::Invalid;
}
Ejemplo n.º 2
0
Error
IOS_CreateSemaphore(int32_t maxCount,
                    int32_t initialCount)
{
   if (sData->firstFreeSemaphoreIndex < 0) {
      return Error::Max;
   }

   auto semaphore = phys_addrof(sData->semaphores[sData->firstFreeSemaphoreIndex]);
   auto semaphoreId = sData->firstFreeSemaphoreIndex;

   // Remove semaphore from free semaphore linked list
   sData->firstFreeSemaphoreIndex = semaphore->nextFreeSemaphoreIndex;

   if (semaphore->nextFreeSemaphoreIndex >= 0) {
      sData->semaphores[semaphore->nextFreeSemaphoreIndex].prevFreeSemaphoreIndex = int16_t { -1 };
   } else {
      sData->lastFreeSemaphoreIndex = int16_t { -1 };
   }

   semaphore->nextFreeSemaphoreIndex = int16_t { -1 };
   semaphore->prevFreeSemaphoreIndex = int16_t { -1 };

   sData->numCreatedSemaphores++;
   semaphore->id = static_cast<SemaphoreId>(semaphoreId | (sData->numCreatedSemaphores << 12));
   semaphore->count = initialCount;
   semaphore->maxCount = maxCount;
   semaphore->pid = internal::getCurrentProcessId();
   semaphore->unknown0x04 = nullptr;
   ThreadQueue_Initialise(phys_addrof(semaphore->waitThreadQueue));

   return static_cast<Error>(semaphore->id);
}
Error
startUsrCfgServiceThread()
{
   // Create message queue
   auto error = IOS_CreateMessageQueue(phys_addrof(sData->messageBuffer),
                                       static_cast<uint32_t>(sData->messageBuffer.size()));
   if (error < Error::OK) {
      return error;
   }
   sData->messageQueueId = static_cast<MessageQueueId>(error);

   // Register the device
   error = mcp::MCP_RegisterResourceManager("/dev/usr_cfg", sData->messageQueueId);
   if (error < Error::OK) {
      IOS_DestroyMessageQueue(sData->messageQueueId);
      return error;
   }

   // Create thread
   error = IOS_CreateThread(&usrCfgServiceThreadEntry, nullptr,
                            phys_addrof(sData->threadStack) + sData->threadStack.size(),
                            static_cast<uint32_t>(sData->threadStack.size()),
                            UCServiceThreadPriority,
                            ThreadFlags::Detached);
   if (error < Error::OK) {
      IOS_DestroyMessageQueue(sData->messageQueueId);
      return error;
   }

   sData->threadId = static_cast<ThreadId>(error);
   kernel::internal::setThreadName(sData->threadId, "UsrCfgServiceThread");

   return IOS_StartThread(sData->threadId);
}
Ejemplo n.º 4
0
Error
IOS_WaitSemaphore(SemaphoreId id,
                  BOOL tryWait)
{
   auto semaphore = getSemaphore(id);
   if (!semaphore) {
      return Error::Invalid;
   }

   if (semaphore->count <= 0 && tryWait) {
      return Error::SemUnavailable;
   }

   while (semaphore->count <= 0) {
      internal::sleepThread(phys_addrof(semaphore->waitThreadQueue));
      internal::reschedule();

      auto thread = internal::getCurrentThread();
      if (thread->context.queueWaitResult != Error::OK) {
         return thread->context.queueWaitResult;
      }
   }

   semaphore->count -= 1;
   return Error::OK;
}
Ejemplo n.º 5
0
Error
IOS_SignalSempahore(SemaphoreId id)
{
   auto semaphore = getSemaphore(id);
   if (!semaphore) {
      return Error::Invalid;
   }

   if (semaphore->count < semaphore->maxCount) {
      semaphore->count += 1;
   }

   internal::wakeupOneThread(phys_addrof(semaphore->waitThreadQueue), Error::OK);
   internal::reschedule();
   return Error::OK;
}
Ejemplo n.º 6
0
Error
startPpcThread()
{
   // Create thread
   auto error = IOS_CreateThread(&ppcThreadEntry, nullptr,
                                 phys_addrof(sPpcThreadData->threadStack) + sPpcThreadData->threadStack.size(),
                                 static_cast<uint32_t>(sPpcThreadData->threadStack.size()),
                                 PpcThreadPriority,
                                 ThreadFlags::Detached);
   if (error < Error::OK) {
      return error;
   }

   sPpcThreadData->threadId = static_cast<ThreadId>(error);
   kernel::internal::setThreadName(sPpcThreadData->threadId, "PpcThread");

   return IOS_StartThread(sPpcThreadData->threadId);
}