Skip to content

Commit

Permalink
Support 32bit iphb wakeup ranges
Browse files Browse the repository at this point in the history
The changes are compatible with pre-existing 16 bit wakeup ranges both
in API and socket protocol levels.

Adds new function iphb_wait2() that allows
* using 32bit values for wakeup ranges
* synchronizing wakeups without forcing resume from suspend

The previously existing iphb_wait() is kept for API compatibility, but
is now just a wrapper for iphb_wait2().

[libiphb] Support 32bit iphb wakeup ranges. Contributes to JB#16116
  • Loading branch information
spiiroin committed Mar 21, 2014
1 parent fd2d0f7 commit 2b43bf7
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 13 deletions.
29 changes: 21 additions & 8 deletions src/iphb_internal.h
Expand Up @@ -29,6 +29,7 @@
#define IPHB_INTERNAL_H

#include <sys/types.h>
#include <stdint.h>

#define HB_SOCKET_PATH "/dev/shm/iphb" /**@brief IPC path between client and iphbd */
#define HB_KERNEL_DEVICE "/dev/iphb" /**@brief Device between kernel module and iphbd */
Expand All @@ -44,16 +45,28 @@

/**@brief Message from client to iphbd ("wake me up") */
struct _iphb_wait_req_t {
unsigned short mintime; /*!< minimum wait time in seconds, zero means use default */
unsigned short maxtime; /*!< maximum wait time in seconds, zero means use default */
pid_t pid; /*!< client process ID (PID) */
uint16_t mintime; /*!< minimum wait time in seconds, zero means use default */
uint16_t maxtime; /*!< maximum wait time in seconds, zero means use default */
pid_t pid; /*!< client process ID (PID) */
// sizeof = 8

/* Since 1.1.0 */
unsigned char wakeup; /*!< Flag for use with dsme internal waits.
* If set to non-zero value, device will
* wakeup to handle the internal wakeup
* instead of handling it while woken up
* due to external activity. */
uint8_t wakeup; /*!< Flag for use with dsme internal waits.
* If set to non-zero value, device will
* wakeup to handle the internal wakeup
* instead of handling it while woken up
* due to external activity. */
// sizeof = 9


/* Since 1.2.0 */
uint8_t version; /*!< Request structure version:
* 0 < 1.2.0
* 1 >= 1.2.0
*/
uint16_t mintime_hi; /*!< Extend minimum wait time to 32bit range */
uint16_t maxtime_hi; /*!< Extend maximum wait time to 32bit range */
// sizeof = 14

/* Note: The size of this structure can grow up to 64 bytes without causing
* binary compatibility breaks, see struct _iphb_req_t below */
Expand Down
36 changes: 31 additions & 5 deletions src/libiphb.c
Expand Up @@ -166,7 +166,7 @@ iphb_get_fd(iphb_t iphbh)


time_t
iphb_wait(iphb_t iphbh, unsigned short mintime, unsigned short maxtime, int must_wait)
iphb_wait2(iphb_t iphbh, unsigned mintime, unsigned maxtime, int must_wait, int resume)
{
struct _iphb_req_t req = {IPHB_WAIT};
struct _iphb_wait_resp_t resp = {0};
Expand All @@ -178,12 +178,32 @@ iphb_wait(iphb_t iphbh, unsigned short mintime, unsigned short maxtime, int must

(void)suck_data(HB_INST(iphbh)->fd);

req.u.wait.mintime = mintime;
req.u.wait.maxtime = maxtime;
req.u.wait.pid = getpid();
/* There are apps that contain out of date libiphb versions built
* in to the application binaries and we need to at least attempt
* not to break handling of iphb requests that used to be ok. The
* required assumption is that such out of data code has initialized
* the padding in request structure to zero. */

/* Originally not used, should be implicitly initialized to zero */
req.u.wait.version = 1;

/* Originally mintime and maxtime were 16 bits wide. As we must
* keep the structure layout compatible with it, the extension
* to 32bit range is done by having upper halfs stored separately.
* The Server side ignores upper parts unless version >= 1. */
req.u.wait.mintime = (mintime >> 0) & 0xffff;
req.u.wait.mintime_hi = (mintime >> 16) & 0xffff;
req.u.wait.maxtime = (maxtime >> 0) & 0xffff;
req.u.wait.maxtime_hi = (maxtime >> 16) & 0xffff;

/* Client process id */
req.u.wait.pid = getpid();

/* The server side ignores this unless version >= 1 */
req.u.wait.wakeup = (resume != 0);

if (send(HB_INST(iphbh)->fd, &req, sizeof(req), MSG_DONTWAIT|MSG_NOSIGNAL) <= 0)
return (time_t)-1;
return (time_t)-1;

if (!must_wait)
return (time_t)0;
Expand Down Expand Up @@ -224,6 +244,12 @@ iphb_wait(iphb_t iphbh, unsigned short mintime, unsigned short maxtime, int must
return (time_t)-1;
}

time_t
iphb_wait(iphb_t iphbh, unsigned short mintime, unsigned short maxtime, int must_wait)
{
return iphb_wait2(iphbh, mintime, maxtime, must_wait, 1);
}


int
iphb_discard_wakeups(iphb_t iphbh)
Expand Down
37 changes: 37 additions & 0 deletions src/libiphb.h
Expand Up @@ -96,6 +96,43 @@ time_t
iphb_wait(iphb_t iphbh, unsigned short mintime, unsigned short maxtime, int must_wait);


/**
Wait for the next heartbeat.
There can be only one wakeup / iphb handle. Calling this function cancels
any previously programmed wakeup. Using zero for both mintime and maxtime
can be used to cancel without programming a new wakeup.
If mintime == maxtime, a global wakeup slot is used rather than ranged
wakeup. To maximize changes of synchronous wakeups the predefined
IPHB_GS_WAIT_* values should be used.
@param iphbh Handle got from iphb_open
@param mintime Time in seconds that MUST be waited before heartbeat
is reacted to.
@param maxtime Time in seconds when the wait SHOULD end. It is wise to
have maxtime-mintime quite big to maximize chances that
other iphb clients can be woken up in sync.
@param must_wait If non-zero, this functions waits for the wakeup before
returning. Zero value means you need to use select/poll
and wait for the socket to become readable. The file
descriptor to wait for can be queried via iphb_get_fd().
Once the socket comes readable, the incoming data must
be flushed - iphb_discard_wakeups can be used for this.
@param resume If nonzero, the device is woken from suspend to end the
wait period. Use zero value if the client process can
wait until the device gets out of suspend for some other
reason.
@return Time waited, (time_t)-1 if error (check errno)
*/
time_t
iphb_wait2(iphb_t iphbh, unsigned mintime, unsigned maxtime, int must_wait,
int resume);



Expand Down

0 comments on commit 2b43bf7

Please sign in to comment.