Skip to content

Commit

Permalink
Merge pull request #7 from spiiroin/32bit_iphb_ranges
Browse files Browse the repository at this point in the history
Support 32bit iphb wakeup ranges
  • Loading branch information
spiiroin committed Mar 24, 2014
2 parents fd2d0f7 + aa6ffa7 commit 4c532ac
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 15 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
40 changes: 35 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,36 @@ 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.
*
* Originally the version field did not exist, but the area now
* occupied by it was initialized to zero. By setting it now to
* a non-zero value, we can signal the server side that additional
* fields are in use.
*
* Version 1 adds: mintime_hi, maxtime_hi and wakeup fields
*/
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 +248,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
12 changes: 10 additions & 2 deletions tests/hbtest3.c
Expand Up @@ -747,7 +747,7 @@ static bool hbtimer_start(hbtimer_t *self)
{
goto cleanup;
}
if( iphb_wait(self->iphb_hnd, self->mintime, self->maxtime, 0) < 0 )
if( iphb_wait2(self->iphb_hnd, self->mintime, self->maxtime, 0, 1) < 0 )
{
goto cleanup;
}
Expand Down Expand Up @@ -1103,8 +1103,16 @@ static void ranges_test(int *xc)
// | |
// group1 group2

/* start extra long timer, we do not expect this to trigger */
{
int d = 24 * 60 * 60;
hbtimer_t *t = hbtimer_create(d*3, d*4, 1);
t->repeats = 0;
timer[timers++] = t;
}

/* fail if tests do not finish in time */
timeout = g_timeout_add_seconds(scale(11) + 10, failure_cb, &timeout);
timeout = g_timeout_add_seconds(scale(11) + 13, failure_cb, &timeout);

if( mainloop_run() )
{
Expand Down

0 comments on commit 4c532ac

Please sign in to comment.