Add synchronization mechanism for entering sleep mode.

When the APT status is APP_PREPARE_SLEEPMODE, the application main thread should call aptSignalReadyForSleep() to signal that it is ready to enter sleep mode, and then call aptWaitStatusEvent() as usual.

Example code:

APP_STATUS status;
while ((status = aptGetStatus()) != APP_EXITING)
{
	if(status==APP_RUNNING)
	{
		// application logic here
	}
	else if(status == APP_SUSPENDING)
	{
		aptReturnToMenu();
	}
	else if(status == APP_PREPARE_SLEEPMODE)
	{
		aptSignalReadyForSleep();
		aptWaitStatusEvent();
	}
}

This maybe isn't the proper/recommended way to do sleep mode, but I tested it multiple times and it always worked reliably.

(note: maybe the sample code above will not work if GPU drawing is done in a separate thread, haven't tested that)
This commit is contained in:
StapleButter 2014-09-18 22:09:15 +02:00
parent 6431810185
commit 1f413a7d44
2 changed files with 17 additions and 4 deletions

View File

@ -48,6 +48,7 @@ u32 aptGetStatusPower();//This can be used when the status is APP_SUSPEND* to ch
void aptSetStatusPower(u32 status); void aptSetStatusPower(u32 status);
void aptReturnToMenu();//This should be called by the user application when aptGetStatus() returns APP_SUSPENDING, not calling this will result in return-to-menu being disabled with the status left at APP_SUSPENDING. This function will not return until the system returns to the application, or when the status was changed to APP_EXITING. void aptReturnToMenu();//This should be called by the user application when aptGetStatus() returns APP_SUSPENDING, not calling this will result in return-to-menu being disabled with the status left at APP_SUSPENDING. This function will not return until the system returns to the application, or when the status was changed to APP_EXITING.
void aptWaitStatusEvent(); void aptWaitStatusEvent();
void aptSignalReadyForSleep();
NS_APPID aptGetMenuAppID(); NS_APPID aptGetMenuAppID();
Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle); Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle);

View File

@ -26,6 +26,7 @@ Handle aptStatusEvent = 0;
APP_STATUS aptStatus = APP_NOTINITIALIZED; APP_STATUS aptStatus = APP_NOTINITIALIZED;
APP_STATUS aptStatusBeforeSleep = APP_NOTINITIALIZED; APP_STATUS aptStatusBeforeSleep = APP_NOTINITIALIZED;
u32 aptStatusPower = 0; u32 aptStatusPower = 0;
Handle aptSleepSync = 0;
u32 aptParameters[0x1000/4]; //TEMP u32 aptParameters[0x1000/4]; //TEMP
@ -204,21 +205,24 @@ static void __handle_notification() {
case APTSIGNAL_PREPARESLEEP: case APTSIGNAL_PREPARESLEEP:
// Reply to sleep-request. // Reply to sleep-request.
aptStatusBeforeSleep = aptGetStatus(); aptStatusBeforeSleep = aptGetStatus();
aptSetStatus(APP_PREPARE_SLEEPMODE);
svcWaitSynchronization(aptSleepSync, U64_MAX);
svcClearEvent(aptSleepSync);
aptOpenSession(); aptOpenSession();
APT_ReplySleepQuery(NULL, currentAppId, 0x1); APT_ReplySleepQuery(NULL, currentAppId, 0x1);
aptCloseSession(); aptCloseSession();
aptSetStatus(APP_PREPARE_SLEEPMODE);
break; break;
case APTSIGNAL_ENTERSLEEP: case APTSIGNAL_ENTERSLEEP:
if(aptGetStatus() == APP_PREPARE_SLEEPMODE) if(aptGetStatus() == APP_PREPARE_SLEEPMODE)
{ {
// Report into sleep-mode. // Report into sleep-mode.
aptSetStatus(APP_SLEEPMODE);
aptOpenSession(); aptOpenSession();
APT_ReplySleepNotificationComplete(NULL, currentAppId); APT_ReplySleepNotificationComplete(NULL, currentAppId);
aptCloseSession(); aptCloseSession();
aptSetStatus(APP_SLEEPMODE);
} }
break; break;
@ -319,6 +323,7 @@ Result aptInit(void)
} }
svcCreateEvent(&aptStatusEvent, 0); svcCreateEvent(&aptStatusEvent, 0);
svcCreateEvent(&aptSleepSync, 0);
return 0; return 0;
} }
@ -345,6 +350,8 @@ void aptExit()
aptCloseSession(); aptCloseSession();
} }
svcCloseHandle(aptSleepSync);
svcCloseHandle(aptStatusMutex); svcCloseHandle(aptStatusMutex);
//svcCloseHandle(aptLockHandle); //svcCloseHandle(aptLockHandle);
svcCloseHandle(aptStatusEvent); svcCloseHandle(aptStatusEvent);
@ -421,7 +428,7 @@ void aptSetStatus(APP_STATUS status)
svcWaitSynchronization(aptStatusMutex, U64_MAX); svcWaitSynchronization(aptStatusMutex, U64_MAX);
prevstatus = status; prevstatus = aptStatus;
aptStatus = status; aptStatus = status;
if(prevstatus != APP_NOTINITIALIZED) if(prevstatus != APP_NOTINITIALIZED)
@ -461,6 +468,11 @@ void aptCloseSession()
svcReleaseMutex(aptLockHandle); svcReleaseMutex(aptLockHandle);
} }
void aptSignalReadyForSleep()
{
svcSignalEvent(aptSleepSync);
}
Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle) Result APT_GetLockHandle(Handle* handle, u16 flags, Handle* lockHandle)
{ {
if(!handle)handle=&aptuHandle; if(!handle)handle=&aptuHandle;