Clock Pulse?

L

luserXtrog

Does anyone have any advice on how best to call a function
once a minute to change a clock face?

My thought so far is:
{ time_t tt;
struct tm *ptm;
time(&tt);
ptm = localtime(&tt);
sleep /* sleep is posix, isn't it? */
(ptm->tm_sec);
while(1) {
my_func();
sleep(60);
}
}

Without posix, would I have to do a busy loop?
 
C

Chris M. Thomasson

luserXtrog said:
Does anyone have any advice on how best to call a function
once a minute to change a clock face?

My thought so far is:
{ time_t tt;
struct tm *ptm;
time(&tt);
ptm = localtime(&tt);
sleep /* sleep is posix, isn't it? */
(ptm->tm_sec);
while(1) {
my_func();
sleep(60);
}
}

You're not taking the return value of `sleep()' into account. IIRC, you need
something along the lines of:
________________________________________________________________
void
sleep_foo(unsigned int seconds)
{
while ((seconds = sleep(seconds)));
}


void
clock_update(void)
{
for (;;)
{
sleep_foo(60);

my_func();
}
}
________________________________________________________________



Without posix, would I have to do a busy loop?

Not if you used some other OS specific primitive. Otherwise, yes.
 
J

James Dow Allen

Does anyone have any advice on how best to call a function
once a minute to change a clock face?
... [snip] ...
        sleep(60);

It may seem like a nit, but you should handle the case where
other applications delay your scheduling. In other words,
if an extra second has elapsed, call sleep(59) for next time.

The Sun/BSD iostat program had this (and other) bug(s),
meaning that its output was very misleading in the most
interesting (heavy load) cases.

James
 
C

Chris M. Thomasson

Does anyone have any advice on how best to call a function
once a minute to change a clock face?
... [snip] ...
sleep(60);
It may seem like a nit, but you should handle the case where
other applications delay your scheduling. In other words,
if an extra second has elapsed, call sleep(59) for next time.
The Sun/BSD iostat program had this (and other) bug(s),
meaning that its output was very misleading in the most
interesting (heavy load) cases.

Oh boy! I have observed, and had to correct, many codes with a __very__
similar error... Think of something along the lines of:
_____________________________________________
void
foo_wait(sem_t* s)
{
sem_wait(s);
}
_____________________________________________




Wow! What a massive and horrific bug!!!!!




Huston, we have a problem!


;^o
 
L

luserXtrog

Does anyone have any advice on how best to call a function
once a minute to change a clock face?
 ... [snip] ...
sleep(60);
It may seem like a nit, but you should handle the case where
other applications delay your scheduling.  In other words,
if an extra second has elapsed, call sleep(59) for next time.
The Sun/BSD iostat program had this (and other) bug(s),
meaning that its output was very misleading in the most
interesting (heavy load) cases.

Oh boy! I have observed, and had to correct, many codes with a __very__
similar error... Think of something along the lines of:
_____________________________________________
void
foo_wait(sem_t* s)
{
    sem_wait(s);}

_____________________________________________

Wow! What a massive and horrific bug!!!!!

Huston, we have a problem!

;^o

I don't understand.
How would one wait for a semaphore without waiting for
a semaphore?
Are you making some comment about making assumptions
about the 'context'[1] during execution?

At the risk of spoiling the joke, could you elaborate?

[1] in the layman sense of "everything else that's going on".
 
C

Chris M. Thomasson

Oh boy! I have observed, and had to correct, many codes with a __very__
similar error... Think of something along the lines of:
_____________________________________________
void
foo_wait(sem_t* s)
{
sem_wait(s);}

_____________________________________________

Wow! What a massive and horrific bug!!!!!

Huston, we have a problem!

;^o
I don't understand.
How would one wait for a semaphore without waiting for
a semaphore?
Are you making some comment about making assumptions
about the 'context'[1] during execution?
At the risk of spoiling the joke, could you elaborate?
[1] in the layman sense of "everything else that's going on".

Read here first:


http://www.opengroup.org/onlinepubs/7990989775/xsh/sem_wait.html


Then try and think about what would happen if `sem_wait()' returns `EINTR'
and the program responds to this event as if it were a legitimate decrement
on the semaphore value...
 
L

luserXtrog

[...]


Oh boy! I have observed, and had to correct, many codes with a __very__
similar error... Think of something along the lines of:
_____________________________________________
void
foo_wait(sem_t* s)
{
sem_wait(s);}

Wow! What a massive and horrific bug!!!!!
Huston, we have a problem!
;^o
I don't understand.
How would one wait for a semaphore without waiting for
a semaphore?
Are you making some comment about making assumptions
about the 'context'[1] during execution?
At the risk of spoiling the joke, could you elaborate?
[1] in the layman sense of "everything else that's going on".

Read here first:

http://www.opengroup.org/onlinepubs/7990989775/xsh/sem_wait.html

Then try and think about what would happen if `sem_wait()' returns `EINTR'
and the program responds to this event as if it were a legitimate decrement
on the semaphore value...

so it should be more like:

void foo_wait (sem_t *s) {
int ret;
do {
ret = sem_wait(s);
} while (ret == -1 && errno == EINTR);
}

?
 
C

Chris M. Thomasson

[...]


Oh boy! I have observed, and had to correct, many codes with a
__very__
similar error... Think of something along the lines of:
_____________________________________________
void
foo_wait(sem_t* s)
{
sem_wait(s);}

Wow! What a massive and horrific bug!!!!!
Huston, we have a problem!
;^o
I don't understand.
How would one wait for a semaphore without waiting for
a semaphore?
Are you making some comment about making assumptions
about the 'context'[1] during execution?
At the risk of spoiling the joke, could you elaborate?
[1] in the layman sense of "everything else that's going on".

Read here first:

http://www.opengroup.org/onlinepubs/7990989775/xsh/sem_wait.html

Then try and think about what would happen if `sem_wait()' returns
`EINTR'
and the program responds to this event as if it were a legitimate
decrement
on the semaphore value...
______________________________________________________
so it should be more like:
void foo_wait (sem_t *s) {
int ret;
do {
ret = sem_wait(s);
} while (ret == -1 && errno == EINTR);
}
______________________________________________________


That can still let some error's go by. Since the procedure `foo_wait()' does
not return anything, I would do it like:
______________________________________________________
void
foo_wait(sem_t* s)
{
int status;

while ((status = sem_wait(s)))
{
if (errno != EINTR)
{
assert(errno == EINTR);
abort();
}
}
}
______________________________________________________




That should get the point across... ;^)




Or, perhaps we should let the caller handle the error and turn `foo_wait()'
into a function:
______________________________________________________
int
foo_wait(sem_t* s)
{
int status;

while ((status = sem_wait(s)))
{
if (errno != EINTR)
{
return errno;
}
}

return 0;
}
______________________________________________________




Now, if `foo_wait()' returns zero, that means the semaphore was actually
decremented.


:^)
 
N

Nobody

Does anyone have any advice on how best to call a function
once a minute to change a clock face?

My thought so far is:
{ time_t tt;
struct tm *ptm;
time(&tt);
ptm = localtime(&tt);
sleep /* sleep is posix, isn't it? */
(ptm->tm_sec);
while(1) {
my_func();
sleep(60);
}
}

Don't rely upon sleep() sleeping for exactly the specified time. Instead,
call sleep() repeatedly until you reach the desired point in time, e.g.:

for (;;) {
struct tm next_tm;
time_t now, next;
int diff;

time(&now);
next_tm = *localtime(&now);
next_tm.tm_sec = 0;
/* this may reach 60, but mktime() will normalise it */
next_tm.tm_min++;
next = mktime(&next_tm);

while (diff = (int) floor(difftime(&next, &now)), diff > 0) {
sleep(diff);
time(&now);
}

/* we are now (approximately) at the minute mark */
}
Without posix, would I have to do a busy loop?

If all you have available is the ANSI C standard library, then you would
need a busy loop.

Note that if you are assuming POSIX, the above code can be simplified
slightly based upon the fact that POSIX specifies time_t as an integer
representing seconds since the epoch, so you can manipulate time_t values
directly without neededing to use mktime() or difftime().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top