1. Req for task.e


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

new topic     » topic index » view message » categorize

2. Re: Req for task.e

Have you tried something like task_schedule(id,{2.0,2.01})? Unless I missunderstood, this is exactly what you need. See task_schedule():

said...

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]

new topic     » goto parent     » topic index » view message » categorize

3. Re: Req for task.e

Insolor said...

Have you tried something like task_schedule(id,{2.0,2.01})? Unless I missunderstood, this is exactly what you need. See task_schedule():

said...

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: Req for task.e

useless_ said...

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.

useless_ said...

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.

useless_ said...

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: Req for task.e

mattlewis said...


<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

new topic     » goto parent     » topic index » view message » categorize

6. Re: Req for task.e

useless_ said...
mattlewis said...


<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.

useless_ said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: Req for task.e

mattlewis said...

<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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu