How do timers work?

A

aaronfude

This is probably not a java specific question.

How, in principle, does Thread.sleep work?

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

Thanks!!!

Aaron Fude
 
R

Rhino

This is probably not a java specific question.

How, in principle, does Thread.sleep work?

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

Thanks!!!
Timers and how they work are discussed in the Java Tutorial -
http://java.sun.com/docs/books/tutorial/index.html.

I don't recall what trail they are in but if you do a search on Timer or
Thread you should find it pretty quickly.

Rhino
 
O

Oscar kind

This is probably not a java specific question.

How, in principle, does Thread.sleep work?

You specify the time your thread is to sleep, and after at least that
amount of time, your thread will run again. Depending on the priority of
your thread, the JVM, etc. this could be immediately.

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

Indeed: busy-waiting uses a lot of CPU power for mo good reason.

Personally, I prefer java.util.Timer over Thread.sleep:
- I hardly ever need to sleep a thread for any amount of time.
- More often, I need to have a task done periodically.

java.util.Timer starts a thread in the background (remember to make it a
daemon thread or it will prevent the JVM from exiting). This background
thread then starts a task after a specified delay, at a specified time,
every interval or with a specified interval in between. See the API for
more details.
 
W

Wiseguy

(e-mail address removed) scribbled on the stall wall:
This is probably not a java specific question.

How, in principle, does Thread.sleep work?

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

You are only missing one line in your pcode.

remember time
while (true) {
if (new time - old time > delay)
return;
yield_2_other_threads;
}
 
A

aaronfude

Wiseguy said:
(e-mail address removed) scribbled on the stall wall:

You are only missing one line in your pcode.

remember time
while (true) {
if (new time - old time > delay)
return;
yield_2_other_threads;
}

Supposing it's the only thread, how does the OS know to largely lead to
other processes? _Continuously_ checking the time since like an
intensive process.
 
A

Anthony Borla

This is probably not a java specific question.

How, in principle, does Thread.sleep work?

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

You'd only write code that way if:

* You were working in a single-tasking environment,
say like the MS-DOS system's of yesteryear, where
you were the only user, and your process the only
one executing, or

* You intended your process to 'hog' the computer
[more specifically, not let other processes use the
CPU] for the duration of the 'sleep' period

The reason for this is that to effect the 'sleep' action [i.e. to force a
delay for the specified period] your process has entered a 'busy loop' - it
does nothing except 'keep busy' looping and checking whether the specified
time period has expired. No useful work is performed during this period,
something that is generally considered a waste of computer resources.

As WiseGuy pointed out, you'd probably add a line of code much like this:

yield_2_other_threads;

This signals a higher-level process [in the case of a Java program, the JVM,
and in the case of an native code program, the scheduling mechanism of the
operating system] that your process will be busy for a while, and that
others are welcome to use the CPU. In this way the higher-level process
regains control, temporarily 'stops' your process, saving its 'state' so
that it may later be restarted in the same place, and allows other processes
to run. Of course, eventually, your process will be restarted, and continue
on its way, the cycle repeating until it terminates.

Obviously I've glossed over many issues - this is actually quite a complex
topic -, and the discussion is not Java-specific, but I hope a few things
are made clear:

* There is always a higher-level process in control, one of
its tasks being to cycle through the list of processes, and
ensure [among other things] each gets a fair share of CPU
time

* It is important to keep the CPU busy, but busy allowing all
processes to do useful work

* There is a degree of co-operation among processes [through
'yielding'] without which the CPU would likely be less
efficiently used

I hope this helps.

Anthony Borla
 
E

el_bandido

This is probably not a java specific question.

If you meant to ask how Thread.sleep() is implemented, then probably not.
How, in principle, does Thread.sleep work?

If I were to write it naively, I would write

remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

Unfortunately you can easily peek at SUNs implementation of the native
sleep() library call, however if you look how others did it, you might
get the idea (it can be depending on the JVM and the underlying
architecture):


from GNU classpath
------------------
static void sleep(long ms, int ns) throws InterruptedException
{

// Round up
ms += (ns != 0) ? 1 : 0;

// Note: JDK treats a zero length sleep is like Thread.yield(),
// without checking the interrupted status of the thread.
// It's unclear if this is a bug in the implementation or the spec.
// See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
if (ms == 0)
{
if (Thread.interrupted())
throw new InterruptedException();
return;
}

// Compute end time, but don't overflow
long now = System.currentTimeMillis();
long end = now + ms;
if (end < now)
end = Long.MAX_VALUE;

// A VM is allowed to return from wait() without notify() having been
// called, so we loop to handle possible spurious wakeups.
VMThread vt = Thread.currentThread().vmThread;
synchronized (vt)
{
while (true)
{
vt.wait(ms);
now = System.currentTimeMillis();
if (now >= end)
break;
ms = end - now;
}
}
}

and System.currentTimeMillis() is directly implemented as:

JNIEXPORT jlong JNICALL
Java_java_lang_VMSystem_currentTimeMillis
(JNIEnv * env __attribute__((__unused__)),
jclass thisClass __attribute__((__unused__)))
{
/* Note: this implementation copied directly from Japhar's, by Chris
Toshok. *
/
jlong result;
struct timeval tp;

if (gettimeofday(&tp, NULL) == -1)
(*env)->FatalError(env, "gettimeofday call failed.");

result = (jlong)tp.tv_sec;
result *= 1000;
result += (tp.tv_usec / 1000);

return result;
}

from JamVM
----------
int monitorWait(Monitor *mon, Thread *self, long long ms, int ns) {
char interrupted = 0;
int old_count;
char timed = (ms != 0) || (ns != 0);
struct timespec ts;

if(mon->owner != self)
return FALSE;

/* We own the monitor */

disableSuspend(self);

old_count = mon->count;
mon->count = 0;
mon->owner = NULL;
mon->waiting++;

if(timed) {
struct timeval tv;

gettimeofday(&tv, 0);

ts.tv_sec = tv.tv_sec + ms/1000;
ts.tv_nsec = (tv.tv_usec + ((ms%1000)*1000))*1000 + ns;

if(ts.tv_nsec > 999999999L) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000L;
}
}

[ ... a lot more code ... ]

It also implements the thread code using the NTPL framework, which is
rather Linux-centric, but fast.

Now in the Kaffe VM:
--------------------
The whole stuff is done with a lot of twists and turns and I'm not sure
if I got it right by browsing the source code ... after going through a
lot of code there is a function being called which listens to the happy
name currentTime():

static jlong currentTime(void) {
struct timeval tm;
gettimeofday(&tm, 0);
return (((jlong)tm.tv_sec * 1000L) + ((jlong)tm.tv_usec / 1000L));
}

So roughly summarise my sparse findings:

sleep() {
grab lock
disable soft interrupts
get time
while (not enough slept) {
schedule other threads
wait a bit
get time
add time
}
enble soft interrupts
release lock
}

If one was restricted to a specific platform only (extremely off-topic
for Java) the Thread.sleep() method could be implemented extremely
efficient and precise (e.g. RDTSC calls, local APIC timer or reading CPU
MSRs).

Take everything with a grain of salt. Cheers,
Roberto Nibali, ratz
 
A

Anthony Borla

Supposing it's the only thread, how does the OS know to
largely lead to other processes? _Continuously_ checking
the time since like an intensive process.

Whether there is one thread / process, or many, the the higher-level program
[be it JVM or operating system scheduler] is designed to cycle through them
and ensure each gets its fair share of CPU time.

In the case of one thread / process, it would still stop it, check for
others, and not finding others, would simply restart the stopped thread /
process.

Again, be mindful this is a conceptual description which glosses over many
issues and details.

I hope this helps.

Anthony Borla


have

Think of the
 
P

Paul van Rossem

This is probably not a java specific question.

How, in principle, does Thread.sleep work?

If I were to write it naively, I would write


remember time
while (true) {
if (new time - old time > delay)
return;
}

Obviously, this is not how.... Well, how then?

Thanks!!!

Aaron Fude
Just to add 1 more aspect that may not be obvious from the other replies:
1) the Java timer uses the system (windows / unix) timer function at its
lowest level, since you are working on a multi-user system and you don't
want to starve all other (non-Java) tasks on that machine.
2) the system timer on its turn uses the built-in hardware timer to
activate the scheduler and reschedule tasks whenever a higher priority
tasks unblocks. The scheduler is usually activated every xxx msecs (h/w
dependent) to check this (on a pre-emptive OS), or only when system
calls are made (on a non-pre-emptive OS).

So, usually there are no busy waiting loops involved whatsoever, since
that would always lead to some level of starvation (resulting in heavy
performance degradation). All such loops would at least at some point
call a system timer or scheduler.

Hope this answers your question (although a bit simplified),
Paul.
 
C

Chris Uppal

Paul said:
2) the system timer on its turn uses the built-in hardware timer to
activate the scheduler and reschedule tasks whenever a higher priority
tasks unblocks. The scheduler is usually activated every xxx msecs (h/w
dependent) to check this (on a pre-emptive OS), or only when system
calls are made (on a non-pre-emptive OS).

So, usually there are no busy waiting loops involved whatsoever,

Except by the hardware timer itself ;-)

It is impossible to implement a timed wait without /something/ doing a busy
loop, checking the time. The idea is that Java programmers should let the Java
implementation look after it, rather than doing it themselves. The Java
implementation in turn lets the OS look after it. And the OS passes it off to
specialised hardware that can do it without making everything else slow down.

But I'm only amplifying the point you make, not really disagreeing with you.

-- chris
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top