diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-12-03 10:26:47 +0100 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-12-03 10:26:47 +0100 |
commit | 307fd830eb168005a3ba3d557343284814757eff (patch) | |
tree | eb14512492d58e33585bc5df3f3d9b23d7308934 /docs | |
parent | ca7657e24549acb8a2dd45fa81c309b5bf9f61ee (diff) | |
download | lanes-307fd830eb168005a3ba3d557343284814757eff.tar.gz lanes-307fd830eb168005a3ba3d557343284814757eff.tar.bz2 lanes-307fd830eb168005a3ba3d557343284814757eff.zip |
New method linda:restrict()
Diffstat (limited to 'docs')
-rw-r--r-- | docs/index.html | 132 |
1 files changed, 77 insertions, 55 deletions
diff --git a/docs/index.html b/docs/index.html index 7432c53..6757981 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -1218,7 +1218,7 @@ | |||
1218 | lane_h = lanes.gen("", loop)(10000) | 1218 | lane_h = lanes.gen("", loop)(10000) |
1219 | 1219 | ||
1220 | while true do | 1220 | while true do |
1221 | local key, val = linda:receive(3.0, "x") -- timeout in seconds | 1221 | local slot, val = linda:receive(3.0, "x") -- timeout in seconds |
1222 | if val == nil then | 1222 | if val == nil then |
1223 | print("timed out") | 1223 | print("timed out") |
1224 | break | 1224 | break |
@@ -1233,7 +1233,7 @@ | |||
1233 | Characteristics of the Lanes implementation of lindas are: | 1233 | Characteristics of the Lanes implementation of lindas are: |
1234 | 1234 | ||
1235 | <ul> | 1235 | <ul> |
1236 | <li>Keys can be of boolean, number, string, light userdata, and deep userdata type. Tables, functions and non-deep userdata can't be keys because their identity isn't preserved when transfered from one Lua state to another.</li> | 1236 | <li>Slots can be of boolean, number, string, light userdata, and deep userdata type. Tables, functions and non-deep userdata can't be slots because their identity isn't preserved when transfered from one Lua state to another.</li> |
1237 | <li>Values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> | 1237 | <li>Values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> |
1238 | <li> | 1238 | <li> |
1239 | Registered functions and userdata transiting into a Keeper state are converted to a special dummy closure that holds its actual identity. On transit out, the identity is used to find the real function or userdata in the destination. | 1239 | Registered functions and userdata transiting into a Keeper state are converted to a special dummy closure that holds its actual identity. On transit out, the identity is used to find the real function or userdata in the destination. |
@@ -1242,10 +1242,11 @@ | |||
1242 | <li>Consuming method is <tt>:receive</tt> (not in).</li> | 1242 | <li>Consuming method is <tt>:receive</tt> (not in).</li> |
1243 | <li>Non-consuming method is <tt>:get</tt> (not rd).</li> | 1243 | <li>Non-consuming method is <tt>:get</tt> (not rd).</li> |
1244 | <li>Two producer-side methods: <tt>:send</tt> and <tt>:set</tt> (not out).</li> | 1244 | <li>Two producer-side methods: <tt>:send</tt> and <tt>:set</tt> (not out).</li> |
1245 | <li><tt>send</tt> allows for sending multiple values -atomically- to a given key.</li> | 1245 | <li><tt>send</tt> allows for sending multiple values -atomically- to a given slot.</li> |
1246 | <li><tt>receive</tt> can wait for multiple keys at once.</li> | 1246 | <li><tt>receive</tt> can wait for multiple slots at once.</li> |
1247 | <li><tt>receive</tt> has a batched mode to consume more than one value from a single key, as in <tt>linda:receive(1.0, linda.batched, "key", 3, 6).</tt></li> | 1247 | <li><tt>receive</tt> has a batched mode to consume more than one value from a single slot, as in <tt>linda:receive(1.0, linda.batched, "slot", 3, 6).</tt></li> |
1248 | <li>Individual keys' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li> | 1248 | <li><tt>restrict</tt> can restrain a particular slot to function either with <tt>send/receive</tt> or <tt>set/get</tt>.</li> |
1249 | <li>Individual slots' queue length can be limited, balancing speed differences in a producer/consumer scenario (making <tt>:send</tt> wait).</li> | ||
1249 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</tt></li> | 1250 | <li><tt>tostring(linda)</tt> returns a string of the form <tt>"Linda: <opt_name>"</tt></li> |
1250 | <li> | 1251 | <li> |
1251 | Several linda objects may share the same <a href="#keepers">Keeper state</a>. In case there is more than one user <a href="#keepers">Keeper state</a>, assignation must be controlled with the linda's group (an integer in <tt>[0,nb_user_keepers]</tt>). | 1252 | Several linda objects may share the same <a href="#keepers">Keeper state</a>. In case there is more than one user <a href="#keepers">Keeper state</a>, assignation must be controlled with the linda's group (an integer in <tt>[0,nb_user_keepers]</tt>). |
@@ -1272,65 +1273,84 @@ | |||
1272 | </p> | 1273 | </p> |
1273 | 1274 | ||
1274 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1275 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1275 | bool,string|(nil,[lanes.cancel_error|"timeout"]) = h:limit(key, <limit>) | 1276 | bool,string|(nil,[lanes.cancel_error|"timeout"]) = h:limit(slot, <limit>) |
1276 | (number|string),string = h:limit(key) | 1277 | (number|string),string = h:limit(slot) |
1277 | </pre></td></tr></table> | 1278 | </pre></td></tr></table> |
1278 | 1279 | ||
1279 | <p> | 1280 | <p> |
1280 | By default, queue sizes are unlimited but limits can be enforced using the <tt>limit()</tt> method. This can be useful to balance execution speeds in a producer/consumer scenario.<br /> | 1281 | By default, queue sizes are unlimited but limits can be enforced using the <tt>limit()</tt> method. This can be useful to balance execution speeds in a producer/consumer scenario.<br /> |
1281 | A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br /> | 1282 | A limit of 0 is allowed to block everything. <tt>"unlimited"</tt> removes the limit.<br /> |
1282 | If the key was full but the limit change added some room, <tt>limit()</tt> first return value is <tt>true</tt> and the linda is signalled so that <tt>send()</tt>-blocked threads are awakened, else the return value is <tt>false</tt>. | 1283 | If the slot was full but the limit change added some room, <tt>limit()</tt> first return value is <tt>true</tt> and the linda is signalled so that <tt>send()</tt>-blocked threads are awakened, else the return value is <tt>false</tt>. |
1283 | If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified key.<br /> | 1284 | If no limit is provided, <tt>limit()</tt> first return value is the current limit for the specified slot.<br /> |
1284 | The second returned value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). | 1285 | The second returned value is a string representing the fill status relatively to the slot's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). |
1285 | Whether reading or writing, if the linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>. | 1286 | Whether reading or writing, if the linda is cancelled, <tt>limit()</tt> returns <tt>nil, lanes.cancel_error</tt>. |
1286 | </p> | 1287 | </p> |
1287 | 1288 | ||
1288 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1289 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1289 | true|lanes.cancel_error = h:send([timeout_secs,] key, ...) | 1290 | string|(nil,[lanes.cancel_error|"timeout"]) = h:restrict(slot [, "<mode>"]) |
1291 | string = h:restrict(slot) | ||
1290 | </pre></td></tr></table> | 1292 | </pre></td></tr></table> |
1291 | 1293 | ||
1292 | <p> | 1294 | <p> |
1293 | Timeouts are given in seconds (>= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first key is not a number (then it is equivalent to an infinite duration).<br /> | 1295 | It is possible to restrict a particular slot in a Linda to either <tt>send/receive</tt> or <tt>set/get</tt> operations.<br /> |
1294 | Each key acts as a FIFO queue. There is no limit to the number of keys a linda may contain. Different lindas can have identical keys, which are totally unrelated. | 1296 | Possible modes are <tt>"none"</tt>, <tt>"set/get"</tt> or <tt>"send/receive"</tt>.<br /> |
1297 | If a new mode is specified, <tt>restrict()</tt> updates the mode and returns the previous one.<br /> | ||
1298 | If no mode is specified, <tt>restrict()</tt> does nothing and returns the current mode.<br /> | ||
1299 | If the linda is cancelled, <tt>restrict()</tt> returns <tt>nil, lanes.cancel_error</tt>.<br /> | ||
1300 | If an unknown mode is specified, <tt>restrict()</tt> raises an error. | ||
1301 | </p> | ||
1302 | |||
1303 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | ||
1304 | true|lanes.cancel_error = h:send([timeout_secs,] slot, ...) | ||
1305 | </pre></td></tr></table> | ||
1306 | |||
1307 | <p> | ||
1308 | Timeouts are given in seconds (>= 0, millisecond accuracy) or <tt>nil</tt>. Timeout can be omitted only if the first slot is not a number (then it is equivalent to an infinite duration).<br /> | ||
1309 | Each slot acts as a FIFO queue. There is no limit to the number of slots a linda may contain. Different lindas can have identical slots, which are totally unrelated. | ||
1295 | </p> | 1310 | </p> |
1296 | 1311 | ||
1297 | <p> | 1312 | <p> |
1298 | Multiple values can be sent to a given key at once, atomically (the send will fail unless all the values fit within the queue limit). This can be useful for multiple producer scenarios, if the protocols used are giving data in streams of multiple units. | 1313 | Multiple values can be sent to a given slot at once, atomically (the send will fail unless all the values fit within the queue limit). This can be useful for multiple producer scenarios, if the protocols used are giving data in streams of multiple units. |
1299 | Atomicity avoids the producers from garbling each others messages, which could happen if the units were sent individually. | 1314 | Atomicity avoids the producers from garbling each others messages, which could happen if the units were sent individually. |
1300 | </p> | 1315 | </p> |
1301 | 1316 | ||
1302 | <p> | 1317 | <p> |
1303 | If no data is provided after the key, <tt>send()</tt> raises an error.<br /> | 1318 | If <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a linda, it will be read as a <tt>nil</tt>.<br /> |
1304 | Also, if <tt>linda.null</tt> or <tt>lanes.null</tt> is sent as data in a linda, it will be read as a <tt>nil</tt>.<br /> | 1319 | </p> |
1320 | |||
1321 | <p> | ||
1322 | <tt>send()</tt> raises an error if no data is provided after the slot.<br /> | ||
1323 | <tt>send()</tt> raises an error if called when a restriction forbids its use on the provided slot.<br /> | ||
1324 | <tt>send()</tt> raises <tt>lanes.cancel_error</tt> if interrupted by a hard cancel request.<br /> | ||
1305 | <tt>send()</tt> return values can be: | 1325 | <tt>send()</tt> return values can be: |
1306 | <ul> | 1326 | <ul> |
1307 | <li><tt>true</tt> on success.</li> | 1327 | <li><tt>true</tt> on success.</li> |
1308 | <li><tt>nil, "timeout"</tt> if the queue limit was met, and the queue did not empty enough during the given duration.</li> | 1328 | <li><tt>nil, "timeout"</tt> if the queue limit was met, and the queue did not empty enough during the given duration.</li> |
1309 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a soft cancel request.</li> | 1329 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a soft cancel request.</li> |
1310 | <li>Raises <tt>lanes.cancel_error</tt> if interrupted by a hard cancel request.</li> | ||
1311 | </ul> | 1330 | </ul> |
1312 | </p> | 1331 | </p> |
1313 | 1332 | ||
1314 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1333 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1315 | key, val = h:receive([timeout_secs,] key [, key...]) | 1334 | slot, val = h:receive([timeout_secs,] slot [, slot...]) |
1316 | 1335 | ||
1317 | key, val [, val...] = h:receive([timeout,] h.batched, key, n_uint_min[, n_uint_max]) | 1336 | slot, val [, val...] = h:receive([timeout,] h.batched, slot, n_uint_min[, n_uint_max]) |
1318 | </pre></td></tr></table> | 1337 | </pre></td></tr></table> |
1319 | 1338 | ||
1320 | <p> | 1339 | <p> |
1340 | <tt>receive()</tt> raises an error if called when a restriction forbids its use on any provided slot.<br /> | ||
1341 | In batched mode, <tt>receive()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>. | ||
1342 | </p> | ||
1343 | |||
1344 | <p> | ||
1321 | Unbatched <tt>receive()</tt> return values can be: | 1345 | Unbatched <tt>receive()</tt> return values can be: |
1322 | <ul> | 1346 | <ul> |
1323 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a hard cancel request.</li> | 1347 | <li><tt>nil, lanes.cancel_error</tt> if interrupted by a hard cancel request.</li> |
1324 | <li><tt>nil, "timeout"</tt> if nothing was available.</li> | 1348 | <li><tt>nil, "timeout"</tt> if nothing was available.</li> |
1325 | <li>A key and the value extracted from it. Note that <tt>nil</tt> can be sent and received; the <tt>key</tt> value will tell it apart from a timeout.</li> | 1349 | <li>A slot and the value extracted from it. Note that <tt>nil</tt> can be sent and received; the first returned value <tt>slot</tt> will tell it apart from a timeout.</li> |
1326 | </ul> | 1350 | </ul> |
1327 | </p> | 1351 | </p> |
1328 | 1352 | ||
1329 | <p> | 1353 | <p> |
1330 | In batched mode, <tt>linda:receive()</tt> will raise an error if <tt>min_count < 1</tt> or <tt>max_count < min_count</tt>. | ||
1331 | </p> | ||
1332 | |||
1333 | <p> | ||
1334 | Note that any number of lanes can be reading or writing a linda. There can be many producers, and many consumers. It is up to you. | 1354 | Note that any number of lanes can be reading or writing a linda. There can be many producers, and many consumers. It is up to you. |
1335 | </p> | 1355 | </p> |
1336 | 1356 | ||
@@ -1339,19 +1359,20 @@ | |||
1339 | </p> | 1359 | </p> |
1340 | 1360 | ||
1341 | <p> | 1361 | <p> |
1342 | When receiving from multiple slots, the keys are checked in order, which can be used for making priority queues. | 1362 | When receiving from multiple slots, the slots are checked in order, which can be used for making priority queues. |
1343 | </p> | 1363 | </p> |
1344 | 1364 | ||
1345 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1365 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1346 | (bool,string)|(nil,lanes.cancel_error) = linda_h:set(key [, val [, ...]]) | 1366 | (bool,string)|(nil,lanes.cancel_error) = linda_h:set(slot [, val [, ...]]) |
1347 | 1367 | ||
1348 | (number,[val [, ...]])|(nil,lanes.cancel_error) = linda_h:get(key [, count = 1]) | 1368 | (number,[val [, ...]])|(nil,lanes.cancel_error) = linda_h:get(slot [, count = 1]) |
1349 | </pre></td></tr></table> | 1369 | </pre></td></tr></table> |
1350 | 1370 | ||
1351 | <p> | 1371 | <p> |
1352 | <tt>get()</tt>/<tt>set()</tt> and <tt>send()</tt>/<tt>receive()</tt> can be used together; reading a slot essentially peeks the next outcoming value of a queue.<br /> | 1372 | <tt>set()</tt> and <tt>get()</tt> raise an error if used when a restriction forbids their use on the provided slot.<br /> |
1353 | <tt>get()</tt>/<tt>set()</tt> are for accessing a key without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br /> | 1373 | Unless a particular slot is constrained with <tt>restrict()</tt>, <tt>get()</tt>/<tt>set()</tt> and <tt>send()</tt>/<tt>receive()</tt> can be used together; reading a slot essentially peeks the next outcoming value of a queue.<br /> |
1354 | Writing to a key never blocks because it ignores the limit. It overwrites existing values and clears any possible queued entries.<br /> | 1374 | <tt>get()</tt>/<tt>set()</tt> are for accessing a slot without queuing or consuming. They can be used for making shared tables of storage among the lanes.<br /> |
1375 | <tt>set()</tt> never blocks because it ignores the limit. It overwrites existing values and clears any possible queued entries.<br /> | ||
1355 | </p> | 1376 | </p> |
1356 | <p> | 1377 | <p> |
1357 | <tt>get()</tt> can read several values at once, and does not block. Return values ares: | 1378 | <tt>get()</tt> can read several values at once, and does not block. Return values ares: |
@@ -1361,12 +1382,12 @@ | |||
1361 | </ul> | 1382 | </ul> |
1362 | </p> | 1383 | </p> |
1363 | <p> | 1384 | <p> |
1364 | <tt>set()</tt> can write several values at the specified key. Writing <tt>nil</tt> values is possible, and clearing the contents at the specified key is done by not providing any value.<br /> | 1385 | <tt>set()</tt> can write several values at the specified slot. Writing <tt>nil</tt> values is possible, and clearing the contents at the specified slot is done by not providing any value.<br /> |
1365 | If <tt>set()</tt> actually stores data, the linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br /> | 1386 | If <tt>set()</tt> actually stores data, the linda is signalled for write, so that <tt>receive()</tt>-blocked Lanes are awakened.<br /> |
1366 | Clearing the contents of a non-existent key does not create it!<br /> | 1387 | Clearing the contents of a non-existent slot does not create it!<br /> |
1367 | If the key was full but the new data count of the key after <tt>set()</tt> is below its limit, <tt>set()</tt> first return value is <tt>true</tt> and the linda is also signaled for read, so that <tt>send()</tt>-blocked Lanes are awakened.<br /> | 1388 | If the slot was full but the new data count of the slot after <tt>set()</tt> is below its limit, <tt>set()</tt> first return value is <tt>true</tt> and the linda is also signaled for read, so that <tt>send()</tt>-blocked Lanes are awakened.<br /> |
1368 | If the key was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br /> | 1389 | If the slot was not already full, nothing additional happens, and <tt>set()</tt> first return value is <tt>false</tt>.<br /> |
1369 | The second return value is a string representing the fill status relatively to the key's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). | 1390 | The second return value is a string representing the fill status relatively to the slot's current limit (one of <tt>"over"</tt>, <tt>"under"</tt>, <tt>"exact"</tt>). |
1370 | </p> | 1391 | </p> |
1371 | 1392 | ||
1372 | <p> | 1393 | <p> |
@@ -1374,25 +1395,26 @@ | |||
1374 | </p> | 1395 | </p> |
1375 | 1396 | ||
1376 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1397 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1377 | [val] = linda_h:count([key[,...]]) | 1398 | [val] = linda_h:count([slot[,...]]) |
1378 | </pre></td></tr></table> | 1399 | </pre></td></tr></table> |
1379 | 1400 | ||
1380 | <p> | 1401 | <p> |
1381 | Returns some information about the contents of the linda.<br /> | 1402 | Returns some information about the contents of the linda.<br /> |
1382 | If no key is specified, and the linda is empty, returns nothing.<br /> | 1403 | If no slot is specified, and the linda is empty, returns nothing.<br /> |
1383 | If no key is specified, and the linda is not empty, returns a table of key/count pairs that counts the number of items in each of the exiting keys of the linda. This count can be 0 if the key has been used but is empty.<br /> | 1404 | If no slot is specified, and the linda is not empty, returns a table of slot/count pairs that counts the number of items in each of the exiting slots of the linda. This count can be 0 if the slot has been used but is empty.<br /> |
1384 | If a single key is specified, returns the number of pending items, or nothing if the key is unknown.<br /> | 1405 | If a single slot is specified, returns the number of pending items, or nothing if the slot is unknown.<br /> |
1385 | If more than one key is specified, return a table of key/count pairs for the known keys. | 1406 | If more than one slot is specified, return a table of slot/count pairs for the known slots. |
1386 | </p> | 1407 | </p> |
1387 | 1408 | ||
1388 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1409 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1389 | linda_h:dump() -> | 1410 | linda_h:dump() -> |
1390 | { | 1411 | { |
1391 | [<key>] = | 1412 | [<slot>] = |
1392 | { | 1413 | { |
1393 | first = <n> | 1414 | first = <n> |
1394 | count = <n> | 1415 | count = <n> |
1395 | limit = <n>|'unlimited' | 1416 | limit = <n>|'unlimited' |
1417 | restrict = "none"|"set/get"|"send/receive" | ||
1396 | fifo = { <array of values> } | 1418 | fifo = { <array of values> } |
1397 | } | 1419 | } |
1398 | ... | 1420 | ... |
@@ -1458,7 +1480,7 @@ | |||
1458 | </li> | 1480 | </li> |
1459 | 1481 | ||
1460 | <li> | 1482 | <li> |
1461 | Namespace control. linda keys have a "flat" namespace, so collisions are possible if you try to use the same linda for too many separate uses. | 1483 | Namespace control. linda slots have a "flat" namespace, so collisions are possible if you try to use the same linda for too many separate uses. |
1462 | </li> | 1484 | </li> |
1463 | 1485 | ||
1464 | <li> | 1486 | <li> |
@@ -1467,7 +1489,7 @@ | |||
1467 | </li> | 1489 | </li> |
1468 | </ul> | 1490 | </ul> |
1469 | 1491 | ||
1470 | On the other side, you need to use a common linda for waiting for multiple keys. You cannot wait for keys from two separate linda objects at the same time. | 1492 | On the other side, you need to use a common linda for waiting for multiple slots. You cannot wait for slots from two separate linda objects at the same time. |
1471 | </p> | 1493 | </p> |
1472 | 1494 | ||
1473 | <p> | 1495 | <p> |
@@ -1480,7 +1502,7 @@ | |||
1480 | <h2 id="timers">Timers</h2> | 1502 | <h2 id="timers">Timers</h2> |
1481 | 1503 | ||
1482 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1504 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1483 | void = lanes.timer(linda_h, key, date_tbl|first_secs [,period_secs]) | 1505 | void = lanes.timer(linda_h, slot, date_tbl|first_secs [,period_secs]) |
1484 | </pre></td></tr></table> | 1506 | </pre></td></tr></table> |
1485 | 1507 | ||
1486 | <p> | 1508 | <p> |
@@ -1492,7 +1514,7 @@ | |||
1492 | </p> | 1514 | </p> |
1493 | 1515 | ||
1494 | <p> | 1516 | <p> |
1495 | Once a timer expires, the <tt>key</tt> is set with the current time (in seconds, same offset as <tt>os.time()</tt> but with millisecond accuracy). The key can be waited upon using the regular <a href="#lindas">linda</a> <tt>:receive()</tt> method. | 1517 | Once a timer expires, the <tt>slot</tt> is set with the current time (in seconds, same offset as <tt>os.time()</tt> but with millisecond accuracy). The slot can be waited upon using the regular <a href="#lindas">linda</a> <tt>:receive()</tt> method. |
1496 | </p> | 1518 | </p> |
1497 | 1519 | ||
1498 | <p> | 1520 | <p> |
@@ -1517,13 +1539,13 @@ | |||
1517 | lanes.timer(linda, "min", t, 60) -- reoccur every minute (sharp) | 1539 | lanes.timer(linda, "min", t, 60) -- reoccur every minute (sharp) |
1518 | 1540 | ||
1519 | while true do | 1541 | while true do |
1520 | local key, v = linda:receive("sec", "min") | 1542 | local slot, v = linda:receive("sec", "min") |
1521 | print("Timer "..key..": "..v) | 1543 | print("Timer "..slot..": "..v) |
1522 | end | 1544 | end |
1523 | </pre></td></tr></table> | 1545 | </pre></td></tr></table> |
1524 | 1546 | ||
1525 | <p> | 1547 | <p> |
1526 | NOTE: Timer keys are set, not queued, so missing a beat is possible especially if the timer cycle is extremely small. The key value can be used to know the actual time passed. | 1548 | NOTE: Timer slots are set, not queued, so missing a beat is possible especially if the timer cycle is extremely small. The slot value can be used to know the actual time passed. |
1527 | </p> | 1549 | </p> |
1528 | 1550 | ||
1529 | <table> | 1551 | <table> |
@@ -1533,7 +1555,7 @@ | |||
1533 | <font size="-1"> | 1555 | <font size="-1"> |
1534 | Having the API as <tt>lanes.timer()</tt> is intentional. Another alternative would be <tt>linda_h:timer()</tt> but timers are not traditionally seen to be part of lindas. Also, it would mean any lane getting a <a href="#lindas">linda</a> handle would be able to modify timers on it. | 1556 | Having the API as <tt>lanes.timer()</tt> is intentional. Another alternative would be <tt>linda_h:timer()</tt> but timers are not traditionally seen to be part of lindas. Also, it would mean any lane getting a <a href="#lindas">linda</a> handle would be able to modify timers on it. |
1535 | A third choice could be abstracting the timers out of <a href="#lindas">linda</a> realm altogether (<tt>timer_h= lanes.timer(date|first_secs, period_secs )</tt>) but that would mean separate waiting functions for timers, and lindas. | 1557 | A third choice could be abstracting the timers out of <a href="#lindas">linda</a> realm altogether (<tt>timer_h= lanes.timer(date|first_secs, period_secs )</tt>) but that would mean separate waiting functions for timers, and lindas. |
1536 | Even if a <a href="#lindas">linda</a> object and key was returned, that key couldn't be waited upon simultaneously with one's general <a href="#lindas">linda</a> events. | 1558 | Even if a <a href="#lindas">linda</a> object and slot was returned, that slot couldn't be waited upon simultaneously with one's general <a href="#lindas">linda</a> events. |
1537 | The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level. | 1559 | The current system gives maximum capabilities with minimum API, and any smoothenings can easily be crafted in Lua at the application level. |
1538 | </font> | 1560 | </font> |
1539 | </td> | 1561 | </td> |
@@ -1578,7 +1600,7 @@ | |||
1578 | </p> | 1600 | </p> |
1579 | 1601 | ||
1580 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1602 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1581 | lock_func|lanes.cancel_error = lanes.genlock(linda_h, key [,N_uint=1]) | 1603 | lock_func|lanes.cancel_error = lanes.genlock(linda_h, slot [,N_uint=1]) |
1582 | 1604 | ||
1583 | bool|lanes.cancel_error = lock_func(M_uint [, "try"] ) -- acquire | 1605 | bool|lanes.cancel_error = lock_func(M_uint [, "try"] ) -- acquire |
1584 | .. | 1606 | .. |
@@ -1604,13 +1626,13 @@ | |||
1604 | <p> | 1626 | <p> |
1605 | 1627 | ||
1606 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1628 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1607 | atomic_func|lanes.cancel_error = lanes.genatomic(linda_h, key [,initial_num=0.0]) | 1629 | atomic_func|lanes.cancel_error = lanes.genatomic(linda_h, slot [,initial_num=0.0]) |
1608 | 1630 | ||
1609 | new_num|lanes.cancel_error = atomic_func([diff_num=+1.0]) | 1631 | new_num|lanes.cancel_error = atomic_func([diff_num=+1.0]) |
1610 | </pre></td></tr></table> | 1632 | </pre></td></tr></table> |
1611 | 1633 | ||
1612 | <p> | 1634 | <p> |
1613 | Each time called, the generated function will change <tt>linda[key]</tt> atomically, without other lanes being able to interfere. The new value is returned. You can use either <tt>diff 0.0</tt> or <tt>get</tt> to just read the current value. | 1635 | Each time called, the generated function will change <tt>linda[slot]</tt> atomically, without other lanes being able to interfere. The new value is returned. You can use either <tt>diff 0.0</tt> or <tt>get</tt> to just read the current value. |
1614 | </p> | 1636 | </p> |
1615 | 1637 | ||
1616 | <p> | 1638 | <p> |
@@ -1632,7 +1654,7 @@ | |||
1632 | <li>Booleans, numbers, strings, light userdata, Lua functions and tables of such can always be passed.</li> | 1654 | <li>Booleans, numbers, strings, light userdata, Lua functions and tables of such can always be passed.</li> |
1633 | <li> | 1655 | <li> |
1634 | Cyclic tables and/or duplicate references are allowed and reproduced appropriately, but only <u>within the same transmission</u>. | 1656 | Cyclic tables and/or duplicate references are allowed and reproduced appropriately, but only <u>within the same transmission</u>. |
1635 | Using the same source table in multiple <a href="#lindas">linda</a> messages keeps no ties between the tables (this is the same reason why tables can't be used as keys). | 1657 | Using the same source table in multiple <a href="#lindas">linda</a> messages keeps no ties between the tables (this is the same reason why tables can't be used as slots). |
1636 | </li> | 1658 | </li> |
1637 | <li> | 1659 | <li> |
1638 | For tables and full userdata: before anything else, the metatable is searched for a <tt>__lanesconvert</tt> field. If found, the source object is converted as follows depending on <tt>__lanesconvert</tt>'s value: | 1660 | For tables and full userdata: before anything else, the metatable is searched for a <tt>__lanesconvert</tt> field. If found, the source object is converted as follows depending on <tt>__lanesconvert</tt>'s value: |
@@ -1914,7 +1936,7 @@ static MyDeepFactory g_MyDeepFactory; | |||
1914 | <ul> | 1936 | <ul> |
1915 | <li>Data passing (arguments, upvalues, <a href="#lindas">linda</a> messages) is generally fast, doing two binary state-to-state copies (from source state to hidden state, hidden state to target state). Remember that not only the function you specify but also its upvalues, their upvalues, etc. etc. will get copied.</li> | 1937 | <li>Data passing (arguments, upvalues, <a href="#lindas">linda</a> messages) is generally fast, doing two binary state-to-state copies (from source state to hidden state, hidden state to target state). Remember that not only the function you specify but also its upvalues, their upvalues, etc. etc. will get copied.</li> |
1916 | <li>Lane startup is fast (1000's of lanes a second), depending on the number of standard libraries initialized. Initializing all standard libraries is about 3-4 times slower than having no standard libraries at all. If you throw in a lot of lanes per second, make sure you give them minimal necessary set of libraries.</li> | 1938 | <li>Lane startup is fast (1000's of lanes a second), depending on the number of standard libraries initialized. Initializing all standard libraries is about 3-4 times slower than having no standard libraries at all. If you throw in a lot of lanes per second, make sure you give them minimal necessary set of libraries.</li> |
1917 | <li>Waiting lindas are woken up (and execute some hidden Lua code) each time <u>any</u> key in the <a href="#lindas">lindas</a> they are waiting for are changed. This may give essential slow-down (not measured, just a gut feeling) if a lot of <a href="#lindas">linda</a> keys are used. Using separate <a href="#lindas">lindas</a> for logically separate issues will help (which is good practice anyhow).</li> | 1939 | <li>Waiting lindas are woken up (and execute some hidden Lua code) each time <u>any</u> slot in the <a href="#lindas">lindas</a> they are waiting for are changed. This may give essential slow-down (not measured, just a gut feeling) if a lot of <a href="#lindas">linda</a> slots are used. Using separate <a href="#lindas">lindas</a> for logically separate issues will help (which is good practice anyhow).</li> |
1918 | <li><a href="#lindas">linda</a> objects are light. The memory footprint is two OS-level signalling objects (<tt>HANDLE</tt> or <tt>pthread_cond_t</tt>) for each, plus one C pointer for the proxies per each Lua state using the <a href="#lindas">linda</a>. Barely nothing.</li> | 1940 | <li><a href="#lindas">linda</a> objects are light. The memory footprint is two OS-level signalling objects (<tt>HANDLE</tt> or <tt>pthread_cond_t</tt>) for each, plus one C pointer for the proxies per each Lua state using the <a href="#lindas">linda</a>. Barely nothing.</li> |
1919 | <li>Timers are light. You can probably expect timers up to 0.01 second resolution to be useful, but that is very system specific. All timers are merged into one main timer state (see <tt>timer.lua</tt>); no OS side timers are utilized.</li> | 1941 | <li>Timers are light. You can probably expect timers up to 0.01 second resolution to be useful, but that is very system specific. All timers are merged into one main timer state (see <tt>timer.lua</tt>); no OS side timers are utilized.</li> |
1920 | <li>If you are using a lot of <a href="#lindas">linda</a> objects, it may be useful to try having more of these <a href="#keepers">Keeper states</a>. By default, only one is used (see <a href="#initialization"><tt>lanes.configure()</tt></a>).</li> | 1942 | <li>If you are using a lot of <a href="#lindas">linda</a> objects, it may be useful to try having more of these <a href="#keepers">Keeper states</a>. By default, only one is used (see <a href="#initialization"><tt>lanes.configure()</tt></a>).</li> |