View mode: basic / threaded / horizontal-split · Log in · Help
January 27, 2007
Implementing a timer using threads
Hi,

i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):

class Timer: Thread
{
       int run()
       {
               while(true)
               {
                       this.wait(1000); // wait one second
                       writefln("one second passed");
               }
               return 0;
       }
}

But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).

regards
Dennis
January 29, 2007
Re: Implementing a timer using threads
Dennis Kempin Wrote:

> Hi,
> 
> i just started to learn D (have been using c++ or java up to now) and am
> wondering how to implement some kind of timer, a thread that calls a
> delegate every n seconds.
> This was my first idea (without flags for stopping the timer etc):
> 
> class Timer: Thread
> {
>         int run()
>         {
>                 while(true)
>                 {
>                         this.wait(1000); // wait one second
>                         writefln("one second passed");
>                 }
>                 return 0;
>         }
> }
> 
> But writefln never gets executed, because this.wait is used to wait for
> other threads than the current one. Is there any other way to get let
> Thread sleep for some seconds (I know that there is a Sleep function for
> Win32, but a platform independend way would be very great).
> 
> regards
> Dennis

You could insert a block of asm code. Look here http://www.digitalmars.com/d/iasm.html for valid opcodes.
Here http://www.acm.uiuc.edu/sigmil/talks/shellcode/sleep.asm is an approach.

This method is platform independant but not architecture independant, anyway, most computers processors are x86.

Good luck.
January 29, 2007
Re: Implementing a timer using threads
Heinz wrote: 
> You could insert a block of asm code. Look here
> http://www.digitalmars.com/d/iasm.html for valid opcodes. Here
> http://www.acm.uiuc.edu/sigmil/talks/shellcode/sleep.asm is an approach.
> 
> This method is platform independant but not architecture independant,
> anyway, most computers processors are x86.
> 
> Good luck.

Hi Heinz,

thanks for your reply. I tried the following solution:
int timerFunction()
{
       while(true)
       {
               writefln("a");
               asm
               {
                       xor EAX,EAX;
                       mov EBX,0x77e61bea;
                       mov AX,1000;
                       push EAX;
                       call EBX;
               }

       }
       return 0;
}
but the result is a crash without any error message or warning. As the
comment of the asm code says "windows shellcode" i think it simply uses the
windows internel Sleep method. Still no way to make the thread go sleep in
linux.
Maybe I just should use linux/windows c API methods and insert a platform
fork. I will report here if i got a working solution.. Maybe I am not the
only one who needs timing. 

regards
Dennis
January 29, 2007
Re: Implementing a timer using threads
okay here we go, i have a simple conditional compilation added to use
windows Sleep or linux usleep function.
Maybe someone has use for this simple class. You can decide if the timed
event shall be called once or forever until the process/thread is
terminated.

I have not tested this in windows but it "should" work ;)

regards Dennis

import std.thread;

version(Windows)
{
       extern (C)
       {
               void Sleep(int);        
       }
}

version(linux)
{
       extern (C)
       {
               void usleep(int);       
       }
}

class Timer: Thread
{
       private void delegate() action;
       private int waitTime;
       private bit autoRestart;

       this(int waitTime, void delegate() action, bit autoRestart=false)
       {
               this.action = action;
               this.waitTime = waitTime;
               this.autoRestart = autoRestart;
       }

       protected this(int waitTime, bit autoRestart=false)
       {
               this.waitTime = waitTime;
               this.autoRestart = autoRestart;
       }

       override int run()
       {
               sleep(waitTime);
               execute();
               while(autoRestart)
               {
                       sleep(waitTime);
                       execute();
               }
               return 0;
       }

       void execute()
       {
               action();
       }

       private void sleep(int time)
       {
               version(Windows)
               {
                       Sleep(time);
               }
               
               version(linux)
               {
                       usleep(time*1000);
               }
       }
}
January 29, 2007
Re: Implementing a timer using threads
Dennis Kempin wrote:
> Hi,
> 
> i just started to learn D (have been using c++ or java up to now) and am
> wondering how to implement some kind of timer, a thread that calls a
> delegate every n seconds.
> This was my first idea (without flags for stopping the timer etc):
> 
> class Timer: Thread
> {
>         int run()
>         {
>                 while(true)
>                 {
>                         this.wait(1000); // wait one second
>                         writefln("one second passed");
>                 }
>                 return 0;
>         }
> }
> 
> But writefln never gets executed, because this.wait is used to wait for
> other threads than the current one. Is there any other way to get let
> Thread sleep for some seconds (I know that there is a Sleep function for
> Win32, but a platform independend way would be very great).
> 
> regards
> Dennis

I'd try something with Thread.yield and a time check.

Example (insert your favorite time API)

class Timer : Thread
{
  run()
  {
    auto next = CurrentTime()+inc;
    while(running)
    {
      auto now = CurrentTime();
      if(now > next)
      {
        dg();
        next += inc;
      }
      else
        this.yield();
    }
  }
}
January 29, 2007
Re: Implementing a timer using threads
Dennis Kempin wrote:
> ...
> Maybe I just should use linux/windows c API methods and insert a platform
> fork. I will report here if i got a working solution.. Maybe I am not the
> only one who needs timing. 

No, I suspect you're probably not the only one.  Seems like most Thread 
apis I've seen have had some sort of Sleep() method.  Not sure why 
Phobos' doesn't.   Hopefully Tango will have a sleep().

--bb
January 30, 2007
Re: Implementing a timer using threads
On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS@pathlink.com> wrote:

>Dennis Kempin wrote:
>> Hi,
>> 
>> i just started to learn D (have been using c++ or java up to now) and am
>> wondering how to implement some kind of timer, a thread that calls a
>> delegate every n seconds.
>> This was my first idea (without flags for stopping the timer etc):
>> 
>> class Timer: Thread
>> {
>>         int run()
>>         {
>>                 while(true)
>>                 {
>>                         this.wait(1000); // wait one second
>>                         writefln("one second passed");
>>                 }
>>                 return 0;
>>         }
>> }
>> 
>> But writefln never gets executed, because this.wait is used to wait for
>> other threads than the current one. Is there any other way to get let
>> Thread sleep for some seconds (I know that there is a Sleep function for
>> Win32, but a platform independend way would be very great).
>> 
>> regards
>> Dennis
>
>I'd try something with Thread.yield and a time check.
>
>Example (insert your favorite time API)
>
>class Timer : Thread
>{
>   run()
>   {
>     auto next = CurrentTime()+inc;
>     while(running)
>     {
>       auto now = CurrentTime();
>       if(now > next)
>       {
>         dg();
>         next += inc;
>       }
>       else
>         this.yield();
>     }
>   }
>}

Be careful about Thread.yield under Windows. It calls Sleep(0) that
won't yield to a thread of a lower priority. In case of the proposed
timer this is not a problem except it will use 100% of CPU and won't
let any lower priority thread run but if you use something like a spin
lock waiting for a lower priority thread to release it, the lock will
never be released. You could use Sleep(1) or SwitchToThread() on
single processor systems. And you should use 'rep nop' for
hyperthreaded CPUs.

A platform independent way to put a thread to sleep using Phobos:
import std.c.time;

sleep(1);// secs
msleep(1000); millisecs
http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
January 30, 2007
Re: Implementing a timer using threads
Bill Baxter wrote:
> Dennis Kempin wrote:
>  > ...
>> Maybe I just should use linux/windows c API methods and insert a platform
>> fork. I will report here if i got a working solution.. Maybe I am not the
>> only one who needs timing. 
> 
> No, I suspect you're probably not the only one.  Seems like most Thread 
> apis I've seen have had some sort of Sleep() method.  Not sure why 
> Phobos' doesn't.   
> Hopefully Tango will have a sleep().

It does.


> 
> --bb
January 30, 2007
Re: Implementing a timer using threads
Max Samukha wrote:
> On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS@pathlink.com> wrote:
> 
> 
>>Dennis Kempin wrote:
>>
>>>Hi,
>>>
>>>i just started to learn D (have been using c++ or java up to now) and am
>>>wondering how to implement some kind of timer, a thread that calls a
>>>delegate every n seconds.
>>>This was my first idea (without flags for stopping the timer etc):
>>>
>>>class Timer: Thread
>>>{
>>>        int run()
>>>        {
>>>                while(true)
>>>                {
>>>                        this.wait(1000); // wait one second
>>>                        writefln("one second passed");
>>>                }
>>>                return 0;
>>>        }
>>>}
>>>
>>>But writefln never gets executed, because this.wait is used to wait for
>>>other threads than the current one. Is there any other way to get let
>>>Thread sleep for some seconds (I know that there is a Sleep function for
>>>Win32, but a platform independend way would be very great).
>>>
>>>regards
>>>Dennis
>>
>>I'd try something with Thread.yield and a time check.
>>
>>Example (insert your favorite time API)
>>
>>class Timer : Thread
>>{
>>  run()
>>  {
>>    auto next = CurrentTime()+inc;
>>    while(running)
>>    {
>>      auto now = CurrentTime();
>>      if(now > next)
>>      {
>>        dg();
>>        next += inc;
>>      }
>>      else
>>        this.yield();
>>    }
>>  }
>>}
> 
> 
> Be careful about Thread.yield under Windows. It calls Sleep(0) that
> won't yield to a thread of a lower priority. In case of the proposed
> timer this is not a problem except it will use 100% of CPU and won't
> let any lower priority thread run but if you use something like a spin
> lock waiting for a lower priority thread to release it, the lock will
> never be released. 

Ouch, I hadn't head of that.

> You could use Sleep(1) or SwitchToThread() on
> single processor systems. And you should use 'rep nop' for
> hyperthreaded CPUs.
> 
> A platform independent way to put a thread to sleep using Phobos:
> import std.c.time;
> 
> sleep(1);// secs
> msleep(1000); millisecs
> http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
> 
>  

However that gives the problem of not accounting for the run time of the 
threads "action". Not alwyas a problem, but...

What is  thread suposed to do to "kill time"? e.i. let other things run 
with out using up much CPU but keep poling the thread.

while(NothingToDo())
	thisThread.MarkTime();
January 30, 2007
Re: Implementing a timer using threads
BCS wrote:
> Max Samukha wrote:
>> A platform independent way to put a thread to sleep using Phobos:
>> import std.c.time;
>>
>> sleep(1);// secs
>> msleep(1000); millisecs
>> http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
>>
>>  
> 
> However that gives the problem of not accounting for the run time of the 
> threads "action". Not alwyas a problem, but...
> 
> What is  thread suposed to do to "kill time"? e.i. let other things run 
> with out using up much CPU but keep poling the thread.
> 
> while(NothingToDo())
>     thisThread.MarkTime();

Couldn't you just do something like:
-----
time_t nextEvent = currentTime() + interval;
time_t now;		
while (true) {
    while ((now = currentTime()) < nextEvent)
         sleep(nextEvent - now);        // or msleep, if you prefer
    nextEvent += interval;
    action();
}
-----
(where time_t is some type suitable for measuring time)

That should sleep until it's time, right?
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home