[SOLVED] How to know if system has just woken up from a mem sleep?


I have a Qt application that runs on Linux.

The user can switch the system to mem sleep using this application.

Switching to mem sleep is trivial, but catching the wake up event in user space isn’t.

My current solution is to use a infinite loop to trap the mem sleep, so that when the system wakes up, my application always continues from a predictable point.

Here is my code:

void MainWindow::memSleep()
    int fd;
    fd = ::open("/sys/power/state", O_RDWR);// see update 1)
    QTime start=QTime::currentTime();
    write(fd,"mem",3); // command that triggers mem sleep
        usleep(5000);  // delay 5ms
        const QTime &end=QTime::currentTime();// check system clock
        if(start.msecsTo(end)>5*2){// if time gap is more than 10ms
            break;         // it means this thread was frozen for more
        }                  // than 5ms, indicating a wake up after a sleep
    :: close(fd);          // the end of this function marks a wake up event

I described this method as a comment on this question, and it was pointed out that it’s not a good solution, which I agree.

Question: Is there a C API that I can use to catch the wake up event?


1) what is mem sleep?


The kernel supports up to four system sleep states generically, although three
of them depend on the platform support code to implement the low-level details
for each state.

The states are represented by strings that can be read or written to the
/sys/power/state file. Those strings may be “mem”, “standby”, “freeze” and
“disk”, where the last one always represents hibernation (Suspend-To-Disk) and
the meaning of the remaining ones depends on the relative_sleep_states command
line argument.

2) why do I want to catch the wake up event?

Because some hardware need to be reset after a wake up. A hardware input device generates erroneous input events after system wakes up, so it has to be disabled before sleep(easy) and enable after wake up(this question).

This should/could be handled by the driver in the kernel, which I have access to, or fixed in hardware, which my team can do but does not have the time to do it.(why I, a app developer, need to fix it in user space)

3) constraints

This is embedded linux, kernel 2.6.37, arch:arm, march:omap2, distro:arago. It’s not as convenient as PC distros to add packages, not does it have ACPI. And mem sleep support in kernel 2.6.37 isn’t mature at all.


Linux device drivers for PCI devices can optionally handle suspend and resume which, presumably, the kernel calls, respectively, just before the system is suspended, and just after resuming from a suspend. The PCI entrypoints are in struct pci_driver.

You could write and install a trivial device driver which does nothing more than sense resume operations and provides an indication to any interested processes. The simplest might be to support a file read() which returns a single byte whenever a resume is sensed. The program only need open the device and leave a thread stuck reading a single character. Whenever the read succeeds, the system just resumed.

More to the point, if the devices your application is handling have device drivers, the drivers should be updated to react appropriately to a resume.

Answered By – wallyk

Answer Checked By – David Goodson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *