September 27, 2004
In article <cj8dj5$1bg2$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <cj8bge$17ni$1@digitaldaemon.com>, ajvincent@juno.com says...
>
>>I'm thinking it would be really nice to specify a code block like this:
>>unittest {
>>timelimit(n) {
>>// code to run goes here
>>}
>>}
>>
>>where n is a number of milliseconds that the code within must finish running by.
>
>Actualy, I think the code would look like this:
>
>#    unittest
>#    {
>#        auto TimeLimit timeLimit = new TimeLimit(n);
>#        // code to run goes here
>#    }
>
>where TimeLimit is an auto class. Its job would be simply to sleep for the given timeout and then throw - unless it gets destructed first.
>
>>if this
>>is a "mission: impossible" task, I'd like to know.
>
>I can imagine some difficulties ... throwing exceptions in constructors/destructors; throwing exceptions from another thread, and so on. It may be that the exception handling mechanism is not the ideal tool for this, but that's the best idea I have so far.
>
>Jill
>
>

That's on the right track, but I'd prefer (and I think I'd be easier to
implement) this:

void myTask()
{
//Do something
}
TimedTask t = new TimedTask(&myTask, 1500 /*Time limit*/);
t.run();

This wouldn't be too hard to implement in Linux using a threading and some signals... in fact, I think I'll write a quick implementation later today.

John


September 27, 2004
teqDruid wrote:
> This wouldn't be too hard to implement in Linux using a threading and some
> signals... in fact, I think I'll write a quick implementation later today.
Could you not just use pthread_kill instead of resorting to signals? I thought they were meant to be reserved for the user of one's library.

-ben
September 27, 2004
In article <cj92l1$fh7$1@digitaldaemon.com>, Stewart Gordon says...
>The time it takes will depend on the speed of the CPU.  So wouldn't it make more
>sense
>to specify a timelimit in CPU cycles?
>
>Stewart.

Wow, that got a lot of replies in a hurry!

I was strongly considering asking for it to be based on CPU cycles instead of time, for that very reason.  For debugging purposes, it does make more sense to base it on how many cycles pass by, if at all possible.

Mr. Bright, do you care to chime in? Is this something we can build into the language, or perhaps make as a std library?


September 27, 2004
pthread_kill sends a signal.  Signals are the most basic form of IPC in Linux. Basically all they can do is interrupt a thread, but one can obviously build off of that.  There is a class of signals that are meant to be delivered to a program from the "outside," but nothing in the pthread standard stops someone from using them inside a program.

John

In article <cj9dsh$120u$1@digitaldaemon.com>, Benjamin Herr says...
>
>teqDruid wrote:
>> This wouldn't be too hard to implement in Linux using a threading and some signals... in fact, I think I'll write a quick implementation later today.
>Could you not just use pthread_kill instead of resorting to signals? I thought they were meant to be reserved for the user of one's library.
>
>-ben


September 27, 2004
Sean Kelly wrote:
> In article <cj9bcm$109b$1@digitaldaemon.com>, Sjoerd van Leent says...
> 
>>Chr. Grade wrote:
>>
>>>How about this:
>>>
>>>[1] new loop construct
>>>
>>>whilst
>>>{
>>>  // never loops more times than u32_max or u64_max
>>>  // compiler issues error if looped more times during unit testing
>>>}
>>>
>>>
>>>[2] new prefix for keywords
>>>
>>>no_overflow ubyte nFoo = 0xFF;
>>>
>>>while( nFoo++ ) {};   // error during unit testing
>>>
>>
>>Don't quite see it:
>>
>>invariant {
>>	assert(nFoo <= 0xFF);
>>}
>>
>>it's valid.
>>
>>Wrap a class that uses this for no_overflow...
> 
> 
> But won't ubyte always be <= 0xFF?
> 
> Sean
> 
> 

I see, my fault.

assert (T < T.type.max)

or something in that manner would be sufficient. Also the reverse (underflow) could be guarded that way.

regards,
Sjoerd
September 27, 2004
The main problem I'm finding with writing a robust implementation is that we don't want to dump the thread, we want to cause it to unwrap its finally stack and then have the manager terminate it.  Just dropping the thread might leave important state out of array.

I'll look into the problem more later; there's a solution, I just don't have the time and stamina (cold) right now to try to pick apart (/dmd/src/phobos/internal/deh.c).  Blech, C.
September 27, 2004
On Sun, 26 Sep 2004 23:50:15 -0700, Burton Radons <burton-radons@shaw.ca> wrote:

<snip>

> Does anyone know if there's a way to terminate threads in Linux?

pthread_kill();

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
September 27, 2004
On Mon, 27 Sep 2004 16:26:22 +0000 (UTC), <ajvincent@juno.com> wrote:
> In article <cj92l1$fh7$1@digitaldaemon.com>, Stewart Gordon says...
>> The time it takes will depend on the speed of the CPU.  So wouldn't it make more
>> sense
>> to specify a timelimit in CPU cycles?
>>
>> Stewart.
>
> Wow, that got a lot of replies in a hurry!
>
> I was strongly considering asking for it to be based on CPU cycles instead of
> time, for that very reason.  For debugging purposes, it does make more sense to
> base it on how many cycles pass by, if at all possible.

Can you use the clock(); function?

> Mr. Bright, do you care to chime in? Is this something we can build into the
> language, or perhaps make as a std library?

Given the number of ideas so far I think it will be possible to do it with a std library.

If it were a language construct would it limit your choices? Basically I'm wondering if everyone might want to do something slightly different and if we had a language construct it would do one thing, and might not be able to do the other things.

That said, this sort of thing would be a really nice addition to the support D already has for threads.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
September 27, 2004
Regan Heath wrote:

>> Mr. Bright, do you care to chime in? Is this something we can build into the
>> language, or perhaps make as a std library?
> 
> 
> Given the number of ideas so far I think it will be possible to do it with a std library.

It doesn't specifically require compiler support, but it does require compiler-specific code.  If/when I return to this I'll write code for terminating threads correctly and send it to Walter.

> If it were a language construct would it limit your choices? Basically I'm wondering if everyone might want to do something slightly different and if we had a language construct it would do one thing, and might not be able to do the other things.

I think it works nicely as a library function.  What it all comes down to is monitored execution of a bunch of code.  So the core method of Thread would be:

   /** Run the thread, calling monitor during execution in the current
     * thread.  If monitor ever returns false, terminate execution of
     * the thread and return false.  If the thread terminates on its
     * own, return true.
     */

   bit monitored_run (bit delegate () monitor)
   {
       /* Start running the thread. */
       start ();

       /* Loop until the thread dies or until monitor returns false. */
       while (getState != TS.TERMINATED)
       {
           /* Ask the monitor whether to continue. */
           if (!monitor ())
           {
               /* Stop execution of the thread. */
               terminate ();

               /* Monitor returned false, return false. */
               return false;
           }

           /* Yield the current timeslice. */
           yield ();
       }

       /* Thread terminated on its own, return true. */
       return true;
   }

While timelimit would be the function:

   /** Execute run in a second thread, calling monitor during execution
     * in the current thread (passing the thread object).  If monitor
     * ever returns false, terminate execution of the thread and return
     * false.  If the thread terminates on its own, return true.
     */

   bit monitored_run (void delegate () run, bit delegate (Thread thread) monitor)
   {
       /* Create the thread object. */
       Thread thread = new Thread (call);

       /* Execute a monitored run. */
       return thread.monitored_run (delegate bit ()
       {
           /* Pass the delegate on with the addition of a parameter. */
           return monitor (thread);
       });
   }

   /** Execute call, throwing TimeLimitError if it takes longer than the
     * specified number of milliseconds.
     */

   void timelimit (uint milliseconds, void delegate () call)
   {
       /* Execute a monitored run. */
       if (!monitored_run (delegate bit (Thread thread)
       {
           /* Wait until the thread dies or until we run out of time. */
           thread.wait (milliseconds);

           /* Return whether the thread died. */
           return thread.getState == Thread.TS.TERMINATED;
       }))
       {
           /* Thread took too long; throw up. */
           throw new TimeLimitError ();
       }
   }

You could also monitor changing global state or do any other babysitting you want.
September 27, 2004
In article <cja27m$1d6u$1@digitaldaemon.com>, Burton Radons says...
>It doesn't specifically require compiler support, but it does require compiler-specific code.  If/when I return to this I'll write code for terminating threads correctly and send it to Walter.

Sweet.  How nice a feeling it is to encounter a product like D, come up with an idea no one else has really thought of yet, and see people just leap on it with a ton of suggested fixes.

It's kind of how I felt here: https://bugzilla.mozilla.org/show_bug.cgi?id=123177

Very invigorating for a newbie to the language.

>> If it were a language construct would it limit your choices? Basically I'm wondering if everyone might want to do something slightly different and if we had a language construct it would do one thing, and might not be able to do the other things.
>
>I think it works nicely as a library function.  What it all comes down to is monitored execution of a bunch of code.  So the core method of Thread would be:
>

Hmm.  If I could ask one minor change, it'd be to see that we save the return value for errors (or 0 for a clean operation) and use an out parameter for the intended return value(s).  This is how Mozilla's XPCOM code works.