The extension gets calls for sleep and wake, and log them. Nothing else happens in the interim, other than (sometimes) some already-existing flows.
One thing to be aware of here is that the assignment of "blame" for things like sleep/wake activity is really messy. The basic cost of being "awake" is fairly high, so we need to track and assign "responsibility" to client that wake the system and/or generate activity while it's awake. However, architecturally it can be difficult to specifically identify what caused any given wake and, more importantly, the bigger concern* is generally about the OTHER work that occurred, not the direct cause of the wake. All of that means that I suspect that simply registering for these notifications will mean you carry some of the "blame", even if your activity is minimal.
*If we assumed that all wakes were essential and unavoidable **, then the primary optimization target is whatever "other" work is occurring, not the process that triggered the wake.
**I'm sure that this isn't the case on many systems, however, removing unnecessary wakes is basically a separate optimization.
The other daemons opt into IOKit's power notifications, and when sleep happens, they set it up so any timer-invoked actions just return immediately.
One thing I would look closely is that you consolidate as much activity as possible to a single thread. Depending on the API your using, that means either tying everything to the main thread runloop or using a single serial GCD queue for "everything". The risk here is that your process is waking up, doing a TINY amount of work on a bunch of thread, and then immediately going idle again. That's a case the system is specifically looking for and will penalize.
Note that this recommendation applies pretty broadly, particularly for daemons built around GCD. One of the issue dispatch creates (particularly using the global queues) is that it can make it feel very "natural" to casually send off very small amounts of work without ever thinking about thread behavior, which can be pretty bad for the overall system. Let me know if this is your situation and I can go into more detail.
The GUI app doesn't do anything special for sleep or wakeup, mainly because I wasn't sure what I should do. 😄
My main note here is to check your assumptions. This isn't even about sleep as such, it's simply checking "what's happening in your app when nothing is happening". The answer should be "nothing", but it's pretty common for the answer to be "a bunch of unnecessary nonsense".
Here is an example of what confuses me: the total is 500 units, but each of the windows has 0.0 units.
That's not what's going on there. It's showing the process hierarchy and the Energy Impact is per process, not cumulative. Also, not that "0.0" really means "didn't use significant power", not "didn't use ANY power".
Using Terminal.app as a convenient example, I have it open with a few windows, one of which is running "top". What Activity Monitor shows is:
Terminal.app = ~10
-> This is the normal app management "cost".
login = 0
-> login creates the environment the child shell operate in, but doesn't really "do" all that much.
tcsh = 0
-> Similar to login, the sheet interprets command line input and defines the environment the tools it launches operate in, but doesn't actually "do" all that much when another command is actively running.
top = ~100 -> ~150
-> This is basically polling the kernel for process state updates, so it's relatively "busy".
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware