1. Req for task.e
- Posted by useless_ May 12, 2013
- 1487 views
Can we get a task_start()?
This would be like a task_schedule(), but not ever called again. With task_start(), the task begins, and runs until it yields or delays for a moment(s), and then resumes. This might save overhead?
procedure OnceEveryOtherSec() while 1 do task_delay(2) if equal(get_key(),'q') then abort(0) end if -- do this thing once every 2 seconds forever -- do this other thing once every 2 seconds forever too end while end procedure junk = task_create(routine_id("OnceEveryOtherSec"), {}) task_start(junk)
It's still a task, it's just not called again by the task scheduler. I am using task_schedule(junk,1) now, but it seems inappropriate, and wastefull.
useless
2. Re: Req for task.e
- Posted by Insolor May 13, 2013
- 1412 views
Have you tried something like task_schedule(id,{2.0,2.01})? Unless I missunderstood, this is exactly what you need. See task_schedule():
schedule is a sequence:
In this case, it must be a pair of positive atoms, the first one not being less than the second one. This defines task_id as a real time task. The pair states the minimum and maximum times, in seconds, to wait before running the task. The pair also sets the time interval for subsequent runs of the task, until the next call to task_schedule() or task_suspend().
[spoiler]Btw, there must be "the first one not being greater then the second one"[/spoiler]
3. Re: Req for task.e
- Posted by useless_ May 13, 2013
- 1350 views
Have you tried something like task_schedule(id,{2.0,2.01})? Unless I missunderstood, this is exactly what you need. See task_schedule():
schedule is a sequence:
In this case, it must be a pair of positive atoms, the first one not being less than the second one. This defines task_id as a real time task. The pair states the minimum and maximum times, in seconds, to wait before running the task. The pair also sets the time interval for subsequent runs of the task, until the next call to task_schedule() or task_suspend().
[spoiler]Btw, there must be "the first one not being greater then the second one"[/spoiler]
Except it must be a sure thing that the task not run twice in the allotted time frame, and it must run once, and it's ok to run a second or two early or late. There's notes sprinkled thru the task docs about "try to run" and how many times it's run per allocated time slot(s), and other indefinites and ambiguities (it's a task switcher layer over a multitasking OS, on multicore cpus, this is to be expected).
I'm not sure what words to use about this, but i know what i would like to have happen. Maybe it's just semantics, but surely the words mean something? I don't need the task to be "scheduled", simply having it start up and then task_sleep(x) (or task_delay(x)) within itself seems more appropriate and less code.
I know since the task still exists and need a slot to run in, it's still being minded by the task manager, and being called only to be told "go away, i'm still sleeping" is wasteful too, i don't see any other way in the task.e to ensure this task is run once until done, and only once.
useless
4. Re: Req for task.e
- Posted by mattlewis (admin) May 13, 2013
- 1326 views
Except it must be a sure thing that the task not run twice in the allotted time frame, and it must run once, and it's ok to run a second or two early or late. There's notes sprinkled thru the task docs about "try to run" and how many times it's run per allocated time slot(s), and other indefinites and ambiguities (it's a task switcher layer over a multitasking OS, on multicore cpus, this is to be expected).
I think a lot of the equivocation is because so much of the timing is dependent on what your program is doing. If you've scheduled something to start at a particular time, but some other task has run longer than you thought it would, euphoria won't be able to run that waiting task until you've given it a chance.
I'm not sure what words to use about this, but i know what i would like to have happen. Maybe it's just semantics, but surely the words mean something? I don't need the task to be "scheduled", simply having it start up and then task_sleep(x) (or task_delay(x)) within itself seems more appropriate and less code.
I think it's reasonable to run everything through task_schedule(), although the different ways of scheduling seem somewhat baffling. It might be better to have some helper routines with explicit parameters (task_schedule_realtime(), task_schedule_shared()) that can call task_schedule() for you.
I know since the task still exists and need a slot to run in, it's still being minded by the task manager, and being called only to be told "go away, i'm still sleeping" is wasteful too, i don't see any other way in the task.e to ensure this task is run once until done, and only once.
This sounds like premature optimization. I often find myself thinking this way. How wasteful is this? Have you quantified it at all? I could see this being a problem if you had a very large number of tasks and had a lot of switching going on. I don't know how many it would take before this would be a real problem, but I suspect the actual processing and I/O waits are going to dwarf the overhead of task switching.
Matt
5. Re: Req for task.e
- Posted by useless_ May 13, 2013
- 1336 views
<snips occured>
I think it's reasonable to run everything through task_schedule(), although the different ways of scheduling seem somewhat baffling. It might be better to have some helper routines with explicit parameters (task_schedule_realtime(), task_schedule_shared()) that can call task_schedule() for you.
Matt
Except this doesn't work, it fires once and never again:
atom selfpingtime = 20 -- seconds for keepalive, lag, and disconnect detection junk = task_create(routine_id("keepaliveping"), {}) -- ping to keep track of lag task_schedule(junk,selfpingtime) procedure keepaliveping() puts(1,"keepaliveping\n") if equal(got_motd,1) then send("PRIVMSG "&my_nick&" :PING "&sprintf("%d",time())&"") -- need a way to remember the ping was sent, in case it never returns, or is very late end if end procedure -- keepaliveping()
But putting keepaliveping's code in an endless while-loop which contains task_delay(selfpingtime) works fine:
procedure keepaliveping() -- this is an endless loop task while 1 do puts(1,"keepaliveping\n") if equal(got_motd,1) then send("PRIVMSG "&my_nick&" :PING "&sprintf("%d",time())&"") -- need a way to remember the ping was sent, in case it never returns, or is very late end if task_delay(selfpingtime) end while end procedure -- keepaliveping()
Why?
useless
6. Re: Req for task.e
- Posted by mattlewis (admin) May 14, 2013
- 1275 views
<snips occured>
I think it's reasonable to run everything through task_schedule(), although the different ways of scheduling seem somewhat baffling. It might be better to have some helper routines with explicit parameters (task_schedule_realtime(), task_schedule_shared()) that can call task_schedule() for you.
Matt
Except this doesn't work, it fires once and never again:
atom selfpingtime = 20 -- seconds for keepalive, lag, and disconnect detection junk = task_create(routine_id("keepaliveping"), {}) -- ping to keep track of lag task_schedule(junk,selfpingtime) procedure keepaliveping() puts(1,"keepaliveping\n") if equal(got_motd,1) then send("PRIVMSG "&my_nick&" :PING "&sprintf("%d",time())&"") -- need a way to remember the ping was sent, in case it never returns, or is very late end if end procedure -- keepaliveping()
Oh. I thought that's what you wanted. Sorry, by "fired again" I thought you meant started, not that it allowed other tasks to work for a while and then resume processing where it left off. When the routine returns, the task ends, as I understand it.
But putting keepaliveping's code in an endless while-loop which contains task_delay(selfpingtime) works fine:
procedure keepaliveping() -- this is an endless loop task while 1 do puts(1,"keepaliveping\n") if equal(got_motd,1) then send("PRIVMSG "&my_nick&" :PING "&sprintf("%d",time())&"") -- need a way to remember the ping was sent, in case it never returns, or is very late end if task_delay(selfpingtime) end while end procedure -- keepaliveping()
Why?
The task is still active here, so it's still a part of scheduling. Meanwhile, every 0.01 seconds, we allow other tasks to run.
Matt
7. Re: Req for task.e
- Posted by useless_ May 14, 2013
- 1236 views
<snip>
The task is still active here, so it's still a part of scheduling. Meanwhile, every 0.01 seconds, we allow other tasks to run.
Matt
I think i see the problem. As usual, it's the english language.
If i create a task, and then schedule it to run every 2 seconds (in a couple other languages i won't name), then it doesn't matter if that first run has ended (crashed, completed, times out, returned, etc), in 2 seconds it will be run again, as scheduled. If the task ended (returned, crashed, completed, ended) in Euphoria, i expected the scheduler to start it again. After all, i scheduled cpu time for it, i want it to run. If i "schedule" a pulse in a 74LS123, i want Q to be logic high (it's function is active), whether the previous pulse ended or not.
Now it makes even more sense to have a task_start. A task can then be created (build the 74LS123 circuit), scheduled some cpu time slots (build the RC time constant), and then started (CLK triggered). If it ends, then it must be restarted (CLK triggered), but not rescheduled (new RC components soldered in). This way too, it can be scheduled, but the start delayed. And once started, the task can delay/sleep itself independantly of the schedule (if it can be unscheduled but retain time slots). Because basically, once started, it's a fast operation, let it complete and then put itself to sleep, instead rescheduling itself.
But that brings me back to the original optomisation request, the task sleeping itself, vs rescheduling itself, because the scheduler will re-run it again immeadiately with no delayed start, so i haveto sleep the task anyhow, but it's an endless loop AND it's still being scheduled.
Or everyone who needs this function can write a new procedure and name it task_start. This explains why i have been chasing my tail trying to create and schedule some available time, but cannot delay the start of the task. Unless i code a task_delay, which i must anyhow, which defeats the point of scheduling? ARG!
useless