digitalmars.D - Can D throw a hanging exception if a function takes too long?
- ajvincent juno.com (13/13) Sep 26 2004 Earlier today, while working on a BigDecimal library for D (my first pro...
- Burton Radons (45/55) Sep 26 2004 Kids, don't call this at home. I have no idea if it's actually doing it...
-
Regan Heath
(7/8)
Sep 27 2004
On Sun, 26 Sep 2004 23:50:15 -0700, Burton Radons
- Arcane Jill (14/23) Sep 26 2004 Actualy, I think the code would look like this:
- teqDruid (12/36) Sep 27 2004 That's on the right track, but I'd prefer (and I think I'd be easier to
- Benjamin Herr (4/6) Sep 27 2004 Could you not just use pthread_kill instead of resorting to signals? I
- teqDruid (7/13) Sep 27 2004 pthread_kill sends a signal. Signals are the most basic form of IPC in ...
- Chr. Grade (13/19) Sep 27 2004 How about this:
- Sjoerd van Leent (9/27) Sep 27 2004 Don't quite see it:
- Sean Kelly (3/28) Sep 27 2004 But won't ubyte always be <= 0xFF?
- Russ Lewis (14/15) Sep 27 2004 Yeah. Let's correct the idea. It would be very cool if we could have
- Sjoerd van Leent (7/45) Sep 27 2004 I see, my fault.
- Chr. Grade (7/45) Sep 28 2004 while( nFoo )
- M (4/17) Sep 27 2004 It is a very good idea, I need them SO MUCH in my programs. And the synt...
-
Stewart Gordon
(7/15)
Sep 27 2004
- ajvincent juno.com (7/11) Sep 27 2004 Wow, that got a lot of replies in a hurry!
- Regan Heath (13/29) Sep 27 2004 Given the number of ideas so far I think it will be possible to do it wi...
- Burton Radons (71/82) Sep 27 2004 It doesn't specifically require compiler support, but it does require
- ajvincent juno.com (10/20) Sep 27 2004 Sweet. How nice a feeling it is to encounter a product like D, come up ...
- Burton Radons (20/34) Sep 27 2004 I'm not sure what you're talking about; how would this impact the API I
- ajvincent juno.com (2/4) Sep 27 2004 Forget it. It was just a minor nit anyway. 8-)
- Burton Radons (32/41) Sep 27 2004 It sounds like you meant a return value from the thread, right? You can...
- ajvincent juno.com (9/24) Sep 27 2004 That sounds about right. The only difference I see is that foo() I woul...
- Mike Swieton (10/26) Sep 27 2004 I suspect this would be difficult to do at the language level. However, ...
- Burton Radons (7/7) Sep 27 2004 The main problem I'm finding with writing a robust implementation is
Earlier today, while working on a BigDecimal library for D (my first project in D, porting a JavaScript-based BigDecimal library I wrote a few years ago), I accidentally caused a hang in my code. 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. If the elapsed amount of time passes, throw an exception and bail out. I don't know anything worth talking about when it comes to compilers, so if this is a "mission: impossible" task, I'd like to know.
Sep 26 2004
ajvincent juno.com wrote:Earlier today, while working on a BigDecimal library for D (my first project in D, porting a JavaScript-based BigDecimal library I wrote a few years ago), I accidentally caused a hang in my code. I'm thinking it would be really nice to specify a code block like this: unittest { timelimit(n) { // code to run goes here } }Kids, don't call this at home. I have no idea if it's actually doing it properly. All I know is that it worked the one time I tried it. private import std.thread; private import std.c.windows.windows; extern (Windows) BOOL TerminateThread (HANDLE handle, DWORD exitCode); class TimeLimitError : Error { this () { super ("TimeLimitError: Time limit has run out."); } } void timelimit (ulong milliseconds, void delegate () call) { int call_wrap () { call (); return 0; } Thread thread = new Thread (&call_wrap); thread.start (); try thread.wait (milliseconds); catch (ThreadError error) { } if (thread.getState == Thread.TS.RUNNING) { TerminateThread (thread.hdl, 0); foreach (inout Thread compare; Thread.getAll ()) if (compare === thread) { compare = null; break; } Thread.nthreads --; CloseHandle (thread.hdl); throw new TimeLimitError (); } } Usage example: timelimit (100, delegate void () { while (1) printf (""); }); Does anyone know if there's a way to terminate threads in Linux?
Sep 26 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/
Sep 27 2004
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: 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
Sep 26 2004
In article <cj8dj5$1bg2$1 digitaldaemon.com>, Arcane Jill says...In article <cj8bge$17ni$1 digitaldaemon.com>, ajvincent juno.com says...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. JohnI'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: 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
Sep 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
Sep 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
Sep 27 2004
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 Chr. Grade ajvincent juno.com wrote: > 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. If the elapsed amount of time passes, throw an exception and bail out.
Sep 27 2004
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 testingDon't quite see it: invariant { assert(nFoo <= 0xFF); } it's valid. Wrap a class that uses this for no_overflow... Regards, Sjoerd
Sep 27 2004
In article <cj9bcm$109b$1 digitaldaemon.com>, Sjoerd van Leent says...Chr. Grade wrote:But won't ubyte always be <= 0xFF? SeanHow 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 testingDon't quite see it: invariant { assert(nFoo <= 0xFF); } it's valid. Wrap a class that uses this for no_overflow...
Sep 27 2004
Sean Kelly wrote:But won't ubyte always be <= 0xFF?Yeah. Let's correct the idea. It would be very cool if we could have the compiler add automatic assertions which protect (in debug mode) against overflow. My thought is that, in debug mode, overflow should always be an error unless you mark a statement as expecting it. Something like this: int i = <whatever>; /* added automatically by compiler */ assert(i < INT_MAX); i++; /* no assert, since the statement expects overflow * MIGHT happen */ overflow i++; I haven't worked out all of the issues here, but this is my rough idea.
Sep 27 2004
Sean Kelly wrote:In article <cj9bcm$109b$1 digitaldaemon.com>, Sjoerd van Leent says...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, SjoerdChr. Grade wrote:But won't ubyte always be <= 0xFF? SeanHow 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 testingDon't quite see it: invariant { assert(nFoo <= 0xFF); } it's valid. Wrap a class that uses this for no_overflow...
Sep 27 2004
Sean Kelly wrote:In article <cj9bcm$109b$1 digitaldaemon.com>, Sjoerd van Leent says...while( nFoo ) { if( isCarryFlag( nFoo ) ) fnWheep( ... ); nFoo++; }Chr. Grade wrote:But won't ubyte always be <= 0xFF? SeanHow 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 testingDon't quite see it: invariant { assert(nFoo <= 0xFF); } it's valid. Wrap a class that uses this for no_overflow...
Sep 28 2004
It is a very good idea, I need them SO MUCH in my programs. And the syntax should be the same in WINDOWS and LINUX. So Walter, PLEASE PLEASE PLEASE make it! In article <cj8bge$17ni$1 digitaldaemon.com>, ajvincent juno.com says...Earlier today, while working on a BigDecimal library for D (my first project in D, porting a JavaScript-based BigDecimal library I wrote a few years ago), I accidentally caused a hang in my code. 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. If the elapsed amount of time passes, throw an exception and bail out. I don't know anything worth talking about when it comes to compilers, so if this is a "mission: impossible" task, I'd like to know.
Sep 27 2004
In article <cj8bge$17ni$1 digitaldaemon.com>, ajvincent juno.com says... <snip>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. If the elapsed amount of time passes, throw an exception and bail out.<snip> 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.
Sep 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?
Sep 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...Can you use the clock(); function?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?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/
Sep 27 2004
Regan Heath wrote: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.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.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.
Sep 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.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.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:
Sep 27 2004
ajvincent juno.com wrote:In article <cja27m$1d6u$1 digitaldaemon.com>, Burton Radons says...I'm not sure what you're talking about; how would this impact the API I presented, exactly? /** 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 Thread.monitored_run (bit delegate () monitor); /** 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); /** Execute call, throwing TimeLimitError if it takes longer than the * specified number of milliseconds. */ void timelimit (uint milliseconds, void delegate () call);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.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:
Sep 27 2004
In article <cja55p$1f2a$1 digitaldaemon.com>, Burton Radons says...I'm not sure what you're talking about; how would this impact the API I presented, exactly?Forget it. It was just a minor nit anyway. 8-)
Sep 27 2004
ajvincent juno.com wrote:In article <cja55p$1f2a$1 digitaldaemon.com>, Burton Radons says...It sounds like you meant a return value from the thread, right? You can have those with this: /** 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, put the result of * run in result and return true. */ template monitored_run_return (ReturnType) { bit monitored_run_return ( ReturnType delegate () run, bit delegate (Thread thread) monitor, out ReturnType result) { return !monitored_run (delegate void () { result = run (); }, &monitor); } } /* Example usage. */ void foo () { int return_value; if (monitored_run_return! (int) ( delegate int () { return xyz; }, bit delegate () { return wst; }, return_value)) { printf ("Got back %d!\n", return_value); } }I'm not sure what you're talking about; how would this impact the API I presented, exactly?Forget it. It was just a minor nit anyway. 8-)
Sep 27 2004
In article <cja6j1$1fv5$1 digitaldaemon.com>, Burton Radons says...It sounds like you meant a return value from the thread, right? You can have those with this: ... /* Example usage. */ void foo () { int return_value; if (monitored_run_return! (int) ( delegate int () { return xyz; }, bit delegate () { return wst; }, return_value)) { printf ("Got back %d!\n", return_value); } }That sounds about right. The only difference I see is that foo() I would think would be "int foo()", and as a function return 0 for a successful operation. In other words, just as int main() returns 0 for an error-free operation, I would think this sort of thing could (not "must"!) do the same. All I'm saying is that if foo() returns a value, then the encapsulating code should probably return the same value. Propagate whatever returns (whether they be arguments or actual return statements) out from foo() to the main application.
Sep 27 2004
On Mon, 27 Sep 2004 06:21:02 +0000, ajvincent wrote:Earlier today, while working on a BigDecimal library for D (my first project in D, porting a JavaScript-based BigDecimal library I wrote a few years ago), I accidentally caused a hang in my code. 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. If the elapsed amount of time passes, throw an exception and bail out. I don't know anything worth talking about when it comes to compilers, so if this is a "mission: impossible" task, I'd like to know.I suspect this would be difficult to do at the language level. However, a threading library could have such functionality, but I think a program would need to be designed for it (i.e. set up it's own watchdog thread). What may be more immediately useful to some people, under Unix at least, is the alarm() system call. Mike Swieton __ The difference between losers and winners is that losers don't fail enough. - Ross Jeffries
Sep 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.
Sep 27 2004