PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2024 → [WD20] Recursion
[WD20] Recursion
Iniciado por guest, 18,ene. 2016 07:40 - 11 respuestas
Publicado el 18,enero 2016 - 07:40
What is the current status of rercusive calls in Windev (ie: a procedure calling itself). I found that in the past it was not officially supported. However in the product brochure for WD19 it states that procedures are recursive. Is this actually true now? Are there any limits or problems.

Kind of related: what if you have 30 threads running that all call another procedure (say to write a comment to a log file). I assume each call to the procedure would get its own variable space for local variables and that simultaneous use of global variables would need to use semaphores or some other way of dealing with conflicts - does this also fail at some point?

Also related: you have 30 threads running and the threadexecute command calls the same procedure:

ThreadExecute("Thread1", threadNormal, SensorMonitorThreadProc,"Sensor1")
ThreadExecute("Thread2", threadNormal, SensorMonitorThreadProc,"Sensor2")
...

Each thread is monitoring a separate external sensor.

Is it better in any way to have a separate procedure for each monitoring thread?

ThreadExecute("Thread1", threadNormal, SensorMonitorThreadProc1)
ThreadExecute("Thread2", threadNormal, SensorMonitorThreadProc2)
...

or does it make any difference?
Publicado el 18,enero 2016 - 12:17
Hi Donald,

AFAIK, recursion is still NOT supported, and the number of levels supported in the stack went down between versions.

It's very easy to test:
iGlobal is int //global var

Procedure TestRecursion()
iGLobal++
trace(iGLobal)
multitaskredraw()
TestRecursion()

Then call testrecursion() anywehre and see the number of levels supported in your version. I haven't tested for some time, so I may be wrong, after all :-)

Best regards
Publicado el 18,enero 2016 - 14:46
Hi Donald,

For recursive calls, try to avoid. Usually one can do otherwise.

30 threads calling a log procedure: no problems, in the log procedure you want to use a critical section to make sure only one thread writes in the file at any given time.

30 threads using the same procedure: no problems, use critical sections when playing with common variable. You will have to desable the automatic thread management to tell WinDev you handle that yourself with critical sections, etc. Otherwise only one thread will run at once in the same procedure. This is not what you want.

Unsing 30 procedure for 30 threads is useless the moment you pass in parameter your sensor variable (or name) to be monitored. When you have to interract with a global variable you sue critical sections. You can also call MainThreadExecute() (something like that) for the log file. Etc.

In WD 21 there will be a new feature to make a common variable automatically managed as in a critical section. There will be no need, for these, to be in critical sections in a thread. This is not there yet.

Best regards,
Alexandre Leclerc
Publicado el 18,enero 2016 - 17:35
Fabrice

In WD20 - 245 depth before failing. Seems reasonable to me.
Publicado el 18,enero 2016 - 22:46
it was at more than 600 at some point...

And it means recursion is still not supported, as a recursive procedure can be called thousands of times very easily.

Add to that that all the previous calls (open window, procedure call, etc) counts in the total, and you never know when it's going to break

Best regards
Publicado el 19,enero 2016 - 10:37
Would you think that the point of failure; be it 245 or 600 depends on available system resources? i.e. more parameters and the faster the resources are used up?
Publicado el 19,enero 2016 - 11:22
Hi Donald,

Recursion levels are by definition highly determined by system (memory) resources and software and machine architecture (32 vs 64 bit) which have different addressing capabilities and thus stack build-up capabilities...

I wouldn't expect any real limitations aside from that within the WX runtime (apart from 32 vs 64 bit runtime)...

I don't know what you are trying to do within each recursion, but if it each iteration contains a copy of a large memory space (e.g. an array of 10.000 objects) it is clear that system resources will be eaten up at light speed...

Just my 2 cents,

Peter Holemans
Publicado el 19,enero 2016 - 13:53
Hi again

my advice is to NOT use recursion at all...
If your process goes deeper than the limit/you think, you crash
In the next version of windev, the number of level working can be lower (as I said, it went from 600 to way less than that between version), and as it is OFFICIALLY not supported, you'll be dead in the water

A good loop will do the trick
Publicado el 19,enero 2016 - 16:16
Hi,

I did a quick test on my WD instance (WX20 32-bit / i7 / 8GB) with a factorial (recursive) algorithm and can consistently blow up the call stack at anything over 245 recursive calls (So an identical result to JP's tests)...

So it looks that the limit is hard coded at 245 (probably 256 (1 byte) or so when taking the WX WDTest runtime call stack underneath my execution also into account).

So yes, for WX20 is will be around that number somewhere. Take into account that in a real program this limit may vary depending on what is already in the threads WX call stack before launching the recursion...

FactorResult is numeric = Factor(245) //246 will blow up the call stack FUNCTION Factor(pNum is numeric) IF pNum <= 1 THEN RESULT 1 ELSE RESULT pNum * Factor(pNum-1) END
Hope this helps anybody from bumping into an issue!

Cheers,

Peter
Publicado el 19,enero 2016 - 19:20
Peter,

always interested in these kinds of tests

With your code
WD19 32bit runs up to 991
WD20 32bit runs hits 1001

:xcool:
Publicado el 20,enero 2016 - 11:25
Hi Arie,

Interesting...
This means it really is machine dependent then...
What's your configuration? And did you run it in test mode or in build mode?

Cheers,

Peter Holemans
Publicado el 20,enero 2016 - 11:35
Peter,

I'm using a i5 8Gb 64bit machine, but with 32bit WD versions.
Started the code from within the IDE with the F9 button, using a global test function which in turn runs Factor()

Just did a test (wd19) and build the executable and then it runs up to 248.
So there's a difference between test and build mode.

LOL