aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.lua')
-rw-r--r--src/lanes.lua79
1 files changed, 62 insertions, 17 deletions
diff --git a/src/lanes.lua b/src/lanes.lua
index 252d151..8837e4b 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -39,11 +39,19 @@ THE SOFTWARE.
39=============================================================================== 39===============================================================================
40]]-- 40]]--
41 41
42module( "lanes", package.seeall ) 42-- Lua 5.1: module() creates a global variable
43-- Lua 5.2: module() might go away
44-- almost everything module() does is done by require()
45-- -> simply create a table, populate it, return it, and be done
46local lanes = {}
47
48lanes.configure = function( _nb_keepers, _timers)
43 49
44local mm = require "lua51-lanes" 50local mm = require "lua51-lanes"
45assert( type(mm)=="table" ) 51assert( type(mm)=="table" )
46 52
53-- configure() is available only the first time lua51-lanes is required process-wide, and we *must* call it to have the other functions in the interface
54if mm.configure then mm.configure( _nb_keepers) end
47 55
48local thread_new = assert(mm.thread_new) 56local thread_new = assert(mm.thread_new)
49 57
@@ -140,6 +148,7 @@ end
140-- 148--
141-- .globals: table of globals to set for a new thread (passed by value) 149-- .globals: table of globals to set for a new thread (passed by value)
142-- 150--
151-- .required: table of packages to require
143-- ... (more options may be introduced later) ... 152-- ... (more options may be introduced later) ...
144-- 153--
145-- Calling with a function parameter ('lane_func') ends the string/table 154-- Calling with a function parameter ('lane_func') ends the string/table
@@ -161,7 +170,8 @@ local valid_libs= {
161 ["*"]= true 170 ["*"]= true
162} 171}
163 172
164function gen( ... ) 173-- PUBLIC LANES API
174local function gen( ... )
165 local opt= {} 175 local opt= {}
166 local libs= nil 176 local libs= nil
167 local lev= 2 -- level for errors 177 local lev= 2 -- level for errors
@@ -204,27 +214,34 @@ function gen( ... )
204 end 214 end
205 end 215 end
206 216
207 local prio, cs, g_tbl, packagepath, packagecpath 217 local prio, cs, g_tbl, packagepath, packagecpath, required
208 218
209 for k,v in pairs(opt) do 219 for k,v in pairs(opt) do
210 if k=="priority" then prio= v 220 if k=="priority" then prio= v
211 elseif k=="cancelstep" then cs= (v==true) and 100 or 221 elseif k=="cancelstep" then
212 (v==false) and 0 or 222 cs = (v==true) and 100 or
213 type(v)=="number" and v or 223 (v==false) and 0 or
214 error( "Bad cancelstep: "..tostring(v), lev ) 224 type(v)=="number" and v or
225 error( "Bad cancelstep: "..tostring(v), lev )
215 elseif k=="globals" then g_tbl= v 226 elseif k=="globals" then g_tbl= v
216 elseif k=="packagepath" then packagepath= v 227 elseif k=="packagepath" then
217 elseif k=="packagecpath" then packagecpath= v 228 packagepath = (type( v) == "string") and v or error( "Bad packagepath: " .. tostring( v), lev)
229 elseif k=="packagecpath" then
230 packagecpath = (type( v) == "string") and v or error( "Bad packagecpath: " .. tostring( v), lev)
231 elseif k=="required" then
232 required= (type( v) == "table") and v or error( "Bad required: " .. tostring( v), lev)
218 --.. 233 --..
219 elseif k==1 then error( "unkeyed option: ".. tostring(v), lev ) 234 elseif k==1 then error( "unkeyed option: ".. tostring(v), lev )
220 else error( "Bad option: ".. tostring(k), lev ) 235 else error( "Bad option: ".. tostring(k), lev )
221 end 236 end
222 end 237 end
223 238
239 if not packagepath then packagepath = package.path end
240 if not packagecpath then packagecpath = package.cpath end
224 -- Lane generator 241 -- Lane generator
225 -- 242 --
226 return function(...) 243 return function(...)
227 return thread_new( func, libs, cs, prio, g_tbl, packagepath, packagecpath, ...) -- args 244 return thread_new( func, libs, cs, prio, g_tbl, packagepath, packagecpath, required, ...) -- args
228 end 245 end
229end 246end
230 247
@@ -235,12 +252,16 @@ end
235----- 252-----
236-- lanes.linda() -> linda_ud 253-- lanes.linda() -> linda_ud
237-- 254--
238linda = mm.linda 255-- PUBLIC LANES API
256local linda = mm.linda
239 257
240 258
241---=== Timers ===--- 259---=== Timers ===---
242local want_timers = true 260
243if want_timers then 261-- PUBLIC LANES API
262local timer = function() error "timers are not active" end
263
264if _timers ~= "NO_TIMERS" then
244 265
245local timer_gateway= assert( mm.timer_gateway ) 266local timer_gateway= assert( mm.timer_gateway )
246-- 267--
@@ -424,6 +445,8 @@ if first_time then
424 assert( key and wakeup_at and period ) 445 assert( key and wakeup_at and period )
425 446
426 set_timer( linda, key, wakeup_at, period>0 and period or nil ) 447 set_timer( linda, key, wakeup_at, period>0 and period or nil )
448 elseif secs == 0 then -- got no value while block-waiting?
449 WR( "timer lane: no linda, aborted?")
427 end 450 end
428 end 451 end
429 end )() 452 end )()
@@ -432,7 +455,8 @@ end
432----- 455-----
433-- = timer( linda_h, key_val, date_tbl|first_secs [,period_secs] ) 456-- = timer( linda_h, key_val, date_tbl|first_secs [,period_secs] )
434-- 457--
435function timer( linda, key, a, period ) 458-- PUBLIC LANES API
459timer = function( linda, key, a, period )
436 460
437 if a==0.0 then 461 if a==0.0 then
438 -- Caller expects to get current time stamp in Linda, on return 462 -- Caller expects to get current time stamp in Linda, on return
@@ -456,7 +480,7 @@ function timer( linda, key, a, period )
456 timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period ) 480 timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period )
457end 481end
458 482
459end -- want_timers 483end -- _timers
460 484
461---=== Lock & atomic generators ===--- 485---=== Lock & atomic generators ===---
462 486
@@ -473,7 +497,8 @@ end -- want_timers
473-- Returns an access function that allows 'N' simultaneous entries between 497-- Returns an access function that allows 'N' simultaneous entries between
474-- acquire (+M) and release (-M). For binary locks, use M==1. 498-- acquire (+M) and release (-M). For binary locks, use M==1.
475-- 499--
476function genlock( linda, key, N ) 500-- PUBLIC LANES API
501local function genlock( linda, key, N )
477 linda:limit(key,N) 502 linda:limit(key,N)
478 linda:set(key,nil) -- clears existing data 503 linda:set(key,nil) -- clears existing data
479 504
@@ -506,7 +531,8 @@ end
506-- Returns an access function that allows atomic increment/decrement of the 531-- Returns an access function that allows atomic increment/decrement of the
507-- number in 'key'. 532-- number in 'key'.
508-- 533--
509function genatomic( linda, key, initial_val ) 534-- PUBLIC LANES API
535local function genatomic( linda, key, initial_val )
510 linda:limit(key,2) -- value [,true] 536 linda:limit(key,2) -- value [,true]
511 linda:set(key,initial_val or 0.0) -- clears existing data (also queue) 537 linda:set(key,initial_val or 0.0) -- clears existing data (also queue)
512 538
@@ -522,4 +548,23 @@ end
522 548
523-- newuserdata = mm.newuserdata 549-- newuserdata = mm.newuserdata
524 550
551 -- activate full interface
552 lanes.gen = gen
553 lanes.linda = mm.linda
554 lanes.timer = timer
555 lanes.genlock = genlock
556 lanes.genatomic = genatomic
557 -- from now on, calling configure does nothing but checking that we don't call it with parameters that changed compared to the first invocation
558 lanes.configure = function( _nk, _t)
559 if _nk ~= _nb_keepers then
560 error( "mismatched configuration: " .. tostring( _nk) .. " keepers instead of " .. tostring( _nb_keepers))
561 end
562 if _t ~= _timers then
563 error( "mismatched configuration: " .. tostring( _t) .. " timer activity instead of " .. tostring( _timers))
564 end
565 end
566end -- lanes.configure
567
525--the end 568--the end
569return lanes
570