Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

linux

qt

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
    while(1){
        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
        start=end;
    }
    :: 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?

Update:

1) what is mem sleep?

https://www.kernel.org/doc/Documentation/power/states.txt

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.

like image 478
user3528438 Avatar asked Aug 19 '15 00:08

user3528438


1 Answers

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.

like image 145
wallyk Avatar answered Oct 03 '22 01:10

wallyk