diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2022-03-16 21:35:55 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2022-03-16 21:38:34 -0700 |
commit | fffcc8b9abf43a69d71c37c92fc149f661dd6da1 (patch) | |
tree | c5a796db79955008c46a61bda54da7e41a47ffb7 | |
parent | d6554919b1e2e5f598e7997297a358905ee54913 (diff) | |
download | teliva-fffcc8b9abf43a69d71c37c92fc149f661dd6da1.tar.gz |
stop running task.scheduler by default
sieve.tlv is 50% slower (18s vs 12s) with the new function call instrumentation.
-rw-r--r-- | doc/manual.html | 26 | ||||
-rw-r--r-- | sieve.tlv | 28 | ||||
-rw-r--r-- | src/lua.c | 3 | ||||
-rw-r--r-- | src/task.lua | 19 | ||||
-rw-r--r-- | src/teliva.c | 2 |
5 files changed, 36 insertions, 42 deletions
diff --git a/doc/manual.html b/doc/manual.html index f5520ce..4bdc72d 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -2123,7 +2123,16 @@ When you run it, it produces the following output: main false cannot resume dead coroutine </pre> - +<div class='teliva'> +Coroutines are powerful, but require some experience to use tastefully. Try to +use them judiciously. If you find yourself juggling lots of coroutines and +trying to decide which one to try to resume, you should probably be using +<a href='#5.13'>tasks and channels</a> instead. On the other hand, tasks have +some cognitive overheads. You have to explicitly manage them with +<a href='#pdf-task.scheduler'><code>task.scheduler</code></a>, and errors can +sometimes be hard to track down. For simple generators that emit elements +on demand, a coroutine is likely the best solution. +</div> <h1>3 - <a name="3">C API</a></h1> @@ -4423,17 +4432,17 @@ For example, suppose file <code>foo</code> contains '[1,2,3,{"x":10}]'. Then: Teliva includes the well-known <a href='https://github.com/majek/lua-channels#readme'>lua-channels</a> -library in module <code>task</code>. It also transparently starts up -<a href='#pdf-task.scheduler'><code>task.scheduler</code></a> for all apps. -See sieve.tlv for a basic example. +library in module <code>task</code>. See sieve.tlv for a basic example. <p> <hr><h3><a name="pdf-task.spawn"><code>task.spawn (fun, [...])</code></a></h3> <p> -Run <code>fun</code> as a coroutine with given parameters. You should use this -instead of <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. +Run <code>fun</code> as a coroutine with given parameters. Spawn tasks instead of +just calling <a href="#pdf-coroutine.create"><code>coroutine.create</code></a> +when you can't statically predict how your coroutines will transfer control to +each other. <p> @@ -4441,8 +4450,9 @@ instead of <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. <p> -Starts running any spawned tasks. You shouldn't need to ever call this from -Teliva. The scheduler is always started for you. +Starts running any spawned tasks. Execution transfers to spawned tasks; +this function only returns when there are no tasks left to run or when all +tasks are blocked (deadlock). <p> diff --git a/sieve.tlv b/sieve.tlv index 9677af4..e5852e5 100644 --- a/sieve.tlv +++ b/sieve.tlv @@ -25,14 +25,17 @@ Window: >Window = curses.stdscr() - __teliva_timestamp: original - doc:blurb: - >To show a brief description of the app on the 'big picture' screen, put the text in a special buffer called 'doc:blurb'. - > - >You can also override the default big picture screen entirely by creating a buffer called 'doc:main'. -- __teliva_timestamp: - >Sat Feb 26 21:50:11 2022 main: >function main() + > task.spawn(main_task) + > task.scheduler() + > Window:refresh() + > Window:getch() + >end +- __teliva_timestamp: original + main_task: + >function main_task() + > Window:clear() > local c = task.Channel:new() > task.spawn(counter, c) > for i=1,10 do @@ -64,8 +67,8 @@ >end - __teliva_timestamp: >Sat Feb 26 21:55:46 2022 - main: - >function main() + main_task: + >function main_task() > local primes = task.Channel:new() > task.spawn(sieve, primes) > for i=1,10 do @@ -104,8 +107,8 @@ >Sat Feb 26 22:09:47 2022 __teliva_note: >infinite primes - main: - >function main() + main_task: + >function main_task() > local primes = task.Channel:new() > task.spawn(sieve, primes) > while true do @@ -120,8 +123,8 @@ >clear screen when it fills up; pause on keypress > >In Teliva getch() implicitly refreshes the screen. - main: - >function main() + main_task: + >function main_task() > Window:nodelay(true) > Window:clear() > local primes = task.Channel:new() @@ -139,7 +142,6 @@ > end > print('key pressed; done') > Window:nodelay(false) - > Window:getch() >end - __teliva_timestamp: >Sat Feb 26 22:27:25 2022 diff --git a/src/lua.c b/src/lua.c index 2c5e696..5445e86 100644 --- a/src/lua.c +++ b/src/lua.c @@ -249,7 +249,8 @@ static int pmain (lua_State *L) { if (s->status != 0) return 0; /* call main() */ - lua_getglobal(L, "spawn_main"); + assign_call_graph_depth_to_name(L, /*depth*/2, "main"); /* manually seed debug info */ + lua_getglobal(L, "main"); s->status = docall(L, 0, 1); if (s->status != 0) return report_in_developer_mode(L, s->status); diff --git a/src/task.lua b/src/task.lua index 9546069..e8bf842 100644 --- a/src/task.lua +++ b/src/task.lua @@ -384,25 +384,6 @@ _M.RECV = RECV _M.SEND = SEND _M.NOP = NOP --- Specific to Teliva -function spawn_main() - task.spawn(call_main) - task.scheduler() - assert(false, "Teliva ran out of stuff to do. Possible causes:\n".. - "- main() returned. Apps shouldn't let this happen.\n".. - "- App is reading past the end of a file (after recv() returned nil)\n".. - "- Some channel is blocked forever.\n") - curses.nodelay(true) - curses.getch() -end - --- This function exists only to make the call to 'main' visible to Teliva. --- Teliva can't yet recognize the caller of indirect calls, as happens with --- task.spawn. -function call_main() - main() -end - ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -- Tests diff --git a/src/teliva.c b/src/teliva.c index dbd0677..1e2eb34 100644 --- a/src/teliva.c +++ b/src/teliva.c @@ -484,7 +484,7 @@ restart: y += 2; mvprintw(y, 0, "functions: "); y++; - for (int depth = /*ignore callers of main*/3; ; ++depth) { + for (int depth = /*main*/2; ; ++depth) { mvaddstr(y, 0, " "); bool drew_anything = false; index_within_level = 0; |