aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.lua')
-rw-r--r--src/lanes.lua61
1 files changed, 45 insertions, 16 deletions
diff --git a/src/lanes.lua b/src/lanes.lua
index 98f8c20..c5b3315 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -96,6 +96,7 @@ local default_params =
96 -- it looks also like LuaJIT allocator may not appreciate direct use of its allocator for other purposes than the VM operation 96 -- it looks also like LuaJIT allocator may not appreciate direct use of its allocator for other purposes than the VM operation
97 internal_allocator = isLuaJIT and "libc" or "allocator", 97 internal_allocator = isLuaJIT and "libc" or "allocator",
98 keepers_gc_threshold = -1, 98 keepers_gc_threshold = -1,
99 linda_wake_period = 'never',
99 nb_user_keepers = 0, 100 nb_user_keepers = 0,
100 on_state_create = nil, 101 on_state_create = nil,
101 shutdown_timeout = 0.25, 102 shutdown_timeout = 0.25,
@@ -141,6 +142,19 @@ local param_checkers =
141 end 142 end
142 return true 143 return true
143 end, 144 end,
145 linda_wake_period = function(val_)
146 -- linda_wake_period should be a number > 0, or the string 'never'
147 if val_ == 'never' then
148 return true
149 end
150 if type(val_) ~= "number" then
151 return nil, "not a number"
152 end
153 if val_ <= 0 then
154 return nil, "value out of range"
155 end
156 return true
157 end,
144 nb_user_keepers = function(val_) 158 nb_user_keepers = function(val_)
145 -- nb_user_keepers should be a number in [0,100] (so that nobody tries to run OOM by specifying a huge amount) 159 -- nb_user_keepers should be a number in [0,100] (so that nobody tries to run OOM by specifying a huge amount)
146 if type(val_) ~= "number" then 160 if type(val_) ~= "number" then
@@ -266,6 +280,10 @@ local opt_validators =
266 local tv = type(v_) 280 local tv = type(v_)
267 return (tv == "string") and v_ or raise_option_error("name", tv, v_) 281 return (tv == "string") and v_ or raise_option_error("name", tv, v_)
268 end, 282 end,
283 native_priority = function(v_)
284 local tv = type(v_)
285 return (tv == "number") and v_ or raise_option_error("native_priority", tv, v_)
286 end,
269 package = function(v_) 287 package = function(v_)
270 local tv = type(v_) 288 local tv = type(v_)
271 return (tv == "table") and v_ or raise_option_error("package", tv, v_) 289 return (tv == "table") and v_ or raise_option_error("package", tv, v_)
@@ -281,7 +299,7 @@ local opt_validators =
281} 299}
282 300
283-- ############################################################################################# 301-- #############################################################################################
284-- ##################################### lanes.gen() ########################################### 302-- ################################### lanes.gen/coro() ########################################
285-- ############################################################################################# 303-- #############################################################################################
286 304
287local process_gen_opt = function(...) 305local process_gen_opt = function(...)
@@ -353,9 +371,16 @@ local process_gen_opt = function(...)
353 opt[k] = validator(v) 371 opt[k] = validator(v)
354 end 372 end
355 end 373 end
374
375 -- special case: can't have priority and native_priority at the same time
376 if opt.priority and opt.native_priority then
377 error "priority and native_priority cannot be specified together"
378 end
356 return func, libs, opt 379 return func, libs, opt
357end -- process_gen_opt 380end -- process_gen_opt
358 381
382-- #################################################################################################
383
359-- lane_h[1..n]: lane results, same as via 'lane_h:join()' 384-- lane_h[1..n]: lane results, same as via 'lane_h:join()'
360-- lane_h[0]: can be read to make sure a thread has finished (gives the number of available results) 385-- lane_h[0]: can be read to make sure a thread has finished (gives the number of available results)
361-- lane_h[negative]: error message, without propagating the error 386-- lane_h[negative]: error message, without propagating the error
@@ -394,25 +419,28 @@ end -- process_gen_opt
394-- Calling with a function argument ('lane_func') ends the string/table 419-- Calling with a function argument ('lane_func') ends the string/table
395-- modifiers, and prepares a lane generator. 420-- modifiers, and prepares a lane generator.
396 421
397-- receives a sequence of strings and tables, plus a function 422local make_generator = function(is_coro_, ...)
398local gen = function(...)
399 local func, libs, opt = process_gen_opt(...) 423 local func, libs, opt = process_gen_opt(...)
400 local core_lane_new = assert(core.lane_new) 424 local core_lane_new = assert(core.lane_new)
401 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level] 425 local prio_is_native = opt.native_priority and true or false
426 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority or opt.native_priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level]
402 return function(...) 427 return function(...)
403 -- must pass functions args last else they will be truncated to the first one 428 -- must pass functions args last else they will be truncated to the first one
404 return core_lane_new(func, libs, priority, globals, package, required, gc_cb, name, error_trace_level, false, ...) 429 return core_lane_new(func, libs, prio_is_native, priority, globals, package, required, gc_cb, name, error_trace_level, is_coro_, ...)
405 end 430 end
431end -- make_generator
432
433-- #################################################################################################
434
435-- receives a sequence of strings and tables, plus a function
436local gen = function(...)
437 return make_generator(false, ...)
406end -- gen() 438end -- gen()
407 439
440-- #################################################################################################
441
408local coro = function(...) 442local coro = function(...)
409 local func, libs, opt = process_gen_opt(...) 443 return make_generator(true, ...)
410 local core_lane_new = assert(core.lane_new)
411 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level]
412 return function(...)
413 -- must pass functions args last else they will be truncated to the first one
414 return core_lane_new(func, libs, priority, globals, package, required, gc_cb, name, error_trace_level, true, ...)
415 end
416end -- coro() 444end -- coro()
417 445
418-- ################################################################################################# 446-- #################################################################################################
@@ -603,7 +631,6 @@ local configure_timers = function()
603 return next_wakeup -- may be 'nil' 631 return next_wakeup -- may be 'nil'
604 end -- check_timers() 632 end -- check_timers()
605 633
606 local timer_gateway_batched = timerLinda.batched
607 set_finalizer(function(err, stk) 634 set_finalizer(function(err, stk)
608 if err and type(err) ~= "userdata" then 635 if err and type(err) ~= "userdata" then
609 error("LanesTimer error: "..tostring(err)) 636 error("LanesTimer error: "..tostring(err))
@@ -628,7 +655,7 @@ local configure_timers = function()
628 655
629 if _timerKey == TGW_KEY then 656 if _timerKey == TGW_KEY then
630 assert(getmetatable(_what) == "Linda") -- '_what' should be a linda on which the client sets a timer 657 assert(getmetatable(_what) == "Linda") -- '_what' should be a linda on which the client sets a timer
631 local _, key, wakeup_at, period = timerLinda:receive(0, timer_gateway_batched, TGW_KEY, 3) 658 local _, key, wakeup_at, period = timerLinda:receive_batched(0, TGW_KEY, 3)
632 assert(key) 659 assert(key)
633 set_timer(_what, key, wakeup_at, period and period > 0 and period or nil) 660 set_timer(_what, key, wakeup_at, period and period > 0 and period or nil)
634 elseif _timerKey == TGW_QUERY then 661 elseif _timerKey == TGW_QUERY then
@@ -643,7 +670,8 @@ local configure_timers = function()
643 end 670 end
644 end 671 end
645 end -- timer_body() 672 end -- timer_body()
646 timer_lane = gen("lanes_core,table", { name = "LanesTimer", package = {}, priority = core.max_prio }, timer_body)() 673 local min_prio, max_prio = core.thread_priority_range()
674 timer_lane = gen("lanes_core,table", { name = "LanesTimer", package = {}, priority = max_prio }, timer_body)()
647 end -- first_time 675 end -- first_time
648 676
649 ----- 677 -----
@@ -758,7 +786,7 @@ local genlock = function(linda_, key_, N)
758 -- 'nil' timeout allows 'key_' to be numeric 786 -- 'nil' timeout allows 'key_' to be numeric
759 return linda_:send(timeout, key_, trues(M_)) -- suspends until been able to push them 787 return linda_:send(timeout, key_, trues(M_)) -- suspends until been able to push them
760 else 788 else
761 local _k, _v = linda_:receive(nil, linda_.batched, key_, -M_) 789 local _k, _v = linda_:receive_batched(nil, key_, -M_)
762 -- propagate cancel_error if we got it, else return true or false 790 -- propagate cancel_error if we got it, else return true or false
763 return (_v == cancel_error and _v) or (_k and true or false) 791 return (_v == cancel_error and _v) or (_k and true or false)
764 end 792 end
@@ -863,6 +891,7 @@ local configure = function(settings_)
863 lanes.set_thread_affinity = core.set_thread_affinity 891 lanes.set_thread_affinity = core.set_thread_affinity
864 lanes.set_thread_priority = core.set_thread_priority 892 lanes.set_thread_priority = core.set_thread_priority
865 lanes.sleep = core.sleep 893 lanes.sleep = core.sleep
894 lanes.thread_priority_range = core.thread_priority_range
866 lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false 895 lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false
867 896
868 lanes.gen = gen 897 lanes.gen = gen