diff --git a/platform/msvc2008/love.vcproj b/platform/msvc2008/love.vcproj index a4b7006f2..714bb5ebb 100644 --- a/platform/msvc2008/love.vcproj +++ b/platform/msvc2008/love.vcproj @@ -3909,98 +3909,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -namespace love -{ -namespace lanes -{ - int open(lua_State * L); - -} // lanes -} // love - -#endif // LOVE_LANES_LANES_H diff --git a/src/libraries/lanes/lanes/keeper.lch b/src/libraries/lanes/lanes/keeper.lch deleted file mode 100644 index ccac6de2a..000000000 --- a/src/libraries/lanes/lanes/keeper.lch +++ /dev/null @@ -1,214 +0,0 @@ -/* bin2c.lua generated code -- DO NOT EDIT - * - * To use from C source: - * char my_chunk[]= - * #include "my.lch" - */ -{ - 27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 12, 0, 0, 0, 64,107,101,101, - 112,101,114, 46,108,117, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9, - 45, 0, 0, 0, 5, 0, 0, 0, 69, 64, 0, 0, 28, 64, 0, 1, 5, 0, 0, 0, - 69,128, 0, 0, 70,192,192, 0, 28,128, 0, 1, 69, 0, 0, 0,133,128, 0, 0, - 134, 0, 65, 1, 92,128, 0, 1,164, 0, 0, 0, 0, 0,128, 0,202, 0, 0, 0, - 10, 1, 0, 0, 74, 1, 0, 0,164, 65, 0, 0, 0, 0,128, 1, 0, 0, 0, 2, - 0, 0,128, 2,228,129, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 36,194, 0, 0, - 0, 0, 0, 3, 7, 66, 1, 0, 36, 2, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, - 7,130, 1, 0, 36, 66, 1, 0, 0, 0, 0, 3, 7,194, 1, 0, 36,130, 1, 0, - 0, 0, 0, 3, 7, 2, 2, 0, 36,194, 1, 0, 0, 0, 0, 3, 7, 66, 2, 0, - 36, 2, 2, 0, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2, 7,130, 2, 0, - 30, 0,128, 0, 11, 0, 0, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0, - 4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108, 0, 4, 6, - 0, 0, 0,116, 97, 98,108,101, 0, 4, 7, 0, 0, 0,114,101,109,111,118,101, - 0, 4, 7, 0, 0, 0, 99,111,110, 99, 97,116, 0, 4, 5, 0, 0, 0,115,101, - 110,100, 0, 4, 8, 0, 0, 0,114,101, 99,101,105,118,101, 0, 4, 6, 0, 0, - 0,108,105,109,105,116, 0, 4, 4, 0, 0, 0,115,101,116, 0, 4, 4, 0, 0, - 0,103,101,116, 0, 4, 6, 0, 0, 0, 99,108,101, 97,114, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 46, 0, 0, 0, 50, 0, 0, 0, 1, 0, 3, 6, 16, 0, 0, 0, - 69, 0, 0, 0, 90, 0, 0, 0, 22,192, 2,128, 69, 0, 0, 0, 70, 64,192, 0, - 75,128,192, 0,196, 0, 0, 0, 10, 1, 0, 0,101, 1, 0, 0, 34, 65, 0, 0, - 65,193, 0, 0,220,128,128, 1, 1, 1, 1, 0,213, 0,129, 1, 92, 64,128, 1, - 30, 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0,105,111, 0, 4, 7, 0, 0, - 0,115,116,100,101,114,114, 0, 4, 6, 0, 0, 0,119,114,105,116,101, 0, 4, - 2, 0, 0, 0, 9, 0, 4, 2, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, - 0, 47, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, - 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, - 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, - 0, 50, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0, - 0, 15, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0,116, 97, 98,108,101, 95, 99, - 111,110, 99, 97,116, 0, 0, 0, 0, 0, 84, 0, 0, 0, 93, 0, 0, 0, 3, 1, - 0, 4, 21, 0, 0, 0, 68, 0, 0, 0, 70, 0,128, 0, 90, 64, 0, 0, 22, 0, - 2,128, 68, 0, 0, 0,138, 0, 0, 0, 73,128, 0, 0, 68, 0,128, 0,138, 0, - 0, 0, 73,128, 0, 0, 68, 0, 0, 1,138, 0, 0, 0, 73,128, 0, 0, 68, 0, - 0, 0, 70, 0,128, 0,132, 0,128, 0,134, 0, 0, 1,196, 0, 0, 1,198, 0, - 128, 1, 94, 0, 0, 2, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, - 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 88, 0, - 0, 0, 88, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 89, 0, 0, 0, 89, 0, - 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 92, 0, 0, 0, 92, 0, - 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, - 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0, - 0, 20, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 95,100, 97,116, 97, 0, 10, - 0, 0, 0, 95,105,110, 99,111,109,105,110,103, 0, 8, 0, 0, 0, 95,108,105, - 109,105,116,115, 0, 0, 0, 0, 0, 96, 0, 0, 0,106, 0, 0, 0, 2, 3, 0, - 16, 40, 0, 0, 0,197, 0, 0, 0, 27, 1, 0, 0, 22,128, 0,128, 27, 1,128, - 0, 22, 0, 0,128, 0, 1, 0, 1,220, 64, 0, 1,196, 0, 0, 0, 0, 1,128, - 0,220, 0, 1, 1,133, 65, 0, 0,198,129,128, 1,156,129, 0, 1,197,129, 0, - 0, 6,130, 0, 2, 26, 66, 0, 0, 22, 0, 0,128, 10, 2, 0, 0,220, 1, 1, - 1, 22, 64, 1,128, 0, 3, 0, 3, 65,195, 0, 0,133, 67, 0, 0,192, 3,128, - 5,156,131, 0, 1,149,129, 3, 6,225,129, 0, 0, 22,192,253,127,196, 1,128, - 0, 1, 2, 1, 0, 64, 2, 0, 0,129, 66, 1, 0,197, 66, 0, 0, 0, 3, 0, - 1,220,130, 0, 1, 1,131, 1, 0, 21, 2, 3, 4, 64, 2, 0, 3,220, 65,128, - 1, 30, 0,128, 0, 7, 0, 0, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, - 0, 4, 9, 0, 0, 0,116,111,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0, - 105,112, 97,105,114,115, 0, 4, 3, 0, 0, 0, 44, 32, 0, 4, 5, 0, 0, 0, - 42, 42, 42, 32, 0, 4, 3, 0, 0, 0, 32, 40, 0, 4, 4, 0, 0, 0, 41, 58, - 32, 0, 0, 0, 0, 0, 40, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0, - 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 99, 0, - 0, 0, 99, 0, 0, 0, 99, 0, 0, 0,101, 0, 0, 0,101, 0, 0, 0,101, 0, - 0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0, - 0, 0,102, 0, 0, 0,102, 0, 0, 0,103, 0, 0, 0,103, 0, 0, 0,103, 0, - 0, 0,103, 0, 0, 0,103, 0, 0, 0,103, 0, 0, 0,102, 0, 0, 0,103, 0, - 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, - 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, - 0, 0,105, 0, 0, 0,106, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0,116,105, - 116,108,101, 0, 0, 0, 0, 0, 39, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, - 0, 0, 0, 39, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 39, - 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 10, 0, 0, 0, 39, 0, 0, 0, - 9, 0, 0, 0,105,110, 99,111,109,105,110,103, 0, 10, 0, 0, 0, 39, 0, 0, - 0, 2, 0, 0, 0, 95, 0, 10, 0, 0, 0, 39, 0, 0, 0, 2, 0, 0, 0,115, - 0, 13, 0, 0, 0, 39, 0, 0, 0, 16, 0, 0, 0, 40,102,111,114, 32,103,101, - 110,101,114, 97,116,111,114, 41, 0, 19, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0, - 0, 40,102,111,114, 32,115,116, 97,116,101, 41, 0, 19, 0, 0, 0, 28, 0, 0, - 0, 14, 0, 0, 0, 40,102,111,114, 32, 99,111,110,116,114,111,108, 41, 0, 19, - 0, 0, 0, 28, 0, 0, 0, 2, 0, 0, 0, 95, 0, 20, 0, 0, 0, 26, 0, 0, - 0, 2, 0, 0, 0,118, 0, 20, 0, 0, 0, 26, 0, 0, 0, 2, 0, 0, 0, 7, - 0, 0, 0,116, 97, 98,108,101,115, 0, 3, 0, 0, 0, 87, 82, 0, 0, 0, 0, - 0,121, 0, 0, 0,158, 0, 0, 0, 1, 2, 3, 16, 56, 0, 0, 0,196, 0, 0, - 0, 0, 1, 0, 0,220, 0, 1, 1,133, 1, 0, 0,193, 65, 0, 0, 37, 2, 0, - 0,156,129, 0, 0, 23,128, 64, 3, 22, 64, 0,128,194, 1,128, 0,222, 1, 0, - 1,198, 65, 0, 2, 23,192,192, 3, 22, 64, 0,128,202, 1, 0, 0, 9,193,129, - 0,198, 65,128, 1,218, 1, 0, 0, 22, 0, 1,128,198, 65, 0, 2,212, 1,128, - 3,204,193, 1,130,218, 65, 0, 0, 22, 0, 0,128,193,129, 0, 0, 6, 66,128, - 2, 26, 2, 0, 0, 22, 0, 1,128, 76,130,129, 3, 24, 64, 2, 4, 22, 64, 0, - 128, 66, 2, 0, 0, 94, 2, 0, 1, 65, 2, 1, 0,128, 2, 0, 3,193, 2, 1, - 0, 96,130, 3,128, 69, 3, 0, 0,128, 3, 0, 6,229, 3, 0, 0, 92,131, 0, - 0, 23,192,192, 6, 22, 0, 0,128, 69, 67, 1, 0, 23,128,192, 3, 22,128, 0, - 128,201, 64,131, 0,193, 1, 1, 0, 22,128, 0,128,134, 67, 0, 2,137, 67,131, - 3,204, 1,193, 3, 95,194,251,127, 66, 2,128, 0, 94, 2, 0, 1, 30, 0,128, - 0, 6, 0, 0, 0, 4, 7, 0, 0, 0,115,101,108,101, 99,116, 0, 4, 2, 0, - 0, 0, 35, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, - 0,240, 63, 4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108, - 0, 0, 0, 0, 0, 56, 0, 0, 0,123, 0, 0, 0,123, 0, 0, 0,123, 0, 0, - 0,125, 0, 0, 0,125, 0, 0, 0,125, 0, 0, 0,125, 0, 0, 0,126, 0, 0, - 0,126, 0, 0, 0,126, 0, 0, 0,126, 0, 0, 0,130, 0, 0, 0,130, 0, 0, - 0,130, 0, 0, 0,131, 0, 0, 0,131, 0, 0, 0,134, 0, 0, 0,134, 0, 0, - 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, - 0,134, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,137, 0, 0, 0,137, 0, 0, - 0,137, 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,138, 0, 0, - 0,141, 0, 0, 0,141, 0, 0, 0,141, 0, 0, 0,141, 0, 0, 0,142, 0, 0, - 0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,145, 0, 0, 0,145, 0, 0, - 0,146, 0, 0, 0,149, 0, 0, 0,149, 0, 0, 0,150, 0, 0, 0,151, 0, 0, - 0,151, 0, 0, 0,153, 0, 0, 0,153, 0, 0, 0,154, 0, 0, 0,141, 0, 0, - 0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0, 14, 0, 0, 0, 3, 0, 0, - 0,117,100, 0, 0, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, - 0, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 3, 0, 0, 0, 55, 0, 0, - 0, 9, 0, 0, 0,105,110, 99,111,109,105,110,103, 0, 3, 0, 0, 0, 55, 0, - 0, 0, 7, 0, 0, 0,108,105,109,105,116,115, 0, 3, 0, 0, 0, 55, 0, 0, - 0, 2, 0, 0, 0,110, 0, 7, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0,108, - 101,110, 0, 25, 0, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0,109, 0, 26, 0, 0, - 0, 55, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,105,110,100,101,120, 41, - 0, 36, 0, 0, 0, 53, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,108,105, - 109,105,116, 41, 0, 36, 0, 0, 0, 53, 0, 0, 0, 11, 0, 0, 0, 40,102,111, - 114, 32,115,116,101,112, 41, 0, 36, 0, 0, 0, 53, 0, 0, 0, 2, 0, 0, 0, - 105, 0, 37, 0, 0, 0, 52, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 41, 0, - 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, - 0, 0, 0, 0, 0,167, 0, 0, 0,189, 0, 0, 0, 2, 1, 3, 14, 40, 0, 0, - 0,132, 0, 0, 0,192, 0, 0, 0,156, 0, 1, 1, 65, 1, 0, 0,133, 65, 0, - 0,193,129, 0, 0, 37, 2, 0, 0,156,129, 0, 0,193, 1, 0, 0, 96,193, 6, - 128, 69, 66, 0, 0,128, 2, 0, 4,229, 2, 0, 0, 92,130, 0, 0,134, 66, 2, - 1, 87,192, 64, 5, 22, 0, 5,128,198, 66,130, 1,218, 2, 0, 0, 22, 64, 2, - 128,198, 66,130, 1,198, 2,192, 5, 87,192,192, 5, 22, 64, 1,128,196, 2,128, - 0, 6, 67,130, 1, 65, 3, 0, 0,220,130,128, 1,137,192,130, 4, 22, 0, 0, - 128,137,192,192, 4,197, 2, 1, 0, 23,192, 2, 5, 22, 0, 0,128,131, 2, 0, - 5,192, 2, 0, 5, 0, 3,128, 4,222, 2,128, 1, 95,129,248,127, 30, 0,128, - 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 7, 0, 0, 0,115, - 101,108,101, 99,116, 0, 4, 2, 0, 0, 0, 35, 0, 0, 4, 13, 0, 0, 0,110, - 105,108, 95,115,101,110,116,105,110,101,108, 0, 0, 0, 0, 0, 40, 0, 0, 0, - 169, 0, 0, 0,169, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0, - 171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0, - 172, 0, 0, 0,172, 0, 0, 0,172, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0, - 175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0, - 176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,178, 0, 0, 0, - 178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0, - 180, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0, - 185, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,171, 0, 0, 0,189, 0, 0, 0, - 11, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0, 0, 39, 0, 0, 0, 4, - 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 39, 0, 0, 0, 5, 0, 0, 0,100, - 97,116, 97, 0, 3, 0, 0, 0, 39, 0, 0, 0, 9, 0, 0, 0,105,110, 99,111, - 109,105,110,103, 0, 3, 0, 0, 0, 39, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3, - 0, 0, 0, 39, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,105,110,100,101, - 120, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32, - 108,105,109,105,116, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 11, 0, 0, 0, 40, - 102,111,114, 32,115,116,101,112, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 2, 0, - 0, 0,105, 0, 10, 0, 0, 0, 38, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, - 14, 0, 0, 0, 38, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 15, 0, 0, 0, - 38, 0, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 13, - 0, 0, 0,116, 97, 98,108,101, 95,114,101,109,111,118,101, 0, 0, 0, 0, 0, - 195, 0, 0, 0,200, 0, 0, 0, 1, 3, 0, 6, 5, 0, 0, 0,196, 0, 0, 0, - 0, 1, 0, 0,220, 0, 1, 1, 73,129,128, 0, 30, 0,128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0, - 199, 0, 0, 0,200, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 4, - 0, 0, 0, 2, 0, 0, 0,110, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, - 0, 95, 0, 3, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3, 0, 0, - 0, 4, 0, 0, 0, 7, 0, 0, 0,108,105,109,105,116,115, 0, 3, 0, 0, 0, - 4, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0, - 0, 0, 0,206, 0, 0, 0,214, 0, 0, 0, 1, 3, 0, 6, 6, 0, 0, 0,196, - 0, 0, 0, 0, 1, 0, 0,220, 0, 1, 1,201,128,128, 0, 9, 1,192, 0, 30, - 0,128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,208, 0, 0, 0, - 208, 0, 0, 0,208, 0, 0, 0,212, 0, 0, 0,213, 0, 0, 0,214, 0, 0, 0, - 6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, - 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0,118, - 97,108, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, - 3, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0,105,110, 99,111,109,105,110,103, - 0, 3, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3, 0, 0, 0, 5, - 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0, 0, - 0, 0,220, 0, 0, 0,229, 0, 0, 0, 1, 2, 0, 7, 10, 0, 0, 0,132, 0, - 0, 0,192, 0, 0, 0,156, 0, 1, 1, 70, 65, 0, 1,133, 1, 0, 0, 23,128, - 129, 2, 22, 0, 0,128, 67, 1,128, 2, 94, 1, 0, 1, 30, 0,128, 0, 1, 0, - 0, 0, 4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108, 0, - 0, 0, 0, 0, 10, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0, - 224, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,226, 0, 0, 0, - 228, 0, 0, 0,229, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 3, 0, 0, 0, 9, 0, 0, 0, - 2, 0, 0, 0, 95, 0, 3, 0, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 95, 0, - 3, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 4, 0, 0, 0, - 9, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0, - 0, 0, 0,237, 0, 0, 0,242, 0, 0, 0, 3, 1, 0, 2, 7, 0, 0, 0, 68, - 0, 0, 0, 73, 0, 64, 0, 68, 0,128, 0, 73, 0, 64, 0, 68, 0, 0, 1, 73, - 0, 64, 0, 30, 0,128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,241, 0, 0, 0, - 241, 0, 0, 0,242, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 95,100, 97,116, 97, - 0, 10, 0, 0, 0, 95,105,110, 99,111,109,105,110,103, 0, 8, 0, 0, 0, 95, - 108,105,109,105,116,115, 0, 45, 0, 0, 0, 39, 0, 0, 0, 39, 0, 0, 0, 39, - 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44, - 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 50, 0, 0, 0, 50, - 0, 0, 0, 59, 0, 0, 0, 68, 0, 0, 0, 77, 0, 0, 0, 93, 0, 0, 0, 93, - 0, 0, 0, 93, 0, 0, 0, 93, 0, 0, 0,106, 0, 0, 0,106, 0, 0, 0,106, - 0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,121, 0, 0, 0,189, 0, 0, 0,189, - 0, 0, 0,189, 0, 0, 0,167, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,195, - 0, 0, 0,214, 0, 0, 0,214, 0, 0, 0,206, 0, 0, 0,229, 0, 0, 0,229, - 0, 0, 0,220, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,242, - 0, 0, 0,237, 0, 0, 0,242, 0, 0, 0, 8, 0, 0, 0, 13, 0, 0, 0,116, - 97, 98,108,101, 95,114,101,109,111,118,101, 0, 7, 0, 0, 0, 44, 0, 0, 0, - 13, 0, 0, 0,116, 97, 98,108,101, 95, 99,111,110, 99, 97,116, 0, 11, 0, 0, - 0, 44, 0, 0, 0, 3, 0, 0, 0, 87, 82, 0, 13, 0, 0, 0, 44, 0, 0, 0, - 6, 0, 0, 0, 95,100, 97,116, 97, 0, 14, 0, 0, 0, 44, 0, 0, 0, 10, 0, - 0, 0, 95,105,110, 99,111,109,105,110,103, 0, 15, 0, 0, 0, 44, 0, 0, 0, - 8, 0, 0, 0, 95,108,105,109,105,116,115, 0, 16, 0, 0, 0, 44, 0, 0, 0, - 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 20, 0, 0, 0, 44, 0, 0, 0, 6, - 0, 0, 0, 68, 69, 66, 85, 71, 0, 23, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, - 0,}; - diff --git a/src/libraries/lanes/lanes/keeper.lua b/src/libraries/lanes/lanes/keeper.lua deleted file mode 100644 index f76173b1e..000000000 --- a/src/libraries/lanes/lanes/keeper.lua +++ /dev/null @@ -1,244 +0,0 @@ --- --- KEEPER.LUA --- --- Keeper state logic --- --- This code is read in for each "keeper state", which are the hidden, inter- --- mediate data stores used by Lanes inter-state communication objects. --- --- Author: Asko Kauppi --- ---[[ -=============================================================================== - -Copyright (C) 2008 Asko Kauppi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -=============================================================================== -]]-- - --- unique key instead of 'nil' in queues --- -assert( nil_sentinel ) - --- We only need to have base and table libraries (and io for debugging) --- -local table_remove= assert( table.remove ) -local table_concat= assert( table.concat ) - -local function WR(...) - if io then - io.stderr:write( table_concat({...},'\t').."\n" ) - end -end - ------ --- Actual data store --- --- { [linda_deep_ud]= { key= val [, ...] } --- ... --- } --- -local _data= {} - ------ --- Entries queued for use when the existing 'data[ud][key]' entry is consumed. --- --- { [linda_deep_ud]= { key= { val [, ... } [, ...] } --- ... --- } --- -local _incoming= {} - ------ --- Length limits (if any) for queues --- --- 0: don't queue values at all; ':send()' waits if the slot is not vacant --- N: allow N values to be queued (slot itself + N-1); wait if full --- nil: no limits, '_incoming' may grow endlessly --- -local _limits= {} - ------ --- data_tbl, incoming_tbl, limits_tbl = tables( linda_deep_ud ) --- --- Gives appropriate tables for a certain Linda (creates them if needed) --- -local function tables( ud ) - -- tables are created either all or nothing - -- - if not _data[ud] then - _data[ud]= {} - _incoming[ud]= {} - _limits[ud]= {} - end - return _data[ud], _incoming[ud], _limits[ud] -end - - -local function DEBUG(title,ud,key) - assert( title and ud and key ) - - local data,incoming,_= tables(ud) - - local s= tostring(data[key]) - for _,v in ipairs( incoming[key] or {} ) do - s= s..", "..tostring(v) - end - WR( "*** "..title.." ("..tostring(key).."): ", s ) -end - - ------ --- bool= send( linda_deep_ud, key, ... ) --- --- Send new data (1..N) to 'key' slot. This send is atomic; all the values --- end up one after each other (this is why having possibility for sending --- multiple values in one call is deemed important). --- --- If the queue has a limit, values are sent only if all of them fit in. --- --- Returns: 'true' if all the values were placed --- 'false' if sending would exceed the queue limit (wait & retry) --- -function send( ud, key, ... ) - - local data,incoming,limits= tables(ud) - - local n= select('#',...) - if n==0 then return true end -- nothing to send - - -- Initialize queue for all keys that have been used with ':send()' - -- - if incoming[key]==nil then - incoming[key]= {} - end - - local len= data[key] and 1+#incoming[key] or 0 - local m= limits[key] - - if m and len+n > m then - return false -- would exceed the limit; try again later - end - - for i=1,n do - local val= select(i,...) - - -- 'nil' in the data replaced by sentinel - if val==nil then - val= nil_sentinel - end - - if len==0 then - data[key]= val - len= 1 - else - incoming[key][len]= val - len= len+1 - end - end - return true -end - - ------ --- [val, key]= receive( linda_deep_ud, key [, ...] ) --- --- Read any of the given keys, consuming the data found. Keys are read in --- order. --- -function receive( ud, ... ) - - local data,incoming,_= tables(ud) - - for i=1,select('#',...) do - local key= select(i,...) - local val= data[key] - - if val~=nil then - if incoming[key] and incoming[key][1]~=nil then - -- pop [1] from 'incoming[key]' into the actual slot - data[key]= table_remove( incoming[key], 1 ) - else - data[key]= nil -- empty the slot - end - if val==nil_sentinel then - val= nil - end - return val, key - end - end - --return nil -end - - ------ --- = limit( linda_deep_ud, key, uint ) --- -function limit( ud, key, n ) - - local _,_,limits= tables(ud) - - limits[key]= n -end - - ------ --- void= set( linda_deep_ud, key, [val] ) --- -function set( ud, key, val ) - - local data,incoming,_= tables(ud) - - -- Setting a key to 'nil' really clears it; only queing uses sentinels. - -- - data[key]= val - incoming[key]= nil -end - - ------ --- [val]= get( linda_deep_ud, key ) --- -function get( ud, key ) - - local data,_,_= tables(ud) - - local val= data[key] - if val==nil_sentinel then - val= nil - end - return val -end - - ------ --- void= clear( linda_deep_ud ) --- --- Clear the data structures used for a Linda (at its destructor) --- -function clear( ud ) - - _data[ud]= nil - _incoming[ud]= nil - _limits[ud]= nil -end - - diff --git a/src/libraries/lanes/lanes/lanes.c b/src/libraries/lanes/lanes/lanes.c deleted file mode 100644 index 5df9e2423..000000000 --- a/src/libraries/lanes/lanes/lanes.c +++ /dev/null @@ -1,1849 +0,0 @@ -/* - * LANES.C Copyright (c) 2007-08, Asko Kauppi - * - * Multithreading in Lua. - * - * History: - * 20-Oct-08 (2.0.2): Added closing of free-running threads, but it does - * not seem to eliminate the occasional segfaults at process - * exit. - * ... - * 24-Jun-08 .. 14-Aug-08 AKa: Major revise, Lanes 2008 version (2.0 rc1) - * ... - * 18-Sep-06 AKa: Started the module. - * - * Platforms (tested internally): - * OS X (10.5.4 PowerPC/Intel) - * Linux x86 (Ubuntu 8.04) - * Win32 (Windows XP Home SP2, Visual C++ 2005/2008 Express) - * PocketPC (TBD) - * - * Platforms (tested externally): - * Win32 (MSYS) by Ross Berteig. - * - * Platforms (testers appreciated): - * Win64 - should work??? - * Linux x64 - should work - * FreeBSD - should work - * QNX - porting shouldn't be hard - * Sun Solaris - porting shouldn't be hard - * - * References: - * "Porting multithreaded applications from Win32 to Mac OS X": - * - * - * Pthreads: - * - * - * MSDN: - * - * - * - * Defines: - * -DLINUX_SCHED_RR: all threads are lifted to SCHED_RR category, to - * allow negative priorities (-2,-1) be used. Even without this, - * using priorities will require 'sudo' privileges on Linux. - * - * -DUSE_PTHREAD_TIMEDJOIN: use 'pthread_timedjoin_np()' for waiting - * for threads with a timeout. This changes the thread cleanup - * mechanism slightly (cleans up at the join, not once the thread - * has finished). May or may not be a good idea to use it. - * Available only in selected operating systems (Linux). - * - * Bugs: - * - * To-do: - * - * ... - */ - -const char * VERSION = "2.0.3"; - -/* -=============================================================================== - -Copyright (C) 2007-08 Asko Kauppi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -=============================================================================== -*/ -#include -#include -#include -#include - -#include "lua.h" -#include "lauxlib.h" - -#include "threading.h" -#include "tools.h" - -#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)) -# include -#endif - -/* geteuid() */ -#ifdef PLATFORM_LINUX -# include -# include -#endif - -/* The selected number is not optimal; needs to be tested. Even using just -* one keeper state may be good enough (depends on the number of Lindas used -* in the applications). -*/ -#define KEEPER_STATES_N 1 // 6 - -/* Do you want full call stacks, or just the line where the error happened? -* -* TBD: The full stack feature does not seem to work (try 'make error'). -*/ -#define ERROR_FULL_STACK - -#ifdef ERROR_FULL_STACK -# define STACK_TRACE_KEY ((void*)lane_error) // used as registry key -#endif - -/* -* Lua code for the keeper states (baked in) -*/ -static char keeper_chunk[]= -#include "keeper.lch" - -struct s_lane; -static bool_t cancel_test( lua_State *L ); -static void cancel_error( lua_State *L ); - -#define CANCEL_TEST_KEY ((void*)cancel_test) // used as registry key -#define CANCEL_ERROR ((void*)cancel_error) // 'cancel_error' sentinel - -/* -* registry[FINALIZER_REG_KEY] is either nil (no finalizers) or a table -* of functions that Lanes will call after the executing 'pcall' has ended. -* -* We're NOT using the GC system for finalizer mainly because providing the -* error (and maybe stack trace) parameters to the finalizer functions would -* anyways complicate that approach. -*/ -#define FINALIZER_REG_KEY ((void*)LG_set_finalizer) - -struct s_Linda; - -#if 1 -# define DEBUG_SIGNAL( msg, signal_ref ) /* */ -#else -# define DEBUG_SIGNAL( msg, signal_ref ) \ - { int i; unsigned char *ptr; char buf[999]; \ - sprintf( buf, ">>> " msg ": %p\t", (signal_ref) ); \ - ptr= (unsigned char *)signal_ref; \ - for( i=0; i> 3) % KEEPER_STATES_N; - struct s_Keeper *K= &keeper[i]; - - MUTEX_LOCK( &K->lock_ ); - return K; -} - -static -void keeper_release( struct s_Keeper *K ) { - MUTEX_UNLOCK( &K->lock_ ); -} - -/* -* Call a function ('func_name') in the keeper state, and pass on the returned -* values to 'L'. -* -* 'linda': deep Linda pointer (used only as a unique table key, first parameter) -* 'starting_index': first of the rest of parameters (none if 0) -* -* Returns: number of return values (pushed to 'L') -*/ -static -int keeper_call( lua_State* K, const char *func_name, - lua_State *L, struct s_Linda *linda, uint_t starting_index ) { - - int args= starting_index ? (lua_gettop(L) - starting_index +1) : 0; - int Ktos= lua_gettop(K); - int retvals; - - lua_getglobal( K, func_name ); - ASSERT_L( lua_isfunction(K,-1) ); - - STACK_GROW( K, 1 ); - lua_pushlightuserdata( K, linda ); - - luaG_inter_copy( L,K, args ); // L->K - lua_call( K, 1+args, LUA_MULTRET ); - - retvals= lua_gettop(K) - Ktos; - - luaG_inter_move( K,L, retvals ); // K->L - return retvals; -} - - -/*---=== Linda ===--- -*/ - -/* -* Actual data is kept within a keeper state, which is hashed by the 's_Linda' -* pointer (which is same to all userdatas pointing to it). -*/ -struct s_Linda { - SIGNAL_T read_happened; - SIGNAL_T write_happened; -}; - -static int LG_linda_id( lua_State* ); - -#define lua_toLinda(L,n) ((struct s_Linda *)luaG_todeep( L, LG_linda_id, n )) - - -/* -* bool= linda_send( linda_ud, [timeout_secs=-1,] key_num|str|bool|lightuserdata, ... ) -* -* Send one or more values to a Linda. If there is a limit, all values must fit. -* -* Returns: 'true' if the value was queued -* 'false' for timeout (only happens when the queue size is limited) -*/ -LUAG_FUNC( linda_send ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - bool_t ret; - bool_t cancel= FALSE; - struct s_Keeper *K; - time_d timeout= -1.0; - uint_t key_i= 2; // index of first key, if timeout not there - - if (lua_isnumber(L,2)) { - timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); - key_i++; - } else if (lua_isnil(L,2)) - key_i++; - - if (lua_isnil(L,key_i)) - luaL_error( L, "nil key" ); - - STACK_GROW(L,1); - - K= keeper_acquire( linda ); - { - lua_State *KL= K->L; // need to do this for 'STACK_CHECK' -STACK_CHECK(KL) - while(TRUE) { - int pushed; - -STACK_MID(KL,0) - pushed= keeper_call( K->L, "send", L, linda, key_i ); - ASSERT_L( pushed==1 ); - - ret= lua_toboolean(L,-1); - lua_pop(L,1); - - if (ret) { - // Wake up ALL waiting threads - // - SIGNAL_ALL( &linda->write_happened ); - break; - - } else if (timeout==0.0) { - break; /* no wait; instant timeout */ - - } else { - /* limit faced; push until timeout */ - - cancel= cancel_test( L ); // testing here causes no delays - if (cancel) break; - - // K lock will be released for the duration of wait and re-acquired - // - if (!SIGNAL_WAIT( &linda->read_happened, &K->lock_, timeout )) - break; // timeout - } - } -STACK_END(KL,0) - } - keeper_release(K); - - if (cancel) - cancel_error(L); - - lua_pushboolean( L, ret ); - return 1; -} - - -/* -* [val, key]= linda_receive( linda_ud, [timeout_secs_num=-1], key_num|str|bool|lightuserdata [, ...] ) -* -* Receive a value from Linda, consuming it. -* -* Returns: value received (which is consumed from the slot) -* key which had it -*/ -LUAG_FUNC( linda_receive ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - int pushed; - bool_t cancel= FALSE; - struct s_Keeper *K; - time_d timeout= -1.0; - uint_t key_i= 2; - - if (lua_isnumber(L,2)) { - timeout= SIGNAL_TIMEOUT_PREPARE( lua_tonumber(L,2) ); - key_i++; - } else if (lua_isnil(L,2)) - key_i++; - - K= keeper_acquire( linda ); - { - while(TRUE) { - pushed= keeper_call( K->L, "receive", L, linda, key_i ); - if (pushed) { - ASSERT_L( pushed==2 ); - - // To be done from within the 'K' locking area - // - SIGNAL_ALL( &linda->read_happened ); - break; - - } else if (timeout==0.0) { - break; /* instant timeout */ - - } else { /* nothing received; wait until timeout */ - - cancel= cancel_test( L ); // testing here causes no delays - if (cancel) break; - - // Release the K lock for the duration of wait, and re-acquire - // - if (!SIGNAL_WAIT( &linda->write_happened, &K->lock_, timeout )) - break; - } - } - } - keeper_release(K); - - if (cancel) - cancel_error(L); - - return pushed; -} - - -/* -* = linda_set( linda_ud, key_num|str|bool|lightuserdata [,value] ) -* -* Set a value to Linda. -* -* Existing slot value is replaced, and possible queue entries removed. -*/ -LUAG_FUNC( linda_set ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - bool_t has_value= !lua_isnil(L,3); - - struct s_Keeper *K= keeper_acquire( linda ); - { - int pushed= keeper_call( K->L, "set", L, linda, 2 ); - ASSERT_L( pushed==0 ); - - /* Set the signal from within 'K' locking. - */ - if (has_value) { - SIGNAL_ALL( &linda->write_happened ); - } - } - keeper_release(K); - - return 0; -} - - -/* -* [val]= linda_get( linda_ud, key_num|str|bool|lightuserdata ) -* -* Get a value from Linda. -*/ -LUAG_FUNC( linda_get ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - int pushed; - - struct s_Keeper *K= keeper_acquire( linda ); - { - pushed= keeper_call( K->L, "get", L, linda, 2 ); - ASSERT_L( pushed==0 || pushed==1 ); - } - keeper_release(K); - - return pushed; -} - - -/* -* = linda_limit( linda_ud, key_num|str|bool|lightuserdata, uint [, ...] ) -* -* Set limits to 1 or more Linda keys. -*/ -LUAG_FUNC( linda_limit ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - - struct s_Keeper *K= keeper_acquire( linda ); - { - int pushed= keeper_call( K->L, "limit", L, linda, 2 ); - ASSERT_L( pushed==0 ); - } - keeper_release(K); - - return 0; -} - - -/* -* lightuserdata= linda_deep( linda_ud ) -* -* Return the 'deep' userdata pointer, identifying the Linda. -* -* This is needed for using Lindas as key indices (timer system needs it); -* separately created proxies of the same underlying deep object will have -* different userdata and won't be known to be essentially the same deep one -* without this. -*/ -LUAG_FUNC( linda_deep ) { - struct s_Linda *linda= lua_toLinda( L, 1 ); - lua_pushlightuserdata( L, linda ); // just the address - return 1; -} - - -/* -* Identity function of a shared userdata object. -* -* lightuserdata= linda_id( "new" [, ...] ) -* = linda_id( "delete", lightuserdata ) -* -* Creation and cleanup of actual 'deep' objects. 'luaG_...' will wrap them into -* regular userdata proxies, per each state using the deep data. -* -* tbl= linda_id( "metatable" ) -* -* Returns a metatable for the proxy objects ('__gc' method not needed; will -* be added by 'luaG_...') -* -* = linda_id( str, ... ) -* -* For any other strings, the ID function must not react at all. This allows -* future extensions of the system. -*/ -LUAG_FUNC( linda_id ) { - const char *which= lua_tostring(L,1); - - if (strcmp( which, "new" )==0) { - struct s_Linda *s; - - /* We don't use any parameters, but one could (they're at [2..TOS]) - */ - ASSERT_L( lua_gettop(L)==1 ); - - /* The deep data is allocated separately of Lua stack; we might no - * longer be around when last reference to it is being released. - * One can use any memory allocation scheme. - */ - s= (struct s_Linda *) malloc( sizeof(struct s_Linda) ); - ASSERT_L(s); - - SIGNAL_INIT( &s->read_happened ); - SIGNAL_INIT( &s->write_happened ); - - lua_pushlightuserdata( L, s ); - return 1; - - } else if (strcmp( which, "delete" )==0) { - struct s_Keeper *K; - struct s_Linda *s= lua_touserdata(L,2); - ASSERT_L(s); - - /* Clean associated structures in the keeper state. - */ - K= keeper_acquire(s); - { - keeper_call( K->L, "clear", L, s, 0 ); - } - keeper_release(K); - - /* There aren't any lanes waiting on these lindas, since all proxies - * have been gc'ed. Right? - */ - SIGNAL_FREE( &s->read_happened ); - SIGNAL_FREE( &s->write_happened ); - free(s); - - return 0; - - } else if (strcmp( which, "metatable" )==0) { - - STACK_CHECK(L) - lua_newtable(L); - lua_newtable(L); - // - // [-2]: linda metatable - // [-1]: metatable's to-be .__index table - - lua_pushcfunction( L, LG_linda_send ); - lua_setfield( L, -2, "send" ); - - lua_pushcfunction( L, LG_linda_receive ); - lua_setfield( L, -2, "receive" ); - - lua_pushcfunction( L, LG_linda_limit ); - lua_setfield( L, -2, "limit" ); - - lua_pushcfunction( L, LG_linda_set ); - lua_setfield( L, -2, "set" ); - - lua_pushcfunction( L, LG_linda_get ); - lua_setfield( L, -2, "get" ); - - lua_pushcfunction( L, LG_linda_deep ); - lua_setfield( L, -2, "deep" ); - - lua_setfield( L, -2, "__index" ); - STACK_END(L,1) - - return 1; - } - - return 0; // unknown request, be quiet -} - - -/*---=== Finalizer ===--- -*/ - -//--- -// void= finalizer( finalizer_func ) -// -// finalizer_func( [err, stack_tbl] ) -// -// Add a function that will be called when exiting the lane, either via -// normal return or an error. -// -LUAG_FUNC( set_finalizer ) -{ - STACK_GROW(L,3); - - // Get the current finalizer table (if any) - // - push_registry_table( L, FINALIZER_REG_KEY, TRUE /*do create if none*/ ); - - lua_pushinteger( L, lua_objlen(L,-1)+1 ); - lua_pushvalue( L, 1 ); // copy of the function - lua_settable( L, -3 ); - - lua_pop(L,1); - return 0; -} - - -//--- -// Run finalizers - if any - with the given parameters -// -// If 'rc' is nonzero, error message and stack index are available as: -// [-1]: stack trace (table) -// [-2]: error message (any type) -// -// Returns: -// 0 if finalizers were run without error (or there were none) -// LUA_ERRxxx return code if any of the finalizers failed -// -// TBD: should we add stack trace on failing finalizer, wouldn't be hard.. -// -static int run_finalizers( lua_State *L, int lua_rc ) -{ - unsigned error_index, tbl_index; - unsigned n; - int rc= 0; - - if (!push_registry_table(L, FINALIZER_REG_KEY, FALSE /*don't create one*/)) - return 0; // no finalizers - - tbl_index= lua_gettop(L); - error_index= (lua_rc!=0) ? tbl_index-1 : 0; // absolute indices - - STACK_GROW(L,4); - - // [-1]: { func [, ...] } - // - for( n= lua_objlen(L,-1); n>0; n-- ) { - unsigned args= 0; - lua_pushinteger( L,n ); - lua_gettable( L, -2 ); - - // [-1]: function - // [-2]: finalizers table - - if (error_index) { - lua_pushvalue( L, error_index ); - lua_pushvalue( L, error_index+1 ); // stack trace - args= 2; - } - - rc= lua_pcall( L, args, 0 /*retvals*/, 0 /*no errfunc*/ ); - // - // LUA_ERRRUN / LUA_ERRMEM - - if (rc!=0) { - // [-1]: error message - // - // If one finalizer fails, don't run the others. Return this - // as the 'real' error, preceding that we could have had (or not) - // from the actual code. - // - break; - } - } - - lua_remove(L,tbl_index); // take finalizer table out of stack - - return rc; -} - - -/*---=== Threads ===--- -*/ - -// NOTE: values to be changed by either thread, during execution, without -// locking, are marked "volatile" -// -struct s_lane { - THREAD_T thread; - // - // M: sub-thread OS thread - // S: not used - - lua_State *L; - // - // M: prepares the state, and reads results - // S: while S is running, M must keep out of modifying the state - - volatile enum e_status status; - // - // M: sets to PENDING (before launching) - // S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED - - volatile bool_t cancel_request; - // - // M: sets to FALSE, flags TRUE for cancel request - // S: reads to see if cancel is requested - -#if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) - SIGNAL_T done_signal_; - // - // M: Waited upon at lane ending (if Posix with no PTHREAD_TIMEDJOIN) - // S: sets the signal once cancellation is noticed (avoids a kill) - - MUTEX_T done_lock_; - // - // Lock required by 'done_signal' condition variable, protecting - // lane status changes to DONE/ERROR_ST/CANCELLED. -#endif - - volatile enum { - NORMAL, // normal master side state - KILLED // issued an OS kill - } mstatus; - // - // M: sets to NORMAL, if issued a kill changes to KILLED - // S: not used - - struct s_lane * volatile selfdestruct_next; - // - // M: sets to non-NULL if facing lane handle '__gc' cycle but the lane - // is still running - // S: cleans up after itself if non-NULL at lane exit -}; - -static MUTEX_T selfdestruct_cs; - // - // Protects modifying the selfdestruct chain - -#define SELFDESTRUCT_END ((struct s_lane *)(-1)) - // - // The chain is ended by '(struct s_lane*)(-1)', not NULL: - // 'selfdestruct_first -> ... -> ... -> (-1)' - -struct s_lane * volatile selfdestruct_first= SELFDESTRUCT_END; - -/* -* Add the lane to selfdestruct chain; the ones still running at the end of the -* whole process will be cancelled. -*/ -static void selfdestruct_add( struct s_lane *s ) { - - MUTEX_LOCK( &selfdestruct_cs ); - { - assert( s->selfdestruct_next == NULL ); - - s->selfdestruct_next= selfdestruct_first; - selfdestruct_first= s; - } - MUTEX_UNLOCK( &selfdestruct_cs ); -} - -/* -* A free-running lane has ended; remove it from selfdestruct chain -*/ -static void selfdestruct_remove( struct s_lane *s ) { - - MUTEX_LOCK( &selfdestruct_cs ); - { - // Make sure (within the MUTEX) that we actually are in the chain - // still (at process exit they will remove us from chain and then - // cancel/kill). - // - if (s->selfdestruct_next != NULL) { - struct s_lane **ref= (struct s_lane **) &selfdestruct_first; - bool_t found= FALSE; - - while( *ref != SELFDESTRUCT_END ) { - if (*ref == s) { - *ref= s->selfdestruct_next; - s->selfdestruct_next= NULL; - found= TRUE; - break; - } - ref= (struct s_lane **) &((*ref)->selfdestruct_next); - } - assert( found ); - } - } - MUTEX_UNLOCK( &selfdestruct_cs ); -} - -/* -* Process end; cancel any still free-running threads -*/ -static void selfdestruct_atexit( void ) { - - if (selfdestruct_first == SELFDESTRUCT_END) return; // no free-running threads - - // Signal _all_ still running threads to exit - // - MUTEX_LOCK( &selfdestruct_cs ); - { - struct s_lane *s= selfdestruct_first; - while( s != SELFDESTRUCT_END ) { - s->cancel_request= TRUE; - s= s->selfdestruct_next; - } - } - MUTEX_UNLOCK( &selfdestruct_cs ); - - // When noticing their cancel, the lanes will remove themselves from - // the selfdestruct chain. - - // TBD: Not sure if Windows (multi core) will require the timed approach, - // or single Yield. I don't have machine to test that (so leaving - // for timed approach). -- AKa 25-Oct-2008 - -#ifdef PLATFORM_LINUX - // It seems enough for Linux to have a single yield here, which allows - // other threads (timer lane) to proceed. Without the yield, there is - // segfault. - // - YIELD(); -#else - // OS X 10.5 (Intel) needs more to avoid segfaults. - // - // "make test" is okay. 100's of "make require" are okay. - // - // Tested on MacBook Core Duo 2GHz and 10.5.5: - // -- AKa 25-Oct-2008 - // - #ifndef ATEXIT_WAIT_SECS - # define ATEXIT_WAIT_SECS (0.1) - #endif - { - double t_until= now_secs() + ATEXIT_WAIT_SECS; - - while( selfdestruct_first != SELFDESTRUCT_END ) { - YIELD(); // give threads time to act on their cancel - - if (now_secs() >= t_until) break; - } - } -#endif - - //--- - // Kill the still free running threads - // - if ( selfdestruct_first != SELFDESTRUCT_END ) { - unsigned n=0; - MUTEX_LOCK( &selfdestruct_cs ); - { - struct s_lane *s= selfdestruct_first; - while( s != SELFDESTRUCT_END ) { - n++; - s= s->selfdestruct_next; - } - } - MUTEX_UNLOCK( &selfdestruct_cs ); - - // Linux (at least 64-bit): CAUSES A SEGFAULT IF THIS BLOCK IS ENABLED - // and works without the block (so let's leave those lanes running) - // -#if 1 - // 2.0.2: at least timer lane is still here - // - //fprintf( stderr, "Left %d lane(s) with cancel request at process end.\n", n ); -#else - MUTEX_LOCK( &selfdestruct_cs ); - { - struct s_lane *s= selfdestruct_first; - while( s != SELFDESTRUCT_END ) { - struct s_lane *next_s= s->selfdestruct_next; - s->selfdestruct_next= NULL; // detach from selfdestruct chain - - THREAD_KILL( &s->thread ); - s= next_s; - n++; - } - selfdestruct_first= SELFDESTRUCT_END; - } - MUTEX_UNLOCK( &selfdestruct_cs ); - - fprintf( stderr, "Killed %d lane(s) at process end.\n", n ); -#endif - } -} - - -// To allow free-running threads (longer lifespan than the handle's) -// 'struct s_lane' are malloc/free'd and the handle only carries a pointer. -// This is not deep userdata since the handle's not portable among lanes. -// -#define lua_toLane(L,i) (* ((struct s_lane**) lua_touserdata(L,i))) - - -/* -* Check if the thread in question ('L') has been signalled for cancel. -* -* Called by cancellation hooks and/or pending Linda operations (because then -* the check won't affect performance). -* -* Returns TRUE if any locks are to be exited, and 'cancel_error()' called, -* to make execution of the lane end. -*/ -static bool_t cancel_test( lua_State *L ) { - struct s_lane *s; - - STACK_GROW(L,1); - - STACK_CHECK(L) - lua_pushlightuserdata( L, CANCEL_TEST_KEY ); - lua_rawget( L, LUA_REGISTRYINDEX ); - s= lua_touserdata( L, -1 ); // lightuserdata (true 's_lane' pointer) / nil - lua_pop(L,1); - STACK_END(L,0) - - // 's' is NULL for the original main state (no-one can cancel that) - // - return s && s->cancel_request; -} - -static void cancel_error( lua_State *L ) { - STACK_GROW(L,1); - lua_pushlightuserdata( L, CANCEL_ERROR ); // special error value - lua_error(L); // no return -} - -static void cancel_hook( lua_State *L, lua_Debug *ar ) { - (void)ar; - if (cancel_test(L)) cancel_error(L); -} - - -//--- -// = _single( [cores_uint=1] ) -// -// Limits the process to use only 'cores' CPU cores. To be used for performance -// testing on multicore devices. DEBUGGING ONLY! -// -LUAG_FUNC( _single ) { - uint_t cores= luaG_optunsigned(L,1,1); - -#ifdef PLATFORM_OSX - #ifdef _UTILBINDTHREADTOCPU - if (cores > 1) luaL_error( L, "Limiting to N>1 cores not possible." ); - // requires 'chudInitialize()' - utilBindThreadToCPU(0); // # of CPU to run on (we cannot limit to 2..N CPUs?) - #else - luaL_error( L, "Not available: compile with _UTILBINDTHREADTOCPU" ); - #endif -#else - luaL_error( L, "not implemented!" ); -#endif - (void)cores; - - return 0; -} - - -/* -* str= lane_error( error_val|str ) -* -* Called if there's an error in some lane; add call stack to error message -* just like 'lua.c' normally does. -* -* ".. will be called with the error message and its return value will be the -* message returned on the stack by lua_pcall." -* -* Note: Rather than modifying the error message itself, it would be better -* to provide the call stack (as string) completely separated. This would -* work great with non-string error values as well (current system does not). -* (This is NOT possible with the Lua 5.1 'lua_pcall()'; we could of course -* implement a Lanes-specific 'pcall' of our own that does this). TBD!!! :) -* --AKa 22-Jan-2009 -*/ -#ifdef ERROR_FULL_STACK - -static int lane_error( lua_State *L ) { - lua_Debug ar; - unsigned lev,n; - - // [1]: error message (any type) - - assert( lua_gettop(L)==1 ); - - // Don't do stack survey for cancelled lanes. - // -#if 1 - if (lua_touserdata(L,1) == CANCEL_ERROR) - return 1; // just pass on -#endif - - // Place stack trace at 'registry[lane_error]' for the 'luc_pcall()' - // caller to fetch. This bypasses the Lua 5.1 limitation of only one - // return value from error handler to 'lua_pcall()' caller. - - // It's adequate to push stack trace as a table. This gives the receiver - // of the stack best means to format it to their liking. Also, it allows - // us to add more stack info later, if needed. - // - // table of { "sourcefile.lua:", ... } - // - STACK_GROW(L,3); - lua_newtable(L); - - // Best to start from level 1, but in some cases it might be a C function - // and we don't get '.currentline' for that. It's okay - just keep level - // and table index growing separate. --AKa 22-Jan-2009 - // - lev= 0; - n=1; - while( lua_getstack(L, ++lev, &ar ) ) { - lua_getinfo(L, "Sl", &ar); - if (ar.currentline > 0) { - lua_pushinteger( L, n++ ); - lua_pushfstring( L, "%s:%d", ar.short_src, ar.currentline ); - lua_settable( L, -3 ); - } - } - - lua_pushlightuserdata( L, STACK_TRACE_KEY ); - lua_insert(L,-2); - lua_settable( L, LUA_REGISTRYINDEX ); - - assert( lua_gettop(L)== 1 ); - - return 1; // the untouched error value -} -#endif - - -//--- -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - static THREAD_RETURN_T __stdcall lane_main( void *vs ) -#else - static THREAD_RETURN_T lane_main( void *vs ) -#endif -{ - struct s_lane *s= (struct s_lane *)vs; - int rc, rc2; - lua_State *L= s->L; - - s->status= RUNNING; // PENDING -> RUNNING - - // Tie "set_finalizer()" to the state - // - lua_pushcfunction( L, LG_set_finalizer ); - lua_setglobal( L, "set_finalizer" ); - -#ifdef ERROR_FULL_STACK - STACK_GROW( L, 1 ); - lua_pushcfunction( L, lane_error ); - lua_insert( L, 1 ); - - // [1]: error handler - // [2]: function to run - // [3..top]: parameters - // - rc= lua_pcall( L, lua_gettop(L)-2, LUA_MULTRET, 1 /*error handler*/ ); - // 0: no error - // LUA_ERRRUN: a runtime error (error pushed on stack) - // LUA_ERRMEM: memory allocation error - // LUA_ERRERR: error while running the error handler (if any) - - assert( rc!=LUA_ERRERR ); // since we've authored it - - lua_remove(L,1); // remove error handler - - // Lua 5.1 error handler is limited to one return value; taking stack trace - // via registry - // - if (rc!=0) { - STACK_GROW(L,1); - lua_pushlightuserdata( L, STACK_TRACE_KEY ); - lua_gettable(L, LUA_REGISTRYINDEX); - - // For cancellation, a stack trace isn't placed - // - assert( lua_istable(L,2) || (lua_touserdata(L,1)==CANCEL_ERROR) ); - - // Just leaving the stack trace table on the stack is enough to get - // it through to the master. - } - -#else - // This code does not use 'lane_error' - // - // [1]: function to run - // [2..top]: parameters - // - rc= lua_pcall( L, lua_gettop(L)-1, LUA_MULTRET, 0 /*no error handler*/ ); - // 0: no error - // LUA_ERRRUN: a runtime error (error pushed on stack) - // LUA_ERRMEM: memory allocation error -#endif - -//STACK_DUMP(L); - // Call finalizers, if the script has set them up. - // - rc2= run_finalizers(L,rc); - if (rc2!=0) { - // Error within a finalizer! - // - // [-1]: error message - - rc= rc2; // we're overruling the earlier script error or normal return - - lua_insert( L,1 ); // make error message [1] - lua_settop( L,1 ); // remove all rest - - // Place an empty stack table just to keep the API simple (always when - // there's an error, there's also stack table - though it may be empty). - // - lua_newtable(L); - } - - if (s->selfdestruct_next != NULL) { - // We're a free-running thread and no-one's there to clean us up. - // - lua_close( s->L ); - L= 0; - - #if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) - SIGNAL_FREE( &s->done_signal_ ); - MUTEX_FREE( &s->done_lock_ ); - #endif - selfdestruct_remove(s); // away from selfdestruct chain - free(s); - - } else { - // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them - - enum e_status st= - (rc==0) ? DONE - : (lua_touserdata(L,1)==CANCEL_ERROR) ? CANCELLED - : ERROR_ST; - - // Posix no PTHREAD_TIMEDJOIN: - // 'done_lock' protects the -> DONE|ERROR_ST|CANCELLED state change - // - #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - s->status= st; - #else - MUTEX_LOCK( &s->done_lock_ ); - { - s->status= st; - SIGNAL_ONE( &s->done_signal_ ); // wake up master (while 's->done_lock' is on) - } - MUTEX_UNLOCK( &s->done_lock_ ); - #endif - } - - return 0; // ignored -} - - -//--- -// lane_ud= thread_new( function, [libs_str], -// [cancelstep_uint=0], -// [prio_int=0], -// [globals_tbl], -// [... args ...] ) -// -// Upvalues: metatable to use for 'lane_ud' -// -LUAG_FUNC( thread_new ) -{ - lua_State *L2; - struct s_lane *s; - struct s_lane **ud; - - const char *libs= lua_tostring( L, 2 ); - uint_t cs= luaG_optunsigned( L, 3,0); - int prio= luaL_optinteger( L, 4,0); - uint_t glob= luaG_isany(L,5) ? 5:0; - - #define FIXED_ARGS (5) - uint_t args= lua_gettop(L) - FIXED_ARGS; - - if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) { - luaL_error( L, "Priority out of range: %d..+%d (%d)", - THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio ); - } - - /* --- Create and prepare the sub state --- */ - - L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, - // sets the panic callback - - if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); - - STACK_GROW( L,2 ); - - // Setting the globals table (needs to be done before loading stdlibs, - // and the lane function) - // - if (glob!=0) { -STACK_CHECK(L) - if (!lua_istable(L,glob)) - luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) ); - - lua_pushvalue( L, glob ); - luaG_inter_move( L,L2, 1 ); // moves the table to L2 - - // L2 [-1]: table of globals - - // "You can change the global environment of a Lua thread using lua_replace" - // (refman-5.0.pdf p. 30) - // - lua_replace( L2, LUA_GLOBALSINDEX ); -STACK_END(L,0) - } - - // Selected libraries - // - if (libs) { - const char *err= luaG_openlibs( L2, libs ); - ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' - - serialize_require( L2 ); - } - - // Lane main function - // -STACK_CHECK(L) - lua_pushvalue( L, 1 ); - luaG_inter_move( L,L2, 1 ); // L->L2 -STACK_MID(L,0) - - ASSERT_L( lua_gettop(L2) == 1 ); - ASSERT_L( lua_isfunction(L2,1) ); - - // revive arguments - // - if (args) luaG_inter_copy( L,L2, args ); // L->L2 -STACK_MID(L,0) - -ASSERT_L( (uint_t)lua_gettop(L2) == 1+args ); -ASSERT_L( lua_isfunction(L2,1) ); - - // 's' is allocated from heap, not Lua, since its life span may surpass - // the handle's (if free running thread) - // - ud= lua_newuserdata( L, sizeof(struct s_lane*) ); - ASSERT_L(ud); - - s= *ud= malloc( sizeof(struct s_lane) ); - ASSERT_L(s); - - //memset( s, 0, sizeof(struct s_lane) ); - s->L= L2; - s->status= PENDING; - s->cancel_request= FALSE; - -#if !( (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) ) - MUTEX_INIT( &s->done_lock_ ); - SIGNAL_INIT( &s->done_signal_ ); -#endif - s->mstatus= NORMAL; - s->selfdestruct_next= NULL; - - // Set metatable for the userdata - // - lua_pushvalue( L, lua_upvalueindex(1) ); - lua_setmetatable( L, -2 ); -STACK_MID(L,1) - - // Place 's' to registry, for 'cancel_test()' (even if 'cs'==0 we still - // do cancel tests at pending send/receive). - // - lua_pushlightuserdata( L2, CANCEL_TEST_KEY ); - lua_pushlightuserdata( L2, s ); - lua_rawset( L2, LUA_REGISTRYINDEX ); - - if (cs) { - lua_sethook( L2, cancel_hook, LUA_MASKCOUNT, cs ); - } - - THREAD_CREATE( &s->thread, lane_main, s, prio ); -STACK_END(L,1) - - return 1; -} - - -//--- -// = thread_gc( lane_ud ) -// -// Cleanup for a thread userdata. If the thread is still executing, leave it -// alive as a free-running thread (will clean up itself). -// -// * Why NOT cancel/kill a loose thread: -// -// At least timer system uses a free-running thread, they should be handy -// and the issue of cancelling/killing threads at gc is not very nice, either -// (would easily cause waits at gc cycle, which we don't want). -// -// * Why YES kill a loose thread: -// -// Current way causes segfaults at program exit, if free-running threads are -// in certain stages. Details are not clear, but this is the core reason. -// If gc would kill threads then at process exit only one thread would remain. -// -// Todo: Maybe we should have a clear #define for selecting either behaviour. -// -LUAG_FUNC( thread_gc ) { - struct s_lane *s= lua_toLane(L,1); - - // We can read 's->status' without locks, but not wait for it - // - if (s->status < DONE) { - // - selfdestruct_add(s); - assert( s->selfdestruct_next ); - return 0; - - } else if (s->mstatus==KILLED) { - // Make sure a kill has proceeded, before cleaning up the data structure. - // - // If not doing 'THREAD_WAIT()' we should close the Lua state here - // (can it be out of order, since we killed the lane abruptly?) - // -#if 0 - lua_close( s->L ); -#else -fprintf( stderr, "** Joining with a killed thread (needs testing) **" ); -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - THREAD_WAIT( &s->thread, -1 ); -#else - THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, -1 ); -#endif -fprintf( stderr, "** Joined ok **" ); -#endif - } - - // Clean up after a (finished) thread - // -#if (! ((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN))) - SIGNAL_FREE( &s->done_signal_ ); - MUTEX_FREE( &s->done_lock_ ); - free(s); -#endif - - return 0; -} - - -//--- -// = thread_cancel( lane_ud [,timeout_secs=0.0] [,force_kill_bool=false] ) -// -// The originator thread asking us specifically to cancel the other thread. -// -// 'timeout': <0: wait forever, until the lane is finished -// 0.0: just signal it to cancel, no time waited -// >0: time to wait for the lane to detect cancellation -// -// 'force_kill': if true, and lane does not detect cancellation within timeout, -// it is forcefully killed. Using this with 0.0 timeout means just kill -// (unless the lane is already finished). -// -// Returns: true if the lane was already finished (DONE/ERROR_ST/CANCELLED) or if we -// managed to cancel it. -// false if the cancellation timed out, or a kill was needed. -// -LUAG_FUNC( thread_cancel ) -{ - struct s_lane *s= lua_toLane(L,1); - double secs= 0.0; - uint_t force_i=2; - bool_t force, done= TRUE; - - if (lua_isnumber(L,2)) { - secs= lua_tonumber(L,2); - force_i++; - } else if (lua_isnil(L,2)) - force_i++; - - force= lua_toboolean(L,force_i); // FALSE if nothing there - - // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN) - // - if (s->status < DONE) { - s->cancel_request= TRUE; // it's now signalled to stop - - done= thread_cancel( s, secs, force ); - } - - lua_pushboolean( L, done ); - return 1; -} - -static bool_t thread_cancel( struct s_lane *s, double secs, bool_t force ) -{ - bool_t done= -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - THREAD_WAIT( &s->thread, secs ); -#else - THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, secs ); -#endif - - if ((!done) && force) { - // Killing is asynchronous; we _will_ wait for it to be done at - // GC, to make sure the data structure can be released (alternative - // would be use of "cancellation cleanup handlers" that at least - // PThread seems to have). - // - THREAD_KILL( &s->thread ); - s->mstatus= KILLED; // mark 'gc' to wait for it - } - return done; -} - - -//--- -// str= thread_status( lane_ud ) -// -// Returns: "pending" not started yet -// -> "running" started, doing its work.. -// <-> "waiting" blocked in a receive() -// -> "done" finished, results are there -// / "error" finished at an error, error value is there -// / "cancelled" execution cancelled by M (state gone) -// -LUAG_FUNC( thread_status ) -{ - struct s_lane *s= lua_toLane(L,1); - enum e_status st= s->status; // read just once (volatile) - const char *str; - - if (s->mstatus == KILLED) - st= CANCELLED; - - str= (st==PENDING) ? "pending" : - (st==RUNNING) ? "running" : // like in 'co.status()' - (st==WAITING) ? "waiting" : - (st==DONE) ? "done" : - (st==ERROR_ST) ? "error" : - (st==CANCELLED) ? "cancelled" : NULL; - ASSERT_L(str); - - lua_pushstring( L, str ); - return 1; -} - - -//--- -// [...] | [nil, err_any, stack_tbl]= thread_join( lane_ud [, wait_secs=-1] ) -// -// timeout: returns nil -// done: returns return values (0..N) -// error: returns nil + error value + stack table -// cancelled: returns nil -// -LUAG_FUNC( thread_join ) -{ - struct s_lane *s= lua_toLane(L,1); - double wait_secs= luaL_optnumber(L,2,-1.0); - lua_State *L2= s->L; - int ret; - - bool_t done= -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - THREAD_WAIT( &s->thread, wait_secs ); -#else - THREAD_WAIT( &s->thread, &s->done_signal_, &s->done_lock_, &s->status, wait_secs ); -#endif - if (!done) - return 0; // timeout: pushes none, leaves 'L2' alive - - // Thread is DONE/ERROR_ST/CANCELLED; all ours now - - STACK_GROW( L, 1 ); - - switch( s->status ) { - case DONE: { - uint_t n= lua_gettop(L2); // whole L2 stack - luaG_inter_move( L2,L, n ); - ret= n; - } break; - - case ERROR_ST: - lua_pushnil(L); - luaG_inter_move( L2,L, 2 ); // error message at [-2], stack trace at [-1] - ret= 3; - break; - - case CANCELLED: - ret= 0; - break; - - default: - fprintf( stderr, "Status: %d\n", s->status ); - ASSERT_L( FALSE ); ret= 0; - } - lua_close(L2); - - return ret; -} - - -/*---=== Timer support ===--- -*/ - -/* -* Push a timer gateway Linda object; only one deep userdata is -* created for this, each lane will get its own proxy. -* -* Note: this needs to be done on the C side; Lua wouldn't be able -* to even see, when we've been initialized for the very first -* time (with us, they will be). -*/ -static -void push_timer_gateway( lua_State *L ) { - - /* No need to lock; 'static' is just fine - */ - static DEEP_PRELUDE *p; // = NULL - - STACK_CHECK(L) - if (!p) { - // Create the Linda (only on first time) - // - // proxy_ud= deep_userdata( idfunc ) - // - lua_pushcfunction( L, luaG_deep_userdata ); - lua_pushcfunction( L, LG_linda_id ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - - ASSERT_L( lua_isuserdata(L,-1) ); - - // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer - // - p= * (DEEP_PRELUDE**) lua_touserdata( L, -1 ); - ASSERT_L(p && p->refcount==1 && p->deep); - - // [-1]: proxy for accessing the Linda - - } else { - /* Push a proxy based on the deep userdata we stored. - */ - luaG_push_proxy( L, LG_linda_id, p ); - } - STACK_END(L,1) -} - -/* -* secs= now_secs() -* -* Returns the current time, as seconds (millisecond resolution). -*/ -LUAG_FUNC( now_secs ) -{ - lua_pushnumber( L, now_secs() ); - return 1; -} - -/* -* wakeup_at_secs= wakeup_conv( date_tbl ) -*/ -LUAG_FUNC( wakeup_conv ) -{ - int year, month, day, hour, min, sec, isdst; - struct tm tm= {0}; - // - // .year (four digits) - // .month (1..12) - // .day (1..31) - // .hour (0..23) - // .min (0..59) - // .sec (0..61) - // .yday (day of the year) - // .isdst (daylight saving on/off) - - STACK_CHECK(L) - lua_getfield( L, 1, "year" ); year= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "month" ); month= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "day" ); day= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "hour" ); hour= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "min" ); min= lua_tointeger(L,-1); lua_pop(L,1); - lua_getfield( L, 1, "sec" ); sec= lua_tointeger(L,-1); lua_pop(L,1); - - // If Lua table has '.isdst' we trust that. If it does not, we'll let - // 'mktime' decide on whether the time is within DST or not (value -1). - // - lua_getfield( L, 1, "isdst" ); - isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; - lua_pop(L,1); - STACK_END(L,0) - - tm.tm_year= year-1900; - tm.tm_mon= month-1; // 0..11 - tm.tm_mday= day; // 1..31 - tm.tm_hour= hour; // 0..23 - tm.tm_min= min; // 0..59 - tm.tm_sec= sec; // 0..60 - tm.tm_isdst= isdst; // 0/1/negative - - lua_pushnumber( L, (double) mktime( &tm ) ); // ms=0 - return 1; -} - - -/*---=== Module linkage ===--- -*/ - -#define REG_FUNC( name ) \ - lua_pushcfunction( L, LG_##name ); \ - lua_setglobal( L, #name ) - -#define REG_FUNC2( name, val ) \ - lua_pushcfunction( L, val ); \ - lua_setglobal( L, #name ) - -#define REG_STR2( name, val ) \ - lua_pushstring( L, val ); \ - lua_setglobal( L, #name ) - -#define REG_INT2( name, val ) \ - lua_pushinteger( L, val ); \ - lua_setglobal( L, #name ) - - -int -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) -__declspec(dllexport) -#endif - luaopen_lanes( lua_State *L ) { - const char *err; - static volatile char been_here; // =0 - - // One time initializations: - // - if (!been_here) { - been_here= TRUE; - -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - now_secs(); // initialize 'now_secs()' internal offset -#endif - -#if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) - chudInitialize(); -#endif - - // Locks for 'tools.c' inc/dec counters - // - MUTEX_INIT( &deep_lock ); - MUTEX_INIT( &mtid_lock ); - - // Serialize calls to 'require' from now on, also in the primary state - // - MUTEX_RECURSIVE_INIT( &require_cs ); - - serialize_require( L ); - - // Selfdestruct chain handling - // - MUTEX_INIT( &selfdestruct_cs ); - atexit( selfdestruct_atexit ); - - //--- - // Linux needs SCHED_RR to change thread priorities, and that is only - // allowed for sudo'ers. SCHED_OTHER (default) has no priorities. - // SCHED_OTHER threads are always lower priority than SCHED_RR. - // - // ^-- those apply to 2.6 kernel. IF **wishful thinking** these - // constraints will change in the future, non-sudo priorities can - // be enabled also for Linux. - // -#ifdef PLATFORM_LINUX - sudo= geteuid()==0; // we are root? - - // If lower priorities (-2..-1) are wanted, we need to lift the main - // thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below - // the launched threads (even -2). - // - #ifdef LINUX_SCHED_RR - if (sudo) { - struct sched_param sp= {0}; sp.sched_priority= _PRIO_0; - PT_CALL( pthread_setschedparam( pthread_self(), SCHED_RR, &sp) ); - } - #endif -#endif - err= init_keepers(); - if (err) - luaL_error( L, "Unable to initialize: %s", err ); - } - - // Linda identity function - // - REG_FUNC( linda_id ); - - // metatable for threads - // - lua_newtable( L ); - lua_pushcfunction( L, LG_thread_gc ); - lua_setfield( L, -2, "__gc" ); - - lua_pushcclosure( L, LG_thread_new, 1 ); // metatable as closure param - lua_setglobal( L, "thread_new" ); - - REG_FUNC( thread_status ); - REG_FUNC( thread_join ); - REG_FUNC( thread_cancel ); - - REG_STR2( _version, VERSION ); - REG_FUNC( _single ); - - REG_FUNC2( _deep_userdata, luaG_deep_userdata ); - - REG_FUNC( now_secs ); - REG_FUNC( wakeup_conv ); - - push_timer_gateway(L); - lua_setglobal( L, "timer_gateway" ); - - REG_INT2( max_prio, THREAD_PRIO_MAX ); - - lua_pushlightuserdata( L, CANCEL_ERROR ); - lua_setglobal( L, "cancel_error" ); - - return 0; -} - - diff --git a/src/libraries/lanes/lanes/lanes.lua b/src/libraries/lanes/lanes/lanes.lua deleted file mode 100644 index c68506db2..000000000 --- a/src/libraries/lanes/lanes/lanes.lua +++ /dev/null @@ -1,611 +0,0 @@ --- --- LANES.LUA --- --- Multithreading and -core support for Lua --- --- Author: Asko Kauppi --- --- History: --- Jun-08 AKa: major revise --- 15-May-07 AKa: pthread_join():less version, some speedup & ability to --- handle more threads (~ 8000-9000, up from ~ 5000) --- 26-Feb-07 AKa: serialization working (C side) --- 17-Sep-06 AKa: started the module (serialization) --- ---[[ -=============================================================================== - -Copyright (C) 2007-08 Asko Kauppi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -=============================================================================== -]]-- - -module( "lanes", package.seeall ) - -require "lua51-lanes" -assert( type(lanes)=="table" ) - -local mm= lanes - -local linda_id= assert( mm.linda_id ) - -local thread_new= assert(mm.thread_new) -local thread_status= assert(mm.thread_status) -local thread_join= assert(mm.thread_join) -local thread_cancel= assert(mm.thread_cancel) - -local _single= assert(mm._single) -local _version= assert(mm._version) - -local _deep_userdata= assert(mm._deep_userdata) - -local now_secs= assert( mm.now_secs ) -local wakeup_conv= assert( mm.wakeup_conv ) -local timer_gateway= assert( mm.timer_gateway ) - -local max_prio= assert( mm.max_prio ) - --- This check is for sublanes requiring Lanes --- --- TBD: We could also have the C level expose 'string.gmatch' for us. But this is simpler. --- -if not string then - error( "To use 'lanes', you will also need to have 'string' available.", 2 ) -end - --- --- Cache globals for code that might run under sandboxing --- -local assert= assert -local string_gmatch= assert( string.gmatch ) -local select= assert( select ) -local type= assert( type ) -local pairs= assert( pairs ) -local tostring= assert( tostring ) -local error= assert( error ) -local setmetatable= assert( setmetatable ) -local rawget= assert( rawget ) - -ABOUT= -{ - author= "Asko Kauppi ", - description= "Running multiple Lua states in parallel", - license= "MIT/X11", - copyright= "Copyright (c) 2007-08, Asko Kauppi", - version= _version, -} - - --- Making copies of necessary system libs will pass them on as upvalues; --- only the first state doing "require 'lanes'" will need to have 'string' --- and 'table' visible. --- -local function WR(str) - io.stderr:write( str.."\n" ) -end - -local function DUMP( tbl ) - if not tbl then return end - local str="" - for k,v in pairs(tbl) do - str= str..k.."="..tostring(v).."\n" - end - WR(str) -end - - ----=== Laning ===--- - --- lane_h[1..n]: lane results, same as via 'lane_h:join()' --- lane_h[0]: can be read to make sure a thread has finished (always gives 'true') --- lane_h[-1]: error message, without propagating the error --- --- Reading a Lane result (or [0]) propagates a possible error in the lane --- (and execution does not return). Cancelled lanes give 'nil' values. --- --- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled" --- -local lane_mt= { - __index= function( me, k ) - if type(k) == "number" then - -- 'me[0]=true' marks we've already taken in the results - -- - if not rawget( me, 0 ) then - -- Wait indefinately; either propagates an error or - -- returns the return values - -- - me[0]= true -- marker, even on errors - - local t= { thread_join(me._ud) } -- wait indefinate - -- - -- { ... } "done": regular return, 0..N results - -- { } "cancelled" - -- { nil, err_str, stack_tbl } "error" - - local st= thread_status(me._ud) - if st=="done" then - -- Use 'pairs' and not 'ipairs' so that nil holes in - -- the returned values are tolerated. - -- - for i,v in pairs(t) do - me[i]= v - end - elseif st=="error" then - assert( t[1]==nil and t[2] and type(t[3])=="table" ) - me[-1]= t[2] - -- me[-2] could carry the stack table, but even - -- me[-1] is rather unnecessary (and undocumented); - -- use ':join()' instead. --AKa 22-Jan-2009 - elseif st=="cancelled" then - -- do nothing - else - error( "Unexpected status: "..st ) - end - end - - -- Check errors even if we'd first peeked them via [-1] - -- and then came for the actual results. - -- - local err= rawget(me, -1) - if err~=nil and k~=-1 then - -- Note: Lua 5.1 interpreter is not prepared to show - -- non-string errors, so we use 'tostring()' here - -- to get meaningful output. --AKa 22-Jan-2009 - -- - -- Also, the stack dump we get is no good; it only - -- lists our internal Lanes functions. There seems - -- to be no way to switch it off, though. - - -- Level 3 should show the line where 'h[x]' was read - -- but this only seems to work for string messages - -- (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009 - -- - error( tostring(err), 3 ) -- level 3 should show the line where 'h[x]' was read - end - return rawget( me, k ) - -- - elseif k=="status" then -- me.status - return thread_status(me._ud) - -- - else - error( "Unknown key: "..k ) - end - end - } - ------ --- h= lanes.gen( [libs_str|opt_tbl [, ...],] lane_func ) ( [...] ) --- --- 'libs': nil: no libraries available (default) --- "": only base library ('assert', 'print', 'unpack' etc.) --- "math,os": math + os + base libraries (named ones + base) --- "*": all standard libraries available --- --- 'opt': .priority: int (-2..+2) smaller is lower priority (0 = default) --- --- .cancelstep: bool | uint --- false: cancellation check only at pending Linda operations --- (send/receive) so no runtime performance penalty (default) --- true: adequate cancellation check (same as 100) --- >0: cancellation check every x Lua lines (small number= faster --- reaction but more performance overhead) --- --- .globals: table of globals to set for a new thread (passed by value) --- --- ... (more options may be introduced later) ... --- --- Calling with a function parameter ('lane_func') ends the string/table --- modifiers, and prepares a lane generator. One can either finish here, --- and call the generator later (maybe multiple times, with different parameters) --- or add on actual thread arguments to also ignite the thread on the same call. --- -local lane_proxy - -local valid_libs= { - ["package"]= true, - ["table"]= true, - ["io"]= true, - ["os"]= true, - ["string"]= true, - ["math"]= true, - ["debug"]= true, - -- - ["base"]= true, - ["coroutine"]= true, - ["*"]= true -} - -function gen( ... ) - local opt= {} - local libs= nil - local lev= 2 -- level for errors - - local n= select('#',...) - - if n==0 then - error( "No parameters!" ) - end - - for i=1,n-1 do - local v= select(i,...) - if type(v)=="string" then - libs= libs and libs..","..v or v - elseif type(v)=="table" then - for k,vv in pairs(v) do - opt[k]= vv - end - elseif v==nil then - -- skip - else - error( "Bad parameter: "..tostring(v) ) - end - end - - local func= select(n,...) - if type(func)~="function" then - error( "Last parameter not function: "..tostring(func) ) - end - - -- Check 'libs' already here, so the error goes in the right place - -- (otherwise will be noticed only once the generator is called) - -- - if libs then - for s in string_gmatch(libs, "[%a*]+") do - if not valid_libs[s] then - error( "Bad library name: "..s ) - end - end - end - - local prio, cs, g_tbl - - for k,v in pairs(opt) do - if k=="priority" then prio= v - elseif k=="cancelstep" then cs= (v==true) and 100 or - (v==false) and 0 or - type(v)=="number" and v or - error( "Bad cancelstep: "..tostring(v), lev ) - elseif k=="globals" then g_tbl= v - --.. - elseif k==1 then error( "unkeyed option: ".. tostring(v), lev ) - else error( "Bad option: ".. tostring(k), lev ) - end - end - - -- Lane generator - -- - return function(...) - return lane_proxy( thread_new( func, libs, cs, prio, g_tbl, - ... ) ) -- args - end -end - -lane_proxy= function( ud ) - local proxy= { - _ud= ud, - - -- void= me:cancel() - -- - cancel= function(me) thread_cancel(me._ud) end, - - -- [...] | [nil,err,stack_tbl]= me:join( [wait_secs=-1] ) - -- - join= function( me, wait ) - return thread_join( me._ud, wait ) - end, - } - assert( proxy._ud ) - setmetatable( proxy, lane_mt ) - - return proxy -end - - ----=== Lindas ===--- - --- We let the C code attach methods to userdata directly - ------ --- linda_ud= lanes.linda() --- -function linda() - local proxy= _deep_userdata( linda_id ) - assert( (type(proxy) == "userdata") and getmetatable(proxy) ) - return proxy -end - - ----=== Timers ===--- - --- --- On first 'require "lanes"', a timer lane is spawned that will maintain --- timer tables and sleep in between the timer events. All interaction with --- the timer lane happens via a 'timer_gateway' Linda, which is common to --- all that 'require "lanes"'. --- --- Linda protocol to timer lane: --- --- TGW_KEY: linda_h, key, [wakeup_at_secs], [repeat_secs] --- -local TGW_KEY= "(timer control)" -- the key does not matter, a 'weird' key may help debugging -local first_time_key= "first time" - -local first_time= timer_gateway:get(first_time_key) == nil -timer_gateway:set(first_time_key,true) - --- --- Timer lane; initialize only on the first 'require "lanes"' instance (which naturally --- has 'table' always declared) --- -if first_time then - local table_remove= assert( table.remove ) - local table_insert= assert( table.insert ) - - -- - -- { [deep_linda_lightuserdata]= { [deep_linda_lightuserdata]=linda_h, - -- [key]= { wakeup_secs [,period_secs] } [, ...] }, - -- } - -- - -- Collection of all running timers, indexed with linda's & key. - -- - -- Note that we need to use the deep lightuserdata identifiers, instead - -- of 'linda_h' themselves as table indices. Otherwise, we'd get multiple - -- entries for the same timer. - -- - -- The 'hidden' reference to Linda proxy is used in 'check_timers()' but - -- also important to keep the Linda alive, even if all outside world threw - -- away pointers to it (which would ruin uniqueness of the deep pointer). - -- Now we're safe. - -- - local collection= {} - - -- - -- set_timer( linda_h, key [,wakeup_at_secs [,period_secs]] ) - -- - local function set_timer( linda, key, wakeup_at, period ) - - assert( wakeup_at==nil or wakeup_at>0.0 ) - assert( period==nil or period>0.0 ) - - local linda_deep= linda:deep() - assert( linda_deep ) - - -- Find or make a lookup for this timer - -- - local t1= collection[linda_deep] - if not t1 then - t1= { [linda_deep]= linda } -- proxy to use the Linda - collection[linda_deep]= t1 - end - - if wakeup_at==nil then - -- Clear the timer - -- - t1[key]= nil - - -- Remove empty tables from collection; speeds timer checks and - -- lets our 'safety reference' proxy be gc:ed as well. - -- - local empty= true - for k,_ in pairs(t1) do - if k~= linda_deep then - empty= false; break - end - end - if empty then - collection[linda_deep]= nil - end - - -- Note: any unread timer value is left at 'linda[key]' intensionally; - -- clearing a timer just stops it. - else - -- New timer or changing the timings - -- - local t2= t1[key] - if not t2 then - t2= {}; t1[key]= t2 - end - - t2[1]= wakeup_at - t2[2]= period -- can be 'nil' - end - end - - ----- - -- [next_wakeup_at]= check_timers() - -- - -- Check timers, and wake up the ones expired (if any) - -- - -- Returns the closest upcoming (remaining) wakeup time (or 'nil' if none). - -- - local function check_timers() - - local now= now_secs() - local next_wakeup - - for linda_deep,t1 in pairs(collection) do - for key,t2 in pairs(t1) do - -- - if key==linda_deep then - -- no 'continue' in Lua :/ - else - -- 't2': { wakeup_at_secs [,period_secs] } - -- - local wakeup_at= t2[1] - local period= t2[2] -- may be 'nil' - - if wakeup_at <= now then - local linda= t1[linda_deep] - assert(linda) - - linda:set( key, now ) - - -- 'pairs()' allows the values to be modified (and even - -- removed) as far as keys are not touched - - if not period then - -- one-time timer; gone - -- - t1[key]= nil - wakeup_at= nil -- no 'continue' in Lua :/ - else - -- repeating timer; find next wakeup (may jump multiple repeats) - -- - repeat - wakeup_at= wakeup_at+period - until wakeup_at > now - - t2[1]= wakeup_at - end - end - - if wakeup_at and ((not next_wakeup) or (wakeup_at < next_wakeup)) then - next_wakeup= wakeup_at - end - end - end -- t2 loop - end -- t1 loop - - return next_wakeup -- may be 'nil' - end - - ----- - -- Snore loop (run as a lane on the background) - -- - -- High priority, to get trustworthy timings. - -- - -- We let the timer lane be a "free running" thread; no handle to it - -- remains. - -- - gen( "io", { priority=max_prio }, function() - - while true do - local next_wakeup= check_timers() - - -- Sleep until next timer to wake up, or a set/clear command - -- - local secs= next_wakeup and (next_wakeup - now_secs()) or nil - local linda= timer_gateway:receive( secs, TGW_KEY ) - - if linda then - local key= timer_gateway:receive( 0.0, TGW_KEY ) - local wakeup_at= timer_gateway:receive( 0.0, TGW_KEY ) - local period= timer_gateway:receive( 0.0, TGW_KEY ) - assert( key and wakeup_at and period ) - - set_timer( linda, key, wakeup_at, period>0 and period or nil ) - end - end - end )() -end - ------ --- = timer( linda_h, key_val, date_tbl|first_secs [,period_secs] ) --- -function timer( linda, key, a, period ) - - if a==0.0 then - -- Caller expects to get current time stamp in Linda, on return - -- (like the timer had expired instantly); it would be good to set this - -- as late as possible (to give most current time) but also we want it - -- to precede any possible timers that might start striking. - -- - linda:set( key, now_secs() ) - - if not period or period==0.0 then - timer_gateway:send( TGW_KEY, linda, key, nil, nil ) -- clear the timer - return -- nothing more to do - end - a= period - end - - local wakeup_at= type(a)=="table" and wakeup_conv(a) -- given point of time - or now_secs()+a - -- queue to timer - -- - timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period ) -end - - ----=== Lock & atomic generators ===--- - --- These functions are just surface sugar, but make solutions easier to read. --- Not many applications should even need explicit locks or atomic counters. - --- --- lock_f= lanes.genlock( linda_h, key [,N_uint=1] ) --- --- = lock_f( +M ) -- acquire M --- ...locked... --- = lock_f( -M ) -- release M --- --- Returns an access function that allows 'N' simultaneous entries between --- acquire (+M) and release (-M). For binary locks, use M==1. --- -function genlock( linda, key, N ) - linda:limit(key,N) - linda:set(key,nil) -- clears existing data - - -- - -- [true [, ...]= trues(uint) - -- - local function trues(n) - if n>0 then return true,trues(n-1) end - end - - return - function(M) - if M>0 then - -- 'nil' timeout allows 'key' to be numeric - linda:send( nil, key, trues(M) ) -- suspends until been able to push them - else - for i=1,-M do - linda:receive( key ) - end - end - end -end - - --- --- atomic_f= lanes.genatomic( linda_h, key [,initial_num=0.0] ) --- --- int= atomic_f( [diff_num=1.0] ) --- --- Returns an access function that allows atomic increment/decrement of the --- number in 'key'. --- -function genatomic( linda, key, initial_val ) - linda:limit(key,2) -- value [,true] - linda:set(key,initial_val or 0.0) -- clears existing data (also queue) - - return - function(diff) - -- 'nil' allows 'key' to be numeric - linda:send( nil, key, true ) -- suspends until our 'true' is in - local val= linda:get(key) + (diff or 1.0) - linda:set( key, val ) -- releases the lock, by emptying queue - return val - end -end - - ---the end diff --git a/src/libraries/lanes/lanes/lanes.lua.h b/src/libraries/lanes/lanes/lanes.lua.h deleted file mode 100644 index 1cd878620..000000000 --- a/src/libraries/lanes/lanes/lanes.lua.h +++ /dev/null @@ -1,1021 +0,0 @@ -/* code automatically generated by bin2c -- DO NOT EDIT */ -{ -/* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"lanes.lua")==0) lua_call(L, 0, 0); -*/ -/* lanes.lua */ -static const unsigned char B1[]={ - 45, 45, 10, 45, 45, 32, 76, 65, 78, 69, 83, 46, 76, 85, 65, 10, 45, 45, 10, 45, - 45, 32, 77,117,108,116,105,116,104,114,101, 97,100,105,110,103, 32, 97,110,100, - 32, 45, 99,111,114,101, 32,115,117,112,112,111,114,116, 32,102,111,114, 32, 76, -117, 97, 10, 45, 45, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 65,115,107, -111, 32, 75, 97,117,112,112,105, 32, 60, 97,107, 97,117,112,112,105, 64,103,109, - 97,105,108, 46, 99,111,109, 62, 10, 45, 45, 10, 45, 45, 32, 72,105,115,116,111, -114,121, 58, 10, 45, 45, 32, 32, 32, 32, 74,117,110, 45, 48, 56, 32, 65, 75, 97, - 58, 32,109, 97,106,111,114, 32,114,101,118,105,115,101, 10, 45, 45, 32, 32, 32, - 32, 49, 53, 45, 77, 97,121, 45, 48, 55, 32, 65, 75, 97, 58, 32,112,116,104,114, -101, 97,100, 95,106,111,105,110, 40, 41, 58,108,101,115,115, 32,118,101,114,115, -105,111,110, 44, 32,115,111,109,101, 32,115,112,101,101,100,117,112, 32, 38, 32, - 97, 98,105,108,105,116,121, 32,116,111, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104, 97,110,100,108,101, 32,109, -111,114,101, 32,116,104,114,101, 97,100,115, 32, 40,126, 32, 56, 48, 48, 48, 45, - 57, 48, 48, 48, 44, 32,117,112, 32,102,114,111,109, 32,126, 32, 53, 48, 48, 48, - 41, 10, 45, 45, 32, 32, 32, 32, 50, 54, 45, 70,101, 98, 45, 48, 55, 32, 65, 75, - 97, 58, 32,115,101,114,105, 97,108,105,122, 97,116,105,111,110, 32,119,111,114, -107,105,110,103, 32, 40, 67, 32,115,105,100,101, 41, 10, 45, 45, 32, 32, 32, 32, - 49, 55, 45, 83,101,112, 45, 48, 54, 32, 65, 75, 97, 58, 32,115,116, 97,114,116, -101,100, 32,116,104,101, 32,109,111,100,117,108,101, 32, 40,115,101,114,105, 97, -108,105,122, 97,116,105,111,110, 41, 10, 45, 45, 10, 45, 45, 91, 91, 10, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 10, 10, 67, -111,112,121,114,105,103,104,116, 32, 40, 67, 41, 32, 50, 48, 48, 55, 45, 48, 56, - 32, 65,115,107,111, 32, 75, 97,117,112,112,105, 32, 60, 97,107, 97,117,112,112, -105, 64,103,109, 97,105,108, 46, 99,111,109, 62, 10, 10, 80,101,114,109,105,115, -115,105,111,110, 32,105,115, 32,104,101,114,101, 98,121, 32,103,114, 97,110,116, -101,100, 44, 32,102,114,101,101, 32,111,102, 32, 99,104, 97,114,103,101, 44, 32, -116,111, 32, 97,110,121, 32,112,101,114,115,111,110, 32,111, 98,116, 97,105,110, -105,110,103, 32, 97, 32, 99,111,112,121, 10,111,102, 32,116,104,105,115, 32,115, -111,102,116,119, 97,114,101, 32, 97,110,100, 32, 97,115,115,111, 99,105, 97,116, -101,100, 32,100,111, 99,117,109,101,110,116, 97,116,105,111,110, 32,102,105,108, -101,115, 32, 40,116,104,101, 32, 34, 83,111,102,116,119, 97,114,101, 34, 41, 44, - 32,116,111, 32,100,101, 97,108, 10,105,110, 32,116,104,101, 32, 83,111,102,116, -119, 97,114,101, 32,119,105,116,104,111,117,116, 32,114,101,115,116,114,105, 99, -116,105,111,110, 44, 32,105,110, 99,108,117,100,105,110,103, 32,119,105,116,104, -111,117,116, 32,108,105,109,105,116, 97,116,105,111,110, 32,116,104,101, 32,114, -105,103,104,116,115, 10,116,111, 32,117,115,101, 44, 32, 99,111,112,121, 44, 32, -109,111,100,105,102,121, 44, 32,109,101,114,103,101, 44, 32,112,117, 98,108,105, -115,104, 44, 32,100,105,115,116,114,105, 98,117,116,101, 44, 32,115,117, 98,108, -105, 99,101,110,115,101, 44, 32, 97,110,100, 47,111,114, 32,115,101,108,108, 10, - 99,111,112,105,101,115, 32,111,102, 32,116,104,101, 32, 83,111,102,116,119, 97, -114,101, 44, 32, 97,110,100, 32,116,111, 32,112,101,114,109,105,116, 32,112,101, -114,115,111,110,115, 32,116,111, 32,119,104,111,109, 32,116,104,101, 32, 83,111, -102,116,119, 97,114,101, 32,105,115, 10,102,117,114,110,105,115,104,101,100, 32, -116,111, 32,100,111, 32,115,111, 44, 32,115,117, 98,106,101, 99,116, 32,116,111, - 32,116,104,101, 32,102,111,108,108,111,119,105,110,103, 32, 99,111,110,100,105, -116,105,111,110,115, 58, 10, 10, 84,104,101, 32, 97, 98,111,118,101, 32, 99,111, -112,121,114,105,103,104,116, 32,110,111,116,105, 99,101, 32, 97,110,100, 32,116, -104,105,115, 32,112,101,114,109,105,115,115,105,111,110, 32,110,111,116,105, 99, -101, 32,115,104, 97,108,108, 32, 98,101, 32,105,110, 99,108,117,100,101,100, 32, -105,110, 10, 97,108,108, 32, 99,111,112,105,101,115, 32,111,114, 32,115,117, 98, -115,116, 97,110,116,105, 97,108, 32,112,111,114,116,105,111,110,115, 32,111,102, - 32,116,104,101, 32, 83,111,102,116,119, 97,114,101, 46, 10, 10, 84, 72, 69, 32, - 83, 79, 70, 84, 87, 65, 82, 69, 32, 73, 83, 32, 80, 82, 79, 86, 73, 68, 69, 68, - 32, 34, 65, 83, 32, 73, 83, 34, 44, 32, 87, 73, 84, 72, 79, 85, 84, 32, 87, 65, - 82, 82, 65, 78, 84, 89, 32, 79, 70, 32, 65, 78, 89, 32, 75, 73, 78, 68, 44, 32, - 69, 88, 80, 82, 69, 83, 83, 32, 79, 82, 10, 73, 77, 80, 76, 73, 69, 68, 44, 32, - 73, 78, 67, 76, 85, 68, 73, 78, 71, 32, 66, 85, 84, 32, 78, 79, 84, 32, 76, 73, - 77, 73, 84, 69, 68, 32, 84, 79, 32, 84, 72, 69, 32, 87, 65, 82, 82, 65, 78, 84, - 73, 69, 83, 32, 79, 70, 32, 77, 69, 82, 67, 72, 65, 78, 84, 65, 66, 73, 76, 73, - 84, 89, 44, 10, 70, 73, 84, 78, 69, 83, 83, 32, 70, 79, 82, 32, 65, 32, 80, 65, - 82, 84, 73, 67, 85, 76, 65, 82, 32, 80, 85, 82, 80, 79, 83, 69, 32, 65, 78, 68, - 32, 78, 79, 78, 73, 78, 70, 82, 73, 78, 71, 69, 77, 69, 78, 84, 46, 32, 32, 73, - 78, 32, 78, 79, 32, 69, 86, 69, 78, 84, 32, 83, 72, 65, 76, 76, 32, 84, 72, 69, - 10, 65, 85, 84, 72, 79, 82, 83, 32, 79, 82, 32, 67, 79, 80, 89, 82, 73, 71, 72, - 84, 32, 72, 79, 76, 68, 69, 82, 83, 32, 66, 69, 32, 76, 73, 65, 66, 76, 69, 32, - 70, 79, 82, 32, 65, 78, 89, 32, 67, 76, 65, 73, 77, 44, 32, 68, 65, 77, 65, 71, - 69, 83, 32, 79, 82, 32, 79, 84, 72, 69, 82, 10, 76, 73, 65, 66, 73, 76, 73, 84, - 89, 44, 32, 87, 72, 69, 84, 72, 69, 82, 32, 73, 78, 32, 65, 78, 32, 65, 67, 84, - 73, 79, 78, 32, 79, 70, 32, 67, 79, 78, 84, 82, 65, 67, 84, 44, 32, 84, 79, 82, - 84, 32, 79, 82, 32, 79, 84, 72, 69, 82, 87, 73, 83, 69, 44, 32, 65, 82, 73, 83, - 73, 78, 71, 32, 70, 82, 79, 77, 44, 10, 79, 85, 84, 32, 79, 70, 32, 79, 82, 32, - 73, 78, 32, 67, 79, 78, 78, 69, 67, 84, 73, 79, 78, 32, 87, 73, 84, 72, 32, 84, - 72, 69, 32, 83, 79, 70, 84, 87, 65, 82, 69, 32, 79, 82, 32, 84, 72, 69, 32, 85, - 83, 69, 32, 79, 82, 32, 79, 84, 72, 69, 82, 32, 68, 69, 65, 76, 73, 78, 71, 83, - 32, 73, 78, 10, 84, 72, 69, 32, 83, 79, 70, 84, 87, 65, 82, 69, 46, 10, 10, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 10, 93, - 93, 45, 45, 10, 10,109,111,100,117,108,101, 40, 32, 34,108, 97,110,101,115, 34, - 44, 32,112, 97, 99,107, 97,103,101, 46,115,101,101, 97,108,108, 32, 41, 10, 10, -114,101,113,117,105,114,101, 32, 34,108,117, 97, 53, 49, 45,108, 97,110,101,115, - 34, 10, 97,115,115,101,114,116, 40, 32,116,121,112,101, 40,108, 97,110,101,115, - 41, 61, 61, 34,116, 97, 98,108,101, 34, 32, 41, 10, 10,108,111, 99, 97,108, 32, -109,109, 61, 32,108, 97,110,101,115, 10, 10,108,111, 99, 97,108, 32,108,105,110, -100, 97, 95,105,100, 61, 32, 32, 32, 32, 97,115,115,101,114,116, 40, 32,109,109, - 46,108,105,110,100, 97, 95,105,100, 32, 41, 10, 10,108,111, 99, 97,108, 32,116, -104,114,101, 97,100, 95,110,101,119, 61, 32, 32, 32, 97,115,115,101,114,116, 40, -109,109, 46,116,104,114,101, 97,100, 95,110,101,119, 41, 10,108,111, 99, 97,108, - 32,116,104,114,101, 97,100, 95,115,116, 97,116,117,115, 61, 32, 97,115,115,101, -114,116, 40,109,109, 46,116,104,114,101, 97,100, 95,115,116, 97,116,117,115, 41, - 10,108,111, 99, 97,108, 32,116,104,114,101, 97,100, 95,106,111,105,110, 61, 32, - 32, 97,115,115,101,114,116, 40,109,109, 46,116,104,114,101, 97,100, 95,106,111, -105,110, 41, 10,108,111, 99, 97,108, 32,116,104,114,101, 97,100, 95, 99, 97,110, - 99,101,108, 61, 32, 97,115,115,101,114,116, 40,109,109, 46,116,104,114,101, 97, -100, 95, 99, 97,110, 99,101,108, 41, 10, 10,108,111, 99, 97,108, 32, 95,115,105, -110,103,108,101, 61, 32, 97,115,115,101,114,116, 40,109,109, 46, 95,115,105,110, -103,108,101, 41, 10,108,111, 99, 97,108, 32, 95,118,101,114,115,105,111,110, 61, - 32, 97,115,115,101,114,116, 40,109,109, 46, 95,118,101,114,115,105,111,110, 41, - 10, 10,108,111, 99, 97,108, 32, 95,100,101,101,112, 95,117,115,101,114,100, 97, -116, 97, 61, 32, 97,115,115,101,114,116, 40,109,109, 46, 95,100,101,101,112, 95, -117,115,101,114,100, 97,116, 97, 41, 10, 10,108,111, 99, 97,108, 32,110,111,119, - 95,115,101, 99,115, 61, 32, 97,115,115,101,114,116, 40, 32,109,109, 46,110,111, -119, 95,115,101, 99,115, 32, 41, 10,108,111, 99, 97,108, 32,119, 97,107,101,117, -112, 95, 99,111,110,118, 61, 32, 97,115,115,101,114,116, 40, 32,109,109, 46,119, - 97,107,101,117,112, 95, 99,111,110,118, 32, 41, 10,108,111, 99, 97,108, 32,116, -105,109,101,114, 95,103, 97,116,101,119, 97,121, 61, 32, 97,115,115,101,114,116, - 40, 32,109,109, 46,116,105,109,101,114, 95,103, 97,116,101,119, 97,121, 32, 41, - 10, 10,108,111, 99, 97,108, 32,109, 97,120, 95,112,114,105,111, 61, 32, 97,115, -115,101,114,116, 40, 32,109,109, 46,109, 97,120, 95,112,114,105,111, 32, 41, 10, - 10, 45, 45, 32, 84,104,105,115, 32, 99,104,101, 99,107, 32,105,115, 32,102,111, -114, 32,115,117, 98,108, 97,110,101,115, 32,114,101,113,117,105,114,105,110,103, - 32, 76, 97,110,101,115, 10, 45, 45, 10, 45, 45, 32, 84, 66, 68, 58, 32, 87,101, - 32, 99,111,117,108,100, 32, 97,108,115,111, 32,104, 97,118,101, 32,116,104,101, - 32, 67, 32,108,101,118,101,108, 32,101,120,112,111,115,101, 32, 39,115,116,114, -105,110,103, 46,103,109, 97,116, 99,104, 39, 32,102,111,114, 32,117,115, 46, 32, - 66,117,116, 32,116,104,105,115, 32,105,115, 32,115,105,109,112,108,101,114, 46, - 10, 45, 45, 10,105,102, 32,110,111,116, 32,115,116,114,105,110,103, 32,116,104, -101,110, 10, 32, 32, 32, 32,101,114,114,111,114, 40, 32, 34, 84,111, 32,117,115, -101, 32, 39,108, 97,110,101,115, 39, 44, 32,121,111,117, 32,119,105,108,108, 32, - 97,108,115,111, 32,110,101,101,100, 32,116,111, 32,104, 97,118,101, 32, 39,115, -116,114,105,110,103, 39, 32, 97,118, 97,105,108, 97, 98,108,101, 46, 34, 44, 32, - 50, 32, 41, 10,101,110,100, 10, 10, 45, 45, 32, 10, 45, 45, 32, 67, 97, 99,104, -101, 32,103,108,111, 98, 97,108,115, 32,102,111,114, 32, 99,111,100,101, 32,116, -104, 97,116, 32,109,105,103,104,116, 32,114,117,110, 32,117,110,100,101,114, 32, -115, 97,110,100, 98,111,120,105,110,103, 32, 10, 45, 45, 10,108,111, 99, 97,108, - 32, 97,115,115,101,114,116, 61, 32, 97,115,115,101,114,116, 10,108,111, 99, 97, -108, 32,115,116,114,105,110,103, 95,103,109, 97,116, 99,104, 61, 32, 97,115,115, -101,114,116, 40, 32,115,116,114,105,110,103, 46,103,109, 97,116, 99,104, 32, 41, - 10,108,111, 99, 97,108, 32,115,101,108,101, 99,116, 61, 32, 97,115,115,101,114, -116, 40, 32,115,101,108,101, 99,116, 32, 41, 10,108,111, 99, 97,108, 32,116,121, -112,101, 61, 32, 97,115,115,101,114,116, 40, 32,116,121,112,101, 32, 41, 10,108, -111, 99, 97,108, 32,112, 97,105,114,115, 61, 32, 97,115,115,101,114,116, 40, 32, -112, 97,105,114,115, 32, 41, 10,108,111, 99, 97,108, 32,116,111,115,116,114,105, -110,103, 61, 32, 97,115,115,101,114,116, 40, 32,116,111,115,116,114,105,110,103, - 32, 41, 10,108,111, 99, 97,108, 32,101,114,114,111,114, 61, 32, 97,115,115,101, -114,116, 40, 32,101,114,114,111,114, 32, 41, 10,108,111, 99, 97,108, 32,115,101, -116,109,101,116, 97,116, 97, 98,108,101, 61, 32, 97,115,115,101,114,116, 40, 32, -115,101,116,109,101,116, 97,116, 97, 98,108,101, 32, 41, 10,108,111, 99, 97,108, - 32,114, 97,119,103,101,116, 61, 32, 97,115,115,101,114,116, 40, 32,114, 97,119, -103,101,116, 32, 41, 10, 10, 65, 66, 79, 85, 84, 61, 32, 10,123, 10, 32, 32, 32, - 32, 97,117,116,104,111,114, 61, 32, 34, 65,115,107,111, 32, 75, 97,117,112,112, -105, 32, 60, 97,107, 97,117,112,112,105, 64,103,109, 97,105,108, 46, 99,111,109, - 62, 34, 44, 10, 32, 32, 32, 32,100,101,115, 99,114,105,112,116,105,111,110, 61, - 32, 34, 82,117,110,110,105,110,103, 32,109,117,108,116,105,112,108,101, 32, 76, -117, 97, 32,115,116, 97,116,101,115, 32,105,110, 32,112, 97,114, 97,108,108,101, -108, 34, 44, 10, 32, 32, 32, 32,108,105, 99,101,110,115,101, 61, 32, 34, 77, 73, - 84, 47, 88, 49, 49, 34, 44, 10, 32, 32, 32, 32, 99,111,112,121,114,105,103,104, -116, 61, 32, 34, 67,111,112,121,114,105,103,104,116, 32, 40, 99, 41, 32, 50, 48, - 48, 55, 45, 48, 56, 44, 32, 65,115,107,111, 32, 75, 97,117,112,112,105, 34, 44, - 10, 32, 32, 32, 32,118,101,114,115,105,111,110, 61, 32, 95,118,101,114,115,105, -111,110, 44, 10,125, 10, 10, 10, 45, 45, 32, 77, 97,107,105,110,103, 32, 99,111, -112,105,101,115, 32,111,102, 32,110,101, 99,101,115,115, 97,114,121, 32,115,121, -115,116,101,109, 32,108,105, 98,115, 32,119,105,108,108, 32,112, 97,115,115, 32, -116,104,101,109, 32,111,110, 32, 97,115, 32,117,112,118, 97,108,117,101,115, 59, - 10, 45, 45, 32,111,110,108,121, 32,116,104,101, 32,102,105,114,115,116, 32,115, -116, 97,116,101, 32,100,111,105,110,103, 32, 34,114,101,113,117,105,114,101, 32, - 39,108, 97,110,101,115, 39, 34, 32,119,105,108,108, 32,110,101,101,100, 32,116, -111, 32,104, 97,118,101, 32, 39,115,116,114,105,110,103, 39, 10, 45, 45, 32, 97, -110,100, 32, 39,116, 97, 98,108,101, 39, 32,118,105,115,105, 98,108,101, 46, 10, - 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 87, 82, - 40,115,116,114, 41, 10, 32, 32, 32, 32,105,111, 46,115,116,100,101,114,114, 58, -119,114,105,116,101, 40, 32,115,116,114, 46, 46, 34, 92,110, 34, 32, 41, 10,101, -110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 68, - 85, 77, 80, 40, 32,116, 98,108, 32, 41, 10, 32, 32, 32, 32,105,102, 32,110,111, -116, 32,116, 98,108, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,101,110, -100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116,114, 61, 34, 34, 10, 32, - 32, 32, 32,102,111,114, 32,107, 44,118, 32,105,110, 32,112, 97,105,114,115, 40, -116, 98,108, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114, 61, - 32,115,116,114, 46, 46,107, 46, 46, 34, 61, 34, 46, 46,116,111,115,116,114,105, -110,103, 40,118, 41, 46, 46, 34, 92,110, 34, 10, 32, 32, 32, 32,101,110,100, 10, - 32, 32, 32, 32, 87, 82, 40,115,116,114, 41, 10,101,110,100, 10, 10, 10, 45, 45, - 45, 61, 61, 61, 32, 76, 97,110,105,110,103, 32, 61, 61, 61, 45, 45, 45, 10, 10, - 45, 45, 32,108, 97,110,101, 95,104, 91, 49, 46, 46,110, 93, 58, 32,108, 97,110, -101, 32,114,101,115,117,108,116,115, 44, 32,115, 97,109,101, 32, 97,115, 32,118, -105, 97, 32, 39,108, 97,110,101, 95,104, 58,106,111,105,110, 40, 41, 39, 10, 45, - 45, 32,108, 97,110,101, 95,104, 91, 48, 93, 58, 32, 32, 32, 32, 99, 97,110, 32, - 98,101, 32,114,101, 97,100, 32,116,111, 32,109, 97,107,101, 32,115,117,114,101, - 32, 97, 32,116,104,114,101, 97,100, 32,104, 97,115, 32,102,105,110,105,115,104, -101,100, 32, 40, 97,108,119, 97,121,115, 32,103,105,118,101,115, 32, 39,116,114, -117,101, 39, 41, 10, 45, 45, 32,108, 97,110,101, 95,104, 91, 45, 49, 93, 58, 32, - 32, 32,101,114,114,111,114, 32,109,101,115,115, 97,103,101, 44, 32,119,105,116, -104,111,117,116, 32,112,114,111,112, 97,103, 97,116,105,110,103, 32,116,104,101, - 32,101,114,114,111,114, 10, 45, 45, 10, 45, 45, 32, 32, 32, 32, 32, 32, 82,101, - 97,100,105,110,103, 32, 97, 32, 76, 97,110,101, 32,114,101,115,117,108,116, 32, - 40,111,114, 32, 91, 48, 93, 41, 32,112,114,111,112, 97,103, 97,116,101,115, 32, - 97, 32,112,111,115,115,105, 98,108,101, 32,101,114,114,111,114, 32,105,110, 32, -116,104,101, 32,108, 97,110,101, 10, 45, 45, 32, 32, 32, 32, 32, 32, 40, 97,110, -100, 32,101,120,101, 99,117,116,105,111,110, 32,100,111,101,115, 32,110,111,116, - 32,114,101,116,117,114,110, 41, 46, 32, 67, 97,110, 99,101,108,108,101,100, 32, -108, 97,110,101,115, 32,103,105,118,101, 32, 39,110,105,108, 39, 32,118, 97,108, -117,101,115, 46, 10, 45, 45, 10, 45, 45, 32,108, 97,110,101, 95,104, 46,115,116, - 97,116,101, 58, 32, 34,112,101,110,100,105,110,103, 34, 47, 34,114,117,110,110, -105,110,103, 34, 47, 34,119, 97,105,116,105,110,103, 34, 47, 34,100,111,110,101, - 34, 47, 34,101,114,114,111,114, 34, 47, 34, 99, 97,110, 99,101,108,108,101,100, - 34, 10, 45, 45, 10,108,111, 99, 97,108, 32,108, 97,110,101, 95,109,116, 61, 32, -123, 10, 32, 32, 32, 32, 95, 95,105,110,100,101,120, 61, 32,102,117,110, 99,116, -105,111,110, 40, 32,109,101, 44, 32,107, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,116,121,112,101, 40,107, 41, 32, - 61, 61, 32, 34,110,117,109, 98,101,114, 34, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, - 39,109,101, 91, 48, 93, 61,116,114,117,101, 39, 32,109, 97,114,107,115, 32,119, -101, 39,118,101, 32, 97,108,114,101, 97,100,121, 32,116, 97,107,101,110, 32,105, -110, 32,116,104,101, 32,114,101,115,117,108,116,115, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -110,111,116, 32,114, 97,119,103,101,116, 40, 32,109,101, 44, 32, 48, 32, 41, 32, -116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 87, 97,105,116, 32,105,110,100, -101,102,105,110, 97,116,101,108,121, 59, 32,101,105,116,104,101,114, 32,112,114, -111,112, 97,103, 97,116,101,115, 32, 97,110, 32,101,114,114,111,114, 32,111,114, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 45, 45, 32,114,101,116,117,114,110,115, 32,116,104,101, 32, -114,101,116,117,114,110, 32,118, 97,108,117,101,115, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,109,101, 91, 48, 93, 61, 32,116,114,117,101, 32, 32, 45, 45, - 32,109, 97,114,107,101,114, 44, 32,101,118,101,110, 32,111,110, 32,101,114,114, -111,114,115, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,116, 61, 32,123, 32, -116,104,114,101, 97,100, 95,106,111,105,110, 40,109,101, 46, 95,117,100, 41, 32, -125, 32, 32, 32, 45, 45, 32,119, 97,105,116, 32,105,110,100,101,102,105,110, 97, -116,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 32,123, 32, 46, 46, 46, 32,125, 32, 32, 32, 32, 32, 32, 34,100, -111,110,101, 34, 58, 32,114,101,103,117,108, 97,114, 32,114,101,116,117,114,110, - 44, 32, 48, 46, 46, 78, 32,114,101,115,117,108,116,115, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 45, 45, 32,123, 32,125, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, - 99, 97,110, 99,101,108,108,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32,123, 32,110,105,108, 44, 32,101,114,114, 95,115,116,114, 44, 32,115,116, - 97, 99,107, 95,116, 98,108, 32,125, 32, 34,101,114,114,111,114, 34, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116, 61, 32,116,104,114, -101, 97,100, 95,115,116, 97,116,117,115, 40,109,101, 46, 95,117,100, 41, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,115,116, 61, 61, 34,100,111,110,101, 34, 32,116,104,101, -110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 85,115,101, 32, 39,112, 97, -105,114,115, 39, 32, 97,110,100, 32,110,111,116, 32, 39,105,112, 97,105,114,115, - 39, 32,115,111, 32,116,104, 97,116, 32,110,105,108, 32,104,111,108,101,115, 32, -105,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101, 32,114,101, -116,117,114,110,101,100, 32,118, 97,108,117,101,115, 32, 97,114,101, 32,116,111, -108,101,114, 97,116,101,100, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32,112, - 97,105,114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,109,101, 91,105, 93, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,115,116, 61, 61, 34, -101,114,114,111,114, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 97,115,115,101,114,116, 40, 32,116, 91, 49, 93, 61, 61,110,105,108, 32, 97,110, -100, 32,116, 91, 50, 93, 32, 97,110,100, 32,116,121,112,101, 40,116, 91, 51, 93, - 41, 61, 61, 34,116, 97, 98,108,101, 34, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,109,101, 91, 45, 49, 93, 61, 32,116, 91, 50, 93, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 32,109,101, 91, 45, 50, 93, 32, 99,111,117,108,100, 32, 99, 97, -114,114,121, 32,116,104,101, 32,115,116, 97, 99,107, 32,116, 97, 98,108,101, 44, - 32, 98,117,116, 32,101,118,101,110, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32,109,101, 91, 45, 49, 93, 32,105,115, 32,114, 97,116,104,101,114, 32,117, -110,110,101, 99,101,115,115, 97,114,121, 32, 40, 97,110,100, 32,117,110,100,111, - 99,117,109,101,110,116,101,100, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32,117,115,101, 32, 39, 58,106,111,105,110, 40, 41, 39, 32,105,110,115,116, -101, 97,100, 46, 32, 32, 32, 45, 45, 65, 75, 97, 32, 50, 50, 45, 74, 97,110, 45, - 50, 48, 48, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,115,116, 61, 61, - 34, 99, 97,110, 99,101,108,108,101,100, 34, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 45, 45, 32,100,111, 32,110,111,116,104,105,110,103, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,114,114,111, -114, 40, 32, 34, 85,110,101,120,112,101, 99,116,101,100, 32,115,116, 97,116,117, -115, 58, 32, 34, 46, 46,115,116, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, -110,100, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32, 67,104,101, 99,107, 32,101,114,114,111,114,115, 32, -101,118,101,110, 32,105,102, 32,119,101, 39,100, 32,102,105,114,115,116, 32,112, -101,101,107,101,100, 32,116,104,101,109, 32,118,105, 97, 32, 91, 45, 49, 93, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 45, 45, 32, 97,110,100, 32,116,104,101,110, 32, 99, 97,109,101, 32,102,111,114, - 32,116,104,101, 32, 97, 99,116,117, 97,108, 32,114,101,115,117,108,116,115, 46, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,108,111, 99, 97,108, 32,101,114,114, 61, 32,114, 97,119,103,101, -116, 40,109,101, 44, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114,126, 61,110,105, -108, 32, 97,110,100, 32,107,126, 61, 45, 49, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 45, 45, 32, 78,111,116,101, 58, 32, 76,117, 97, 32, 53, 46, 49, 32,105,110, -116,101,114,112,114,101,116,101,114, 32,105,115, 32,110,111,116, 32,112,114,101, -112, 97,114,101,100, 32,116,111, 32,115,104,111,119, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, - 32, 32, 32, 32, 32, 32, 32,110,111,110, 45,115,116,114,105,110,103, 32,101,114, -114,111,114,115, 44, 32,115,111, 32,119,101, 32,117,115,101, 32, 39,116,111,115, -116,114,105,110,103, 40, 41, 39, 32,104,101,114,101, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, - 32, 32, 32, 32, 32, 32, 32,116,111, 32,103,101,116, 32,109,101, 97,110,105,110, -103,102,117,108, 32,111,117,116,112,117,116, 46, 32, 32, 45, 45, 65, 75, 97, 32, - 50, 50, 45, 74, 97,110, 45, 50, 48, 48, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 45, 45, 32, 32, 32, 32, 32, 32, 32, 65,108,115,111, 44, 32,116,104, -101, 32,115,116, 97, 99,107, 32,100,117,109,112, 32,119,101, 32,103,101,116, 32, -105,115, 32,110,111, 32,103,111,111,100, 59, 32,105,116, 32,111,110,108,121, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32, 32, 32, 32, 32, 32, 32,108,105,115,116,115, 32,111, -117,114, 32,105,110,116,101,114,110, 97,108, 32, 76, 97,110,101,115, 32,102,117, -110, 99,116,105,111,110,115, 46, 32, 84,104,101,114,101, 32,115,101,101,109,115, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 45, 45, 32, 32, 32, 32, 32, 32, 32,116,111, 32, 98,101, 32, -110,111, 32,119, 97,121, 32,116,111, 32,115,119,105,116, 99,104, 32,105,116, 32, -111,102,102, 44, 32,116,104,111,117,103,104, 46, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 32, 76,101,118,101,108, 32, 51, 32,115,104,111,117,108,100, 32, -115,104,111,119, 32,116,104,101, 32,108,105,110,101, 32,119,104,101,114,101, 32, - 39,104, 91,120, 93, 39, 32,119, 97,115, 32,114,101, 97,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 45, 45, 32, 98,117,116, 32,116,104,105,115, 32,111,110,108,121, 32,115,101,101, -109,115, 32,116,111, 32,119,111,114,107, 32,102,111,114, 32,115,116,114,105,110, -103, 32,109,101,115,115, 97,103,101,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 40, 76, -117, 97, 32, 53, 46, 49, 46, 52, 41, 46, 32, 78,111, 32,105,100,101, 97, 44, 32, -119,104,121, 46, 32, 32, 32, 45, 45, 65, 75, 97, 32, 50, 50, 45, 74, 97,110, 45, - 50, 48, 48, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,114,114,111, -114, 40, 32,116,111,115,116,114,105,110,103, 40,101,114,114, 41, 44, 32, 51, 32, - 41, 32, 32, 32, 45, 45, 32,108,101,118,101,108, 32, 51, 32,115,104,111,117,108, -100, 32,115,104,111,119, 32,116,104,101, 32,108,105,110,101, 32,119,104,101,114, -101, 32, 39,104, 91,120, 93, 39, 32,119, 97,115, 32,114,101, 97,100, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,114, 97,119,103,101,116, 40, 32,109,101, 44, - 32,107, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,101,108,115,101,105,102, 32,107, 61, 61, 34,115,116, 97,116,117, -115, 34, 32,116,104,101,110, 32, 32, 32, 32, 32, 45, 45, 32,109,101, 46,115,116, - 97,116,117,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,104,114,101, 97,100, 95,115, -116, 97,116,117,115, 40,109,101, 46, 95,117,100, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,114, -114,111,114, 40, 32, 34, 85,110,107,110,111,119,110, 32,107,101,121, 58, 32, 34, - 46, 46,107, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, -110,100, 10, 32, 32, 32, 32,125, 10, 10, 45, 45, 45, 45, 45, 10, 45, 45, 32,104, - 61, 32,108, 97,110,101,115, 46,103,101,110, 40, 32, 91,108,105, 98,115, 95,115, -116,114,124,111,112,116, 95,116, 98,108, 32, 91, 44, 32, 46, 46, 46, 93, 44, 93, - 32,108, 97,110,101, 95,102,117,110, 99, 32, 41, 32, 40, 32, 91, 46, 46, 46, 93, - 32, 41, 10, 45, 45, 10, 45, 45, 32, 39,108,105, 98,115, 39, 58, 32,110,105,108, - 58, 32, 32, 32, 32, 32,110,111, 32,108,105, 98,114, 97,114,105,101,115, 32, 97, -118, 97,105,108, 97, 98,108,101, 32, 40,100,101,102, 97,117,108,116, 41, 10, 45, - 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 34, 58, 32, 32, 32, 32, 32, 32,111, -110,108,121, 32, 98, 97,115,101, 32,108,105, 98,114, 97,114,121, 32, 40, 39, 97, -115,115,101,114,116, 39, 44, 32, 39,112,114,105,110,116, 39, 44, 32, 39,117,110, -112, 97, 99,107, 39, 32,101,116, 99, 46, 41, 10, 45, 45, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 34,109, 97,116,104, 44,111,115, 34, 58, 32,109, 97,116,104, 32, 43, - 32,111,115, 32, 43, 32, 98, 97,115,101, 32,108,105, 98,114, 97,114,105,101,115, - 32, 40,110, 97,109,101,100, 32,111,110,101,115, 32, 43, 32, 98, 97,115,101, 41, - 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 42, 34, 58, 32, 32, 32, 32, - 32, 97,108,108, 32,115,116, 97,110,100, 97,114,100, 32,108,105, 98,114, 97,114, -105,101,115, 32, 97,118, 97,105,108, 97, 98,108,101, 10, 45, 45, 10, 45, 45, 32, - 39,111,112,116, 39, 58, 32, 46,112,114,105,111,114,105,116,121, 58, 32, 32,105, -110,116, 32, 40, 45, 50, 46, 46, 43, 50, 41, 32,115,109, 97,108,108,101,114, 32, -105,115, 32,108,111,119,101,114, 32,112,114,105,111,114,105,116,121, 32, 40, 48, - 32, 61, 32,100,101,102, 97,117,108,116, 41, 10, 45, 45, 10, 45, 45, 9, 32, 32, - 32, 32, 32, 32, 46, 99, 97,110, 99,101,108,115,116,101,112, 58, 32, 98,111,111, -108, 32,124, 32,117,105,110,116, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,102, 97,108,115,101, 58, 32, 99, 97,110, 99,101,108,108, 97,116,105, -111,110, 32, 99,104,101, 99,107, 32,111,110,108,121, 32, 97,116, 32,112,101,110, -100,105,110,103, 32, 76,105,110,100, 97, 32,111,112,101,114, 97,116,105,111,110, -115, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 40,115,101,110,100, 47,114,101, 99,101,105,118,101, 41, 32,115,111, - 32,110,111, 32,114,117,110,116,105,109,101, 32,112,101,114,102,111,114,109, 97, -110, 99,101, 32,112,101,110, 97,108,116,121, 32, 40,100,101,102, 97,117,108,116, - 41, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,114,117,101, - 58, 32, 32, 97,100,101,113,117, 97,116,101, 32, 99, 97,110, 99,101,108,108, 97, -116,105,111,110, 32, 99,104,101, 99,107, 32, 40,115, 97,109,101, 32, 97,115, 32, - 49, 48, 48, 41, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 62, - 48, 58, 32, 32, 32, 32, 99, 97,110, 99,101,108,108, 97,116,105,111,110, 32, 99, -104,101, 99,107, 32,101,118,101,114,121, 32,120, 32, 76,117, 97, 32,108,105,110, -101,115, 32, 40,115,109, 97,108,108, 32,110,117,109, 98,101,114, 61, 32,102, 97, -115,116,101,114, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,114,101, 97, 99,116,105,111,110, 32, 98,117,116, 32,109, -111,114,101, 32,112,101,114,102,111,114,109, 97,110, 99,101, 32,111,118,101,114, -104,101, 97,100, 41, 10, 45, 45, 10, 45, 45, 32, 32, 32, 32, 32, 32, 32, 32, 46, -103,108,111, 98, 97,108,115, 58, 32, 32,116, 97, 98,108,101, 32,111,102, 32,103, -108,111, 98, 97,108,115, 32,116,111, 32,115,101,116, 32,102,111,114, 32, 97, 32, -110,101,119, 32,116,104,114,101, 97,100, 32, 40,112, 97,115,115,101,100, 32, 98, -121, 32,118, 97,108,117,101, 41, 10, 45, 45, 10, 45, 45, 32, 32, 32, 32, 32, 32, - 32, 32, 46, 46, 46, 32, 40,109,111,114,101, 32,111,112,116,105,111,110,115, 32, -109, 97,121, 32, 98,101, 32,105,110,116,114,111,100,117, 99,101,100, 32,108, 97, -116,101,114, 41, 32, 46, 46, 46, 10, 45, 45, 10, 45, 45, 32, 67, 97,108,108,105, -110,103, 32,119,105,116,104, 32, 97, 32,102,117,110, 99,116,105,111,110, 32,112, - 97,114, 97,109,101,116,101,114, 32, 40, 39,108, 97,110,101, 95,102,117,110, 99, - 39, 41, 32,101,110,100,115, 32,116,104,101, 32,115,116,114,105,110,103, 47,116, - 97, 98,108,101, 10, 45, 45, 32,109,111,100,105,102,105,101,114,115, 44, 32, 97, -110,100, 32,112,114,101,112, 97,114,101,115, 32, 97, 32,108, 97,110,101, 32,103, -101,110,101,114, 97,116,111,114, 46, 32, 79,110,101, 32, 99, 97,110, 32,101,105, -116,104,101,114, 32,102,105,110,105,115,104, 32,104,101,114,101, 44, 10, 45, 45, - 32, 97,110,100, 32, 99, 97,108,108, 32,116,104,101, 32,103,101,110,101,114, 97, -116,111,114, 32,108, 97,116,101,114, 32, 40,109, 97,121, 98,101, 32,109,117,108, -116,105,112,108,101, 32,116,105,109,101,115, 44, 32,119,105,116,104, 32,100,105, -102,102,101,114,101,110,116, 32,112, 97,114, 97,109,101,116,101,114,115, 41, 32, - 10, 45, 45, 32,111,114, 32, 97,100,100, 32,111,110, 32, 97, 99,116,117, 97,108, - 32,116,104,114,101, 97,100, 32, 97,114,103,117,109,101,110,116,115, 32,116,111, - 32, 97,108,115,111, 32,105,103,110,105,116,101, 32,116,104,101, 32,116,104,114, -101, 97,100, 32,111,110, 32,116,104,101, 32,115, 97,109,101, 32, 99, 97,108,108, - 46, 10, 45, 45, 10,108,111, 99, 97,108, 32,108, 97,110,101, 95,112,114,111,120, -121, 10, 10,108,111, 99, 97,108, 32,118, 97,108,105,100, 95,108,105, 98,115, 61, - 32,123, 10, 32, 32, 32, 32, 91, 34,112, 97, 99,107, 97,103,101, 34, 93, 61, 32, -116,114,117,101, 44, 10, 32, 32, 32, 32, 91, 34,116, 97, 98,108,101, 34, 93, 61, - 32,116,114,117,101, 44, 10, 32, 32, 32, 32, 91, 34,105,111, 34, 93, 61, 32,116, -114,117,101, 44, 10, 32, 32, 32, 32, 91, 34,111,115, 34, 93, 61, 32,116,114,117, -101, 44, 10, 32, 32, 32, 32, 91, 34,115,116,114,105,110,103, 34, 93, 61, 32,116, -114,117,101, 44, 10, 32, 32, 32, 32, 91, 34,109, 97,116,104, 34, 93, 61, 32,116, -114,117,101, 44, 10, 32, 32, 32, 32, 91, 34,100,101, 98,117,103, 34, 93, 61, 32, -116,114,117,101, 44, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 91, 34, 98, - 97,115,101, 34, 93, 61, 32,116,114,117,101, 44, 10, 32, 32, 32, 32, 91, 34, 99, -111,114,111,117,116,105,110,101, 34, 93, 61, 32,116,114,117,101, 44, 10, 32, 32, - 32, 32, 91, 34, 42, 34, 93, 61, 32,116,114,117,101, 10,125, 10, 10,102,117,110, - 99,116,105,111,110, 32,103,101,110, 40, 32, 46, 46, 46, 32, 41, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32,111,112,116, 61, 32,123,125, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,108,105, 98,115, 61, 32,110,105,108, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,108,101,118, 61, 32, 50, 32, 32, 45, 45, 32,108,101,118,101, -108, 32,102,111,114, 32,101,114,114,111,114,115, 10, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32,110, 61, 32,115,101,108,101, 99,116, 40, 39, 35, 39, 44, 46, 46, - 46, 41, 10, 32, 32, 32, 32, 10, 32, 32, 32, 32,105,102, 32,110, 61, 61, 48, 32, -116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,114,114,111,114, 40, 32, - 34, 78,111, 32,112, 97,114, 97,109,101,116,101,114,115, 33, 34, 32, 41, 10, 32, - 32, 32, 32,101,110,100, 10, 10, 32, 32, 32, 32,102,111,114, 32,105, 61, 49, 44, -110, 45, 49, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, - 32,118, 61, 32,115,101,108,101, 99,116, 40,105, 44, 46, 46, 46, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32,105,102, 32,116,121,112,101, 40,118, 41, 61, 61, 34,115, -116,114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,108,105, 98,115, 61, 32,108,105, 98,115, 32, 97,110,100, 32,108, -105, 98,115, 46, 46, 34, 44, 34, 46, 46,118, 32,111,114, 32,118, 10, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,116,121,112,101, 40,118, 41, 61, - 61, 34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,102,111,114, 32,107, 44,118,118, 32,105,110, 32,112, 97, -105,114,115, 40,118, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,111,112,116, 91,107, 93, 61, 32,118,118, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, - 32,101,108,115,101,105,102, 32,118, 61, 61,110,105,108, 32,116,104,101,110, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,115,107,105,112, 10, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,114,114,111,114, 40, 32, 34, 66, 97,100, 32,112, 97,114, - 97,109,101,116,101,114, 58, 32, 34, 46, 46,116,111,115,116,114,105,110,103, 40, -118, 41, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 32,101,110,100, 10, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,117,110, 99, - 61, 32,115,101,108,101, 99,116, 40,110, 44, 46, 46, 46, 41, 10, 32, 32, 32, 32, -105,102, 32,116,121,112,101, 40,102,117,110, 99, 41,126, 61, 34,102,117,110, 99, -116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, -114,114,111,114, 40, 32, 34, 76, 97,115,116, 32,112, 97,114, 97,109,101,116,101, -114, 32,110,111,116, 32,102,117,110, 99,116,105,111,110, 58, 32, 34, 46, 46,116, -111,115,116,114,105,110,103, 40,102,117,110, 99, 41, 32, 41, 10, 32, 32, 32, 32, -101,110,100, 10, 10, 32, 32, 32, 32, 45, 45, 32, 67,104,101, 99,107, 32, 39,108, -105, 98,115, 39, 32, 97,108,114,101, 97,100,121, 32,104,101,114,101, 44, 32,115, -111, 32,116,104,101, 32,101,114,114,111,114, 32,103,111,101,115, 32,105,110, 32, -116,104,101, 32,114,105,103,104,116, 32,112,108, 97, 99,101, 10, 32, 32, 32, 32, - 45, 45, 32, 40,111,116,104,101,114,119,105,115,101, 32,119,105,108,108, 32, 98, -101, 32,110,111,116,105, 99,101,100, 32,111,110,108,121, 32,111,110, 99,101, 32, -116,104,101, 32,103,101,110,101,114, 97,116,111,114, 32,105,115, 32, 99, 97,108, -108,101,100, 41, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32,105,102, 32,108, -105, 98,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, - 32,115, 32,105,110, 32,115,116,114,105,110,103, 95,103,109, 97,116, 99,104, 40, -108,105, 98,115, 44, 32, 34, 91, 37, 97, 42, 93, 43, 34, 41, 32,100,111, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,118, 97, -108,105,100, 95,108,105, 98,115, 91,115, 93, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,114,114,111,114, 40, 32, - 34, 66, 97,100, 32,108,105, 98,114, 97,114,121, 32,110, 97,109,101, 58, 32, 34, - 46, 46,115, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,114,105, -111, 44, 32, 99,115, 44, 32,103, 95,116, 98,108, 10, 10, 32, 32, 32, 32,102,111, -114, 32,107, 44,118, 32,105,110, 32,112, 97,105,114,115, 40,111,112,116, 41, 32, -100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,107, 61, - 61, 34,112,114,105,111,114,105,116,121, 34, 32,116,104,101,110, 32,112,114,105, -111, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, -107, 61, 61, 34, 99, 97,110, 99,101,108,115,116,101,112, 34, 32,116,104,101,110, - 32, 99,115, 61, 32, 40,118, 61, 61,116,114,117,101, 41, 32, 97,110,100, 32, 49, - 48, 48, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 40,118, 61, 61,102, 97,108,115,101, 41, 32, 97,110,100, - 32, 48, 32,111,114, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,116,121,112,101, 40,118, 41, 61, 61, 34,110,117,109, - 98,101,114, 34, 32, 97,110,100, 32,118, 32,111,114, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,114,114,111,114, 40, - 32, 34, 66, 97,100, 32, 99, 97,110, 99,101,108,115,116,101,112, 58, 32, 34, 46, - 46,116,111,115,116,114,105,110,103, 40,118, 41, 44, 32,108,101,118, 32, 41, 10, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,107, 61, 61, 34,103, -108,111, 98, 97,108,115, 34, 32,116,104,101,110, 32,103, 95,116, 98,108, 61, 32, -118, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 46, 46, 10, 32, 32, 32, 32, 32, - 32, 32, 32,101,108,115,101,105,102, 32,107, 61, 61, 49, 32,116,104,101,110, 32, -101,114,114,111,114, 40, 32, 34,117,110,107,101,121,101,100, 32,111,112,116,105, -111,110, 58, 32, 34, 46, 46, 32,116,111,115,116,114,105,110,103, 40,118, 41, 44, - 32,108,101,118, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32, -101,114,114,111,114, 40, 32, 34, 66, 97,100, 32,111,112,116,105,111,110, 58, 32, - 34, 46, 46, 32,116,111,115,116,114,105,110,103, 40,107, 41, 44, 32,108,101,118, - 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101, -110,100, 10, 10, 32, 32, 32, 32, 45, 45, 32, 76, 97,110,101, 32,103,101,110,101, -114, 97,116,111,114, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 46, 46, 46, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,108, - 97,110,101, 95,112,114,111,120,121, 40, 32,116,104,114,101, 97,100, 95,110,101, -119, 40, 32,102,117,110, 99, 44, 32,108,105, 98,115, 44, 32, 99,115, 44, 32,112, -114,105,111, 44, 32,103, 95,116, 98,108, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 46, 46, 46, - 32, 41, 32, 41, 32, 32, 32, 32, 32, 45, 45, 32, 97,114,103,115, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,108, 97,110, -101, 95,112,114,111,120,121, 61, 32,102,117,110, 99,116,105,111,110, 40, 32,117, -100, 32, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,114,111,120,121, 61, - 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95,117,100, 61, 32,117,100, 44, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, -118,111,105,100, 61, 32,109,101, 58, 99, 97,110, 99,101,108, 40, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 97,110, - 99,101,108, 61, 32,102,117,110, 99,116,105,111,110, 40,109,101, 41, 32,116,104, -114,101, 97,100, 95, 99, 97,110, 99,101,108, 40,109,101, 46, 95,117,100, 41, 32, -101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 32, 91, 46, 46, 46, 93, 32,124, 32, 91,110,105,108, 44,101,114, -114, 44,115,116, 97, 99,107, 95,116, 98,108, 93, 61, 32,109,101, 58,106,111,105, -110, 40, 32, 91,119, 97,105,116, 95,115,101, 99,115, 61, 45, 49, 93, 32, 41, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32,106, -111,105,110, 61, 32,102,117,110, 99,116,105,111,110, 40, 32,109,101, 44, 32,119, - 97,105,116, 32, 41, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,114,101,116,117,114,110, 32,116,104,114,101, 97,100, 95,106,111,105, -110, 40, 32,109,101, 46, 95,117,100, 44, 32,119, 97,105,116, 32, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 44, 10, 32, 32, 32, 32, 32, - 32, 32, 32,125, 10, 32, 32, 32, 32, 97,115,115,101,114,116, 40, 32,112,114,111, -120,121, 46, 95,117,100, 32, 41, 10, 32, 32, 32, 32,115,101,116,109,101,116, 97, -116, 97, 98,108,101, 40, 32,112,114,111,120,121, 44, 32,108, 97,110,101, 95,109, -116, 32, 41, 10, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,114,111,120, -121, 10,101,110,100, 10, 10, 10, 45, 45, 45, 61, 61, 61, 32, 76,105,110,100, 97, -115, 32, 61, 61, 61, 45, 45, 45, 10, 10, 45, 45, 32, 87,101, 32,108,101,116, 32, -116,104,101, 32, 67, 32, 99,111,100,101, 32, 97,116,116, 97, 99,104, 32,109,101, -116,104,111,100,115, 32,116,111, 32,117,115,101,114,100, 97,116, 97, 32,100,105, -114,101, 99,116,108,121, 10, 10, 45, 45, 45, 45, 45, 10, 45, 45, 32,108,105,110, -100, 97, 95,117,100, 61, 32,108, 97,110,101,115, 46,108,105,110,100, 97, 40, 41, - 10, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,108,105,110,100, 97, 40, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,114,111,120,121, 61, 32, 95,100, -101,101,112, 95,117,115,101,114,100, 97,116, 97, 40, 32,108,105,110,100, 97, 95, -105,100, 32, 41, 10, 32, 32, 32, 32, 97,115,115,101,114,116, 40, 32, 40,116,121, -112,101, 40,112,114,111,120,121, 41, 32, 61, 61, 32, 34,117,115,101,114,100, 97, -116, 97, 34, 41, 32, 97,110,100, 32,103,101,116,109,101,116, 97,116, 97, 98,108, -101, 40,112,114,111,120,121, 41, 32, 41, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32,112,114,111,120,121, 10,101,110,100, 10, 10, 10, 45, 45, 45, 61, 61, 61, - 32, 84,105,109,101,114,115, 32, 61, 61, 61, 45, 45, 45, 10, 10, 45, 45, 10, 45, - 45, 32, 79,110, 32,102,105,114,115,116, 32, 39,114,101,113,117,105,114,101, 32, - 34,108, 97,110,101,115, 34, 39, 44, 32, 97, 32,116,105,109,101,114, 32,108, 97, -110,101, 32,105,115, 32,115,112, 97,119,110,101,100, 32,116,104, 97,116, 32,119, -105,108,108, 32,109, 97,105,110,116, 97,105,110, 10, 45, 45, 32,116,105,109,101, -114, 32,116, 97, 98,108,101,115, 32, 97,110,100, 32,115,108,101,101,112, 32,105, -110, 32, 98,101,116,119,101,101,110, 32,116,104,101, 32,116,105,109,101,114, 32, -101,118,101,110,116,115, 46, 32, 65,108,108, 32,105,110,116,101,114, 97, 99,116, -105,111,110, 32,119,105,116,104, 10, 45, 45, 32,116,104,101, 32,116,105,109,101, -114, 32,108, 97,110,101, 32,104, 97,112,112,101,110,115, 32,118,105, 97, 32, 97, - 32, 39,116,105,109,101,114, 95,103, 97,116,101,119, 97,121, 39, 32, 76,105,110, -100, 97, 44, 32,119,104,105, 99,104, 32,105,115, 32, 99,111,109,109,111,110, 32, -116,111, 10, 45, 45, 32, 97,108,108, 32,116,104, 97,116, 32, 39,114,101,113,117, -105,114,101, 32, 34,108, 97,110,101,115, 34, 39, 46, 10, 45, 45, 32, 10, 45, 45, - 32, 76,105,110,100, 97, 32,112,114,111,116,111, 99,111,108, 32,116,111, 32,116, -105,109,101,114, 32,108, 97,110,101, 58, 10, 45, 45, 10, 45, 45, 32, 32, 84, 71, - 87, 95, 75, 69, 89, 58, 32,108,105,110,100, 97, 95,104, 44, 32,107,101,121, 44, - 32, 91,119, 97,107,101,117,112, 95, 97,116, 95,115,101, 99,115, 93, 44, 32, 91, -114,101,112,101, 97,116, 95,115,101, 99,115, 93, 10, 45, 45, 10,108,111, 99, 97, -108, 32, 84, 71, 87, 95, 75, 69, 89, 61, 32, 34, 40,116,105,109,101,114, 32, 99, -111,110,116,114,111,108, 41, 34, 32, 32, 32, 32, 45, 45, 32,116,104,101, 32,107, -101,121, 32,100,111,101,115, 32,110,111,116, 32,109, 97,116,116,101,114, 44, 32, - 97, 32, 39,119,101,105,114,100, 39, 32,107,101,121, 32,109, 97,121, 32,104,101, -108,112, 32,100,101, 98,117,103,103,105,110,103, 10,108,111, 99, 97,108, 32,102, -105,114,115,116, 95,116,105,109,101, 95,107,101,121, 61, 32, 34,102,105,114,115, -116, 32,116,105,109,101, 34, 10, 10,108,111, 99, 97,108, 32,102,105,114,115,116, - 95,116,105,109,101, 61, 32,116,105,109,101,114, 95,103, 97,116,101,119, 97,121, - 58,103,101,116, 40,102,105,114,115,116, 95,116,105,109,101, 95,107,101,121, 41, - 32, 61, 61, 32,110,105,108, 10,116,105,109,101,114, 95,103, 97,116,101,119, 97, -121, 58,115,101,116, 40,102,105,114,115,116, 95,116,105,109,101, 95,107,101,121, - 44,116,114,117,101, 41, 10, 10, 45, 45, 10, 45, 45, 32, 84,105,109,101,114, 32, -108, 97,110,101, 59, 32,105,110,105,116,105, 97,108,105,122,101, 32,111,110,108, -121, 32,111,110, 32,116,104,101, 32,102,105,114,115,116, 32, 39,114,101,113,117, -105,114,101, 32, 34,108, 97,110,101,115, 34, 39, 32,105,110,115,116, 97,110, 99, -101, 32, 40,119,104,105, 99,104, 32,110, 97,116,117,114, 97,108,108,121, 10, 45, - 45, 32,104, 97,115, 32, 39,116, 97, 98,108,101, 39, 32, 97,108,119, 97,121,115, - 32,100,101, 99,108, 97,114,101,100, 41, 10, 45, 45, 10,105,102, 32,102,105,114, -115,116, 95,116,105,109,101, 32,116,104,101,110, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,116, 97, 98,108,101, 95,114,101,109,111,118,101, 61, 32, 97,115,115, -101,114,116, 40, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 32, 41, 10, - 32, 32, 32, 32,108,111, 99, 97,108, 32,116, 97, 98,108,101, 95,105,110,115,101, -114,116, 61, 32, 97,115,115,101,114,116, 40, 32,116, 97, 98,108,101, 46,105,110, -115,101,114,116, 32, 41, 10, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, - 45, 32,123, 32, 91,100,101,101,112, 95,108,105,110,100, 97, 95,108,105,103,104, -116,117,115,101,114,100, 97,116, 97, 93, 61, 32,123, 32, 91,100,101,101,112, 95, -108,105,110,100, 97, 95,108,105,103,104,116,117,115,101,114,100, 97,116, 97, 93, - 61,108,105,110,100, 97, 95,104, 44, 32, 10, 32, 32, 32, 32, 45, 45, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91,107,101,121, 93, 61, 32,123, 32,119, - 97,107,101,117,112, 95,115,101, 99,115, 32, 91, 44,112,101,114,105,111,100, 95, -115,101, 99,115, 93, 32,125, 32, 91, 44, 32, 46, 46, 46, 93, 32,125, 44, 10, 32, - 32, 32, 32, 45, 45, 32,125, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, - 45, 32, 67,111,108,108,101, 99,116,105,111,110, 32,111,102, 32, 97,108,108, 32, -114,117,110,110,105,110,103, 32,116,105,109,101,114,115, 44, 32,105,110,100,101, -120,101,100, 32,119,105,116,104, 32,108,105,110,100, 97, 39,115, 32, 38, 32,107, -101,121, 46, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 78,111, -116,101, 32,116,104, 97,116, 32,119,101, 32,110,101,101,100, 32,116,111, 32,117, -115,101, 32,116,104,101, 32,100,101,101,112, 32,108,105,103,104,116,117,115,101, -114,100, 97,116, 97, 32,105,100,101,110,116,105,102,105,101,114,115, 44, 32,105, -110,115,116,101, 97,100, 10, 32, 32, 32, 32, 45, 45, 32,111,102, 32, 39,108,105, -110,100, 97, 95,104, 39, 32,116,104,101,109,115,101,108,118,101,115, 32, 97,115, - 32,116, 97, 98,108,101, 32,105,110,100,105, 99,101,115, 46, 32, 79,116,104,101, -114,119,105,115,101, 44, 32,119,101, 39,100, 32,103,101,116, 32,109,117,108,116, -105,112,108,101, 10, 32, 32, 32, 32, 45, 45, 32,101,110,116,114,105,101,115, 32, -102,111,114, 32,116,104,101, 32,115, 97,109,101, 32,116,105,109,101,114, 46, 10, - 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 84,104,101, 32, 39,104, -105,100,100,101,110, 39, 32,114,101,102,101,114,101,110, 99,101, 32,116,111, 32, - 76,105,110,100, 97, 32,112,114,111,120,121, 32,105,115, 32,117,115,101,100, 32, -105,110, 32, 39, 99,104,101, 99,107, 95,116,105,109,101,114,115, 40, 41, 39, 32, - 98,117,116, 10, 32, 32, 32, 32, 45, 45, 32, 97,108,115,111, 32,105,109,112,111, -114,116, 97,110,116, 32,116,111, 32,107,101,101,112, 32,116,104,101, 32, 76,105, -110,100, 97, 32, 97,108,105,118,101, 44, 32,101,118,101,110, 32,105,102, 32, 97, -108,108, 32,111,117,116,115,105,100,101, 32,119,111,114,108,100, 32,116,104,114, -101,119, 10, 32, 32, 32, 32, 45, 45, 32, 97,119, 97,121, 32,112,111,105,110,116, -101,114,115, 32,116,111, 32,105,116, 32, 40,119,104,105, 99,104, 32,119,111,117, -108,100, 32,114,117,105,110, 32,117,110,105,113,117,101,110,101,115,115, 32,111, -102, 32,116,104,101, 32,100,101,101,112, 32,112,111,105,110,116,101,114, 41, 46, - 10, 32, 32, 32, 32, 45, 45, 32, 78,111,119, 32,119,101, 39,114,101, 32,115, 97, -102,101, 46, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32, 99,111,108,108,101, 99,116,105,111,110, 61, 32,123,125, 10, 10, 32, 32, 32, - 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32,115,101,116, 95,116,105,109,101,114, - 40, 32,108,105,110,100, 97, 95,104, 44, 32,107,101,121, 32, 91, 44,119, 97,107, -101,117,112, 95, 97,116, 95,115,101, 99,115, 32, 91, 44,112,101,114,105,111,100, - 95,115,101, 99,115, 93, 93, 32, 41, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,116, 95, -116,105,109,101,114, 40, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, 32,119, - 97,107,101,117,112, 95, 97,116, 44, 32,112,101,114,105,111,100, 32, 41, 10, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 97,115,115,101,114,116, 40, 32,119, 97,107,101, -117,112, 95, 97,116, 61, 61,110,105,108, 32,111,114, 32,119, 97,107,101,117,112, - 95, 97,116, 62, 48, 46, 48, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 97,115, -115,101,114,116, 40, 32,112,101,114,105,111,100, 61, 61,110,105,108, 32,111,114, - 32,112,101,114,105,111,100, 62, 48, 46, 48, 32, 41, 10, 10, 32, 32, 32, 32, 32, - 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,100, 97, 95,100,101,101,112, 61, - 32,108,105,110,100, 97, 58,100,101,101,112, 40, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 97,115,115,101,114,116, 40, 32,108,105,110,100, 97, 95,100,101,101,112, - 32, 41, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 70,105,110,100, 32, -111,114, 32,109, 97,107,101, 32, 97, 32,108,111,111,107,117,112, 32,102,111,114, - 32,116,104,105,115, 32,116,105,109,101,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,116, 49, 61, - 32, 99,111,108,108,101, 99,116,105,111,110, 91,108,105,110,100, 97, 95,100,101, -101,112, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,116, - 49, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116, - 49, 61, 32,123, 32, 91,108,105,110,100, 97, 95,100,101,101,112, 93, 61, 32,108, -105,110,100, 97, 32,125, 32, 32, 32, 32, 32, 45, 45, 32,112,114,111,120,121, 32, -116,111, 32,117,115,101, 32,116,104,101, 32, 76,105,110,100, 97, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,108,108,101, 99,116,105,111,110, 91, -108,105,110,100, 97, 95,100,101,101,112, 93, 61, 32,116, 49, 10, 32, 32, 32, 32, - 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, - 32,105,102, 32,119, 97,107,101,117,112, 95, 97,116, 61, 61,110,105,108, 32,116, -104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 67, -108,101, 97,114, 32,116,104,101, 32,116,105,109,101,114, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,116, 49, 91,107,101,121, 93, 61, 32,110,105,108, 10, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 82,101,109,111,118,101, 32,101,109, -112,116,121, 32,116, 97, 98,108,101,115, 32,102,114,111,109, 32, 99,111,108,108, -101, 99,116,105,111,110, 59, 32,115,112,101,101,100,115, 32,116,105,109,101,114, - 32, 99,104,101, 99,107,115, 32, 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32,108,101,116,115, 32,111,117,114, 32, 39,115, 97,102, -101,116,121, 32,114,101,102,101,114,101,110, 99,101, 39, 32,112,114,111,120,121, - 32, 98,101, 32,103, 99, 58,101,100, 32, 97,115, 32,119,101,108,108, 46, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,109,112,116,121, 61, 32,116, -114,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, 32, -107, 44, 95, 32,105,110, 32,112, 97,105,114,115, 40,116, 49, 41, 32,100,111, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,107, -126, 61, 32,108,105,110,100, 97, 95,100,101,101,112, 32,116,104,101,110, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, -109,112,116,121, 61, 32,102, 97,108,115,101, 59, 32, 98,114,101, 97,107, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,109,112,116,121, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,108, -108,101, 99,116,105,111,110, 91,108,105,110,100, 97, 95,100,101,101,112, 93, 61, - 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 45, 45, 32, 78,111,116,101, 58, 32, 97,110,121, 32,117, -110,114,101, 97,100, 32,116,105,109,101,114, 32,118, 97,108,117,101, 32,105,115, - 32,108,101,102,116, 32, 97,116, 32, 39,108,105,110,100, 97, 91,107,101,121, 93, - 39, 32,105,110,116,101,110,115,105,111,110, 97,108,108,121, 59, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 32, 32, 32, 32, 32, 32, 99,108, -101, 97,114,105,110,103, 32, 97, 32,116,105,109,101,114, 32,106,117,115,116, 32, -115,116,111,112,115, 32,105,116, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108, -115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 78,101, -119, 32,116,105,109,101,114, 32,111,114, 32, 99,104, 97,110,103,105,110,103, 32, -116,104,101, 32,116,105,109,105,110,103,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, -111, 99, 97,108, 32,116, 50, 61, 32,116, 49, 91,107,101,121, 93, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,116, 50, 32,116, -104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -116, 50, 61, 32,123,125, 59, 32,116, 49, 91,107,101,121, 93, 61, 32,116, 50, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116, 50, 91, 49, 93, 61, 32, -119, 97,107,101,117,112, 95, 97,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,116, 50, 91, 50, 93, 61, 32,112,101,114,105,111,100, 32, 32, 32, 45, 45, - 32, 99, 97,110, 32, 98,101, 32, 39,110,105,108, 39, 10, 32, 32, 32, 32, 32, 32, - 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 10, 32, 32, 32, 32, 45, - 45, 45, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 91,110,101,120,116, 95,119, 97, -107,101,117,112, 95, 97,116, 93, 61, 32, 99,104,101, 99,107, 95,116,105,109,101, -114,115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 67, -104,101, 99,107, 32,116,105,109,101,114,115, 44, 32, 97,110,100, 32,119, 97,107, -101, 32,117,112, 32,116,104,101, 32,111,110,101,115, 32,101,120,112,105,114,101, -100, 32, 40,105,102, 32, 97,110,121, 41, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, - 32, 32, 45, 45, 32, 82,101,116,117,114,110,115, 32,116,104,101, 32, 99,108,111, -115,101,115,116, 32,117,112, 99,111,109,105,110,103, 32, 40,114,101,109, 97,105, -110,105,110,103, 41, 32,119, 97,107,101,117,112, 32,116,105,109,101, 32, 40,111, -114, 32, 39,110,105,108, 39, 32,105,102, 32,110,111,110,101, 41, 46, 10, 32, 32, - 32, 32, 45, 45, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,117,110, 99,116, -105,111,110, 32, 99,104,101, 99,107, 95,116,105,109,101,114,115, 40, 41, 10, 10, - 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,110,111,119, 61, 32,110, -111,119, 95,115,101, 99,115, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, - 99, 97,108, 32,110,101,120,116, 95,119, 97,107,101,117,112, 10, 10, 32, 32, 32, - 32, 32, 32, 32, 32,102,111,114, 32,108,105,110,100, 97, 95,100,101,101,112, 44, -116, 49, 32,105,110, 32,112, 97,105,114,115, 40, 99,111,108,108,101, 99,116,105, -111,110, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102, -111,114, 32,107,101,121, 44,116, 50, 32,105,110, 32,112, 97,105,114,115, 40,116, - 49, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,105,102, 32,107,101,121, 61, 61,108,105,110,100, 97, 95,100,101,101,112, 32, -116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 45, 45, 32,110,111, 32, 39, 99,111,110,116,105,110,117,101, - 39, 32,105,110, 32, 76,117, 97, 32, 58, 47, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 39,116, 50, 39, - 58, 32,123, 32,119, 97,107,101,117,112, 95, 97,116, 95,115,101, 99,115, 32, 91, - 44,112,101,114,105,111,100, 95,115,101, 99,115, 93, 32,125, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, -111, 99, 97,108, 32,119, 97,107,101,117,112, 95, 97,116, 61, 32,116, 50, 91, 49, - 93, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,108,111, 99, 97,108, 32,112,101,114,105,111,100, 61, 32,116, 50, 91, 50, - 93, 32, 32, 32, 32, 32, 45, 45, 32,109, 97,121, 32, 98,101, 32, 39,110,105,108, - 39, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,119, 97,107,101,117,112, 95, 97,116, 32, 60, 61, 32,110, -111,119, 32,116,104,101,110, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97, -108, 32,108,105,110,100, 97, 61, 32,116, 49, 91,108,105,110,100, 97, 95,100,101, -101,112, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 97,115,115,101,114,116, 40,108,105,110,100, 97, - 41, 10, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,100, 97, 58,115,101,116, - 40, 32,107,101,121, 44, 32,110,111,119, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 45, 45, 32, 39,112, 97,105,114,115, 40, 41, 39, 32, 97, -108,108,111,119,115, 32,116,104,101, 32,118, 97,108,117,101,115, 32,116,111, 32, - 98,101, 32,109,111,100,105,102,105,101,100, 32, 40, 97,110,100, 32,101,118,101, -110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 45, 45, 32,114,101,109,111,118,101,100, 41, 32, 97,115, - 32,102, 97,114, 32, 97,115, 32,107,101,121,115, 32, 97,114,101, 32,110,111,116, - 32,116,111,117, 99,104,101,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,110,111,116, 32,112,101,114,105,111,100, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,111,110,101, 45,116,105,109,101, - 32,116,105,109,101,114, 59, 32,103,111,110,101, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116, 49, 91,107,101,121, 93, 61, - 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,119, 97,107,101,117,112, 95, - 97,116, 61, 32,110,105,108, 32, 32, 32, 45, 45, 32,110,111, 32, 39, 99,111,110, -116,105,110,117,101, 39, 32,105,110, 32, 76,117, 97, 32, 58, 47, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,114,101,112, -101, 97,116,105,110,103, 32,116,105,109,101,114, 59, 32,102,105,110,100, 32,110, -101,120,116, 32,119, 97,107,101,117,112, 32, 40,109, 97,121, 32,106,117,109,112, - 32,109,117,108,116,105,112,108,101, 32,114,101,112,101, 97,116,115, 41, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101, -112,101, 97,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,119, 97,107, -101,117,112, 95, 97,116, 61, 32,119, 97,107,101,117,112, 95, 97,116, 43,112,101, -114,105,111,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,117,110,116,105,108, 32,119, - 97,107,101,117,112, 95, 97,116, 32, 62, 32,110,111,119, 10, 32, 32, 32, 32, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,116, 50, 91, 49, 93, 61, 32,119, 97,107,101,117, -112, 95, 97,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, - 32,119, 97,107,101,117,112, 95, 97,116, 32, 97,110,100, 32, 40, 40,110,111,116, - 32,110,101,120,116, 95,119, 97,107,101,117,112, 41, 32,111,114, 32, 40,119, 97, -107,101,117,112, 95, 97,116, 32, 60, 32,110,101,120,116, 95,119, 97,107,101,117, -112, 41, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110,101,120,116, 95,119, 97, -107,101,117,112, 61, 32,119, 97,107,101,117,112, 95, 97,116, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 32, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 32, 45, 45, 32, -116, 50, 32,108,111,111,112, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 32, - 45, 45, 32,116, 49, 32,108,111,111,112, 10, 32, 32, 32, 32, 32, 32, 32, 32, 10, - 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,101,120,116, 95, -119, 97,107,101,117,112, 32, 32, 45, 45, 32,109, 97,121, 32, 98,101, 32, 39,110, -105,108, 39, 10, 32, 32, 32, 32,101,110,100, 32, 32, 32, 32, 10, 10, 32, 32, 32, - 32, 45, 45, 45, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 83,110,111,114,101, 32, -108,111,111,112, 32, 40,114,117,110, 32, 97,115, 32, 97, 32,108, 97,110,101, 32, -111,110, 32,116,104,101, 32, 98, 97, 99,107,103,114,111,117,110,100, 41, 10, 32, - 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 72,105,103,104, 32,112,114, -105,111,114,105,116,121, 44, 32,116,111, 32,103,101,116, 32,116,114,117,115,116, -119,111,114,116,104,121, 32,116,105,109,105,110,103,115, 46, 10, 32, 32, 32, 32, - 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 87,101, 32,108,101,116, 32,116,104,101, - 32,116,105,109,101,114, 32,108, 97,110,101, 32, 98,101, 32, 97, 32, 34,102,114, -101,101, 32,114,117,110,110,105,110,103, 34, 32,116,104,114,101, 97,100, 59, 32, -110,111, 32,104, 97,110,100,108,101, 32,116,111, 32,105,116, 10, 32, 32, 32, 32, - 45, 45, 32,114,101,109, 97,105,110,115, 46, 10, 32, 32, 32, 32, 45, 45, 10, 32, - 32, 32, 32,103,101,110, 40, 32, 34,105,111, 34, 44, 32,123, 32,112,114,105,111, -114,105,116,121, 61,109, 97,120, 95,112,114,105,111, 32,125, 44, 32,102,117,110, - 99,116,105,111,110, 40, 41, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105, -108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,108,111, 99, 97,108, 32,110,101,120,116, 95,119, 97,107,101,117,112, - 61, 32, 99,104,101, 99,107, 95,116,105,109,101,114,115, 40, 41, 10, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 83,108,101,101,112, 32,117, -110,116,105,108, 32,110,101,120,116, 32,116,105,109,101,114, 32,116,111, 32,119, - 97,107,101, 32,117,112, 44, 32,111,114, 32, 97, 32,115,101,116, 47, 99,108,101, - 97,114, 32, 99,111,109,109, 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 45, 45, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, - 99, 97,108, 32,115,101, 99,115, 61, 32,110,101,120,116, 95,119, 97,107,101,117, -112, 32, 97,110,100, 32, 40,110,101,120,116, 95,119, 97,107,101,117,112, 32, 45, - 32,110,111,119, 95,115,101, 99,115, 40, 41, 41, 32,111,114, 32,110,105,108, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105, -110,100, 97, 61, 32,116,105,109,101,114, 95,103, 97,116,101,119, 97,121, 58,114, -101, 99,101,105,118,101, 40, 32,115,101, 99,115, 44, 32, 84, 71, 87, 95, 75, 69, - 89, 32, 41, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -108,105,110,100, 97, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,107,101,121, 61, 32,116,105, -109,101,114, 95,103, 97,116,101,119, 97,121, 58,114,101, 99,101,105,118,101, 40, - 32, 48, 46, 48, 44, 32, 84, 71, 87, 95, 75, 69, 89, 32, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,119, 97, -107,101,117,112, 95, 97,116, 61, 32,116,105,109,101,114, 95,103, 97,116,101,119, - 97,121, 58,114,101, 99,101,105,118,101, 40, 32, 48, 46, 48, 44, 32, 84, 71, 87, - 95, 75, 69, 89, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,108,111, 99, 97,108, 32,112,101,114,105,111,100, 61, 32,116,105,109, -101,114, 95,103, 97,116,101,119, 97,121, 58,114,101, 99,101,105,118,101, 40, 32, - 48, 46, 48, 44, 32, 84, 71, 87, 95, 75, 69, 89, 32, 41, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,115,115,101,114,116, 40, 32,107, -101,121, 32, 97,110,100, 32,119, 97,107,101,117,112, 95, 97,116, 32, 97,110,100, - 32,112,101,114,105,111,100, 32, 41, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,115,101,116, 95,116,105,109,101,114, 40, 32,108,105, -110,100, 97, 44, 32,107,101,121, 44, 32,119, 97,107,101,117,112, 95, 97,116, 44, - 32,112,101,114,105,111,100, 62, 48, 32, 97,110,100, 32,112,101,114,105,111,100, - 32,111,114, 32,110,105,108, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32,101,110,100, 32, 41, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, - 10, 45, 45, 32, 61, 32,116,105,109,101,114, 40, 32,108,105,110,100, 97, 95,104, - 44, 32,107,101,121, 95,118, 97,108, 44, 32,100, 97,116,101, 95,116, 98,108,124, -102,105,114,115,116, 95,115,101, 99,115, 32, 91, 44,112,101,114,105,111,100, 95, -115,101, 99,115, 93, 32, 41, 10, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, -116,105,109,101,114, 40, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, 32, 97, - 44, 32,112,101,114,105,111,100, 32, 41, 10, 10, 32, 32, 32, 32,105,102, 32, 97, - 61, 61, 48, 46, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32, 67, 97,108,108,101,114, 32,101,120,112,101, 99,116,115, 32,116,111, 32, -103,101,116, 32, 99,117,114,114,101,110,116, 32,116,105,109,101, 32,115,116, 97, -109,112, 32,105,110, 32, 76,105,110,100, 97, 44, 32,111,110, 32,114,101,116,117, -114,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 40,108,105,107,101, 32, -116,104,101, 32,116,105,109,101,114, 32,104, 97,100, 32,101,120,112,105,114,101, -100, 32,105,110,115,116, 97,110,116,108,121, 41, 59, 32,105,116, 32,119,111,117, -108,100, 32, 98,101, 32,103,111,111,100, 32,116,111, 32,115,101,116, 32,116,104, -105,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 97,115, 32,108, 97,116, -101, 32, 97,115, 32,112,111,115,115,105, 98,108,101, 32, 40,116,111, 32,103,105, -118,101, 32,109,111,115,116, 32, 99,117,114,114,101,110,116, 32,116,105,109,101, - 41, 32, 98,117,116, 32, 97,108,115,111, 32,119,101, 32,119, 97,110,116, 32,105, -116, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,111, 32,112,114,101, 99, -101,100,101, 32, 97,110,121, 32,112,111,115,115,105, 98,108,101, 32,116,105,109, -101,114,115, 32,116,104, 97,116, 32,109,105,103,104,116, 32,115,116, 97,114,116, - 32,115,116,114,105,107,105,110,103, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,100, 97, 58,115,101,116, 40, - 32,107,101,121, 44, 32,110,111,119, 95,115,101, 99,115, 40, 41, 32, 41, 10, 10, - 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,112,101,114,105,111, -100, 32,111,114, 32,112,101,114,105,111,100, 61, 61, 48, 46, 48, 32,116,104,101, -110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,105,109,101,114, 95, -103, 97,116,101,119, 97,121, 58,115,101,110,100, 40, 32, 84, 71, 87, 95, 75, 69, - 89, 44, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, 32,110,105,108, 44, 32, -110,105,108, 32, 41, 32, 32, 32, 45, 45, 32, 99,108,101, 97,114, 32,116,104,101, - 32,116,105,109,101,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114, -101,116,117,114,110, 32, 32, 45, 45, 32,110,111,116,104,105,110,103, 32,109,111, -114,101, 32,116,111, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 97, 61, 32,112,101,114,105,111,100, 10, 32, - 32, 32, 32,101,110,100, 10, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,119, 97, -107,101,117,112, 95, 97,116, 61, 32,116,121,112,101, 40, 97, 41, 61, 61, 34,116, - 97, 98,108,101, 34, 32, 97,110,100, 32,119, 97,107,101,117,112, 95, 99,111,110, -118, 40, 97, 41, 32, 32, 32, 32, 45, 45, 32,103,105,118,101,110, 32,112,111,105, -110,116, 32,111,102, 32,116,105,109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,111,114, 32,110,111,119, 95,115,101, 99, -115, 40, 41, 43, 97, 10, 32, 32, 32, 32, 45, 45, 32,113,117,101,117,101, 32,116, -111, 32,116,105,109,101,114, 10, 32, 32, 32, 32, 45, 45, 10, 32, 32, 32, 32,116, -105,109,101,114, 95,103, 97,116,101,119, 97,121, 58,115,101,110,100, 40, 32, 84, - 71, 87, 95, 75, 69, 89, 44, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, 32, -119, 97,107,101,117,112, 95, 97,116, 44, 32,112,101,114,105,111,100, 32, 41, 10, -101,110,100, 10, 10, 10, 45, 45, 45, 61, 61, 61, 32, 76,111, 99,107, 32, 38, 32, - 97,116,111,109,105, 99, 32,103,101,110,101,114, 97,116,111,114,115, 32, 61, 61, - 61, 45, 45, 45, 10, 10, 45, 45, 32, 84,104,101,115,101, 32,102,117,110, 99,116, -105,111,110,115, 32, 97,114,101, 32,106,117,115,116, 32,115,117,114,102, 97, 99, -101, 32,115,117,103, 97,114, 44, 32, 98,117,116, 32,109, 97,107,101, 32,115,111, -108,117,116,105,111,110,115, 32,101, 97,115,105,101,114, 32,116,111, 32,114,101, - 97,100, 46, 10, 45, 45, 32, 78,111,116, 32,109, 97,110,121, 32, 97,112,112,108, -105, 99, 97,116,105,111,110,115, 32,115,104,111,117,108,100, 32,101,118,101,110, - 32,110,101,101,100, 32,101,120,112,108,105, 99,105,116, 32,108,111, 99,107,115, - 32,111,114, 32, 97,116,111,109,105, 99, 32, 99,111,117,110,116,101,114,115, 46, - 10, 10, 45, 45, 10, 45, 45, 32,108,111, 99,107, 95,102, 61, 32,108, 97,110,101, -115, 46,103,101,110,108,111, 99,107, 40, 32,108,105,110,100, 97, 95,104, 44, 32, -107,101,121, 32, 91, 44, 78, 95,117,105,110,116, 61, 49, 93, 32, 41, 10, 45, 45, - 10, 45, 45, 32, 61, 32,108,111, 99,107, 95,102, 40, 32, 43, 77, 32, 41, 32, 32, - 32, 45, 45, 32, 97, 99,113,117,105,114,101, 32, 77, 10, 45, 45, 32, 32, 32, 32, - 32, 32, 46, 46, 46,108,111, 99,107,101,100, 46, 46, 46, 10, 45, 45, 32, 61, 32, -108,111, 99,107, 95,102, 40, 32, 45, 77, 32, 41, 32, 32, 32, 45, 45, 32,114,101, -108,101, 97,115,101, 32, 77, 10, 45, 45, 10, 45, 45, 32, 82,101,116,117,114,110, -115, 32, 97,110, 32, 97, 99, 99,101,115,115, 32,102,117,110, 99,116,105,111,110, - 32,116,104, 97,116, 32, 97,108,108,111,119,115, 32, 39, 78, 39, 32,115,105,109, -117,108,116, 97,110,101,111,117,115, 32,101,110,116,114,105,101,115, 32, 98,101, -116,119,101,101,110, 10, 45, 45, 32, 97, 99,113,117,105,114,101, 32, 40, 43, 77, - 41, 32, 97,110,100, 32,114,101,108,101, 97,115,101, 32, 40, 45, 77, 41, 46, 32, - 70,111,114, 32, 98,105,110, 97,114,121, 32,108,111, 99,107,115, 44, 32,117,115, -101, 32, 77, 61, 61, 49, 46, 10, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, -103,101,110,108,111, 99,107, 40, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, - 32, 78, 32, 41, 10, 32, 32, 32, 32,108,105,110,100, 97, 58,108,105,109,105,116, - 40,107,101,121, 44, 78, 41, 10, 32, 32, 32, 32,108,105,110,100, 97, 58,115,101, -116, 40,107,101,121, 44,110,105,108, 41, 32, 32, 45, 45, 32, 99,108,101, 97,114, -115, 32,101,120,105,115,116,105,110,103, 32,100, 97,116, 97, 10, 10, 32, 32, 32, - 32, 45, 45, 10, 32, 32, 32, 32, 45, 45, 32, 91,116,114,117,101, 32, 91, 44, 32, - 46, 46, 46, 93, 61, 32,116,114,117,101,115, 40,117,105,110,116, 41, 10, 32, 32, - 32, 32, 45, 45, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,117,110, 99,116, -105,111,110, 32,116,114,117,101,115, 40,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32,105,102, 32,110, 62, 48, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, -116,114,117,101, 44,116,114,117,101,115, 40,110, 45, 49, 41, 32,101,110,100, 10, - 32, 32, 32, 32,101,110,100, 10, 10, 32, 32, 32, 32,114,101,116,117,114,110, 10, - 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40, 77, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,105,102, 32, 77, 62, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 39,110,105,108, 39, 32,116,105,109, -101,111,117,116, 32, 97,108,108,111,119,115, 32, 39,107,101,121, 39, 32,116,111, - 32, 98,101, 32,110,117,109,101,114,105, 99, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,108,105,110,100, 97, 58,115,101,110,100, 40, 32,110,105,108, 44, - 32,107,101,121, 44, 32,116,114,117,101,115, 40, 77, 41, 32, 41, 32, 32, 32, 32, - 45, 45, 32,115,117,115,112,101,110,100,115, 32,117,110,116,105,108, 32, 98,101, -101,110, 32, 97, 98,108,101, 32,116,111, 32,112,117,115,104, 32,116,104,101,109, - 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,102,111,114, 32,105, 61, 49, 44, 45, 77, 32,100,111, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,100, - 97, 58,114,101, 99,101,105,118,101, 40, 32,107,101,121, 32, 41, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, - 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 10, 45, - 45, 10, 45, 45, 32, 97,116,111,109,105, 99, 95,102, 61, 32,108, 97,110,101,115, - 46,103,101,110, 97,116,111,109,105, 99, 40, 32,108,105,110,100, 97, 95,104, 44, - 32,107,101,121, 32, 91, 44,105,110,105,116,105, 97,108, 95,110,117,109, 61, 48, - 46, 48, 93, 32, 41, 10, 45, 45, 10, 45, 45, 32,105,110,116, 61, 32, 97,116,111, -109,105, 99, 95,102, 40, 32, 91,100,105,102,102, 95,110,117,109, 61, 49, 46, 48, - 93, 32, 41, 10, 45, 45, 10, 45, 45, 32, 82,101,116,117,114,110,115, 32, 97,110, - 32, 97, 99, 99,101,115,115, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97, -116, 32, 97,108,108,111,119,115, 32, 97,116,111,109,105, 99, 32,105,110, 99,114, -101,109,101,110,116, 47,100,101, 99,114,101,109,101,110,116, 32,111,102, 32,116, -104,101, 10, 45, 45, 32,110,117,109, 98,101,114, 32,105,110, 32, 39,107,101,121, - 39, 46, 10, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,103,101,110, 97,116, -111,109,105, 99, 40, 32,108,105,110,100, 97, 44, 32,107,101,121, 44, 32,105,110, -105,116,105, 97,108, 95,118, 97,108, 32, 41, 10, 32, 32, 32, 32,108,105,110,100, - 97, 58,108,105,109,105,116, 40,107,101,121, 44, 50, 41, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32,118, 97,108,117,101, 32, 91, 44,116,114,117,101, 93, - 10, 32, 32, 32, 32,108,105,110,100, 97, 58,115,101,116, 40,107,101,121, 44,105, -110,105,116,105, 97,108, 95,118, 97,108, 32,111,114, 32, 48, 46, 48, 41, 32, 32, - 32, 45, 45, 32, 99,108,101, 97,114,115, 32,101,120,105,115,116,105,110,103, 32, -100, 97,116, 97, 32, 40, 97,108,115,111, 32,113,117,101,117,101, 41, 10, 10, 32, - 32, 32, 32,114,101,116,117,114,110, 10, 32, 32, 32, 32,102,117,110, 99,116,105, -111,110, 40,100,105,102,102, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, - 39,110,105,108, 39, 32, 97,108,108,111,119,115, 32, 39,107,101,121, 39, 32,116, -111, 32, 98,101, 32,110,117,109,101,114,105, 99, 10, 32, 32, 32, 32, 32, 32, 32, - 32,108,105,110,100, 97, 58,115,101,110,100, 40, 32,110,105,108, 44, 32,107,101, -121, 44, 32,116,114,117,101, 32, 41, 32, 32, 32, 32, 45, 45, 32,115,117,115,112, -101,110,100,115, 32,117,110,116,105,108, 32,111,117,114, 32, 39,116,114,117,101, - 39, 32,105,115, 32,105,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97, -108, 32,118, 97,108, 61, 32,108,105,110,100, 97, 58,103,101,116, 40,107,101,121, - 41, 32, 43, 32, 40,100,105,102,102, 32,111,114, 32, 49, 46, 48, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32,108,105,110,100, 97, 58,115,101,116, 40, 32,107,101,121, - 44, 32,118, 97,108, 32, 41, 32, 32, 32, 45, 45, 32,114,101,108,101, 97,115,101, -115, 32,116,104,101, 32,108,111, 99,107, 44, 32, 98,121, 32,101,109,112,116,121, -105,110,103, 32,113,117,101,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101, -116,117,114,110, 32,118, 97,108, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, - 10, 10, 10, 45, 45,116,104,101, 32,101,110,100, 10, -}; - - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"lanes.lua")==0) lua_call(L, 0, 0); -} diff --git a/src/libraries/lanes/lanes/threading.c b/src/libraries/lanes/lanes/threading.c deleted file mode 100644 index 68d1e41f2..000000000 --- a/src/libraries/lanes/lanes/threading.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * THREADING.C Copyright (c) 2007-08, Asko Kauppi - * - * Lua Lanes OS threading specific code. - * - * References: - * -*/ - -/* -=============================================================================== - -Copyright (C) 2007-08 Asko Kauppi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -=============================================================================== -*/ -#include -#include -#include -#include -#include - -#include "threading.h" -#include "lua.h" - -#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)) -# include -#endif - - -#if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) -# include -# include -#endif - -/* Linux needs to check, whether it's been run as root -*/ -#ifdef PLATFORM_LINUX - volatile bool_t sudo; -#endif - -#ifdef _MSC_VER -// ".. selected for automatic inline expansion" (/O2 option) -# pragma warning( disable : 4711 ) -// ".. type cast from function pointer ... to data pointer" -# pragma warning( disable : 4054 ) -#endif - -//#define THREAD_CREATE_RETRIES_MAX 20 - // loops (maybe retry forever?) - -/* -* FAIL is for unexpected API return values - essentially programming -* error in _this_ code. -*/ -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) -static void FAIL( const char *funcname, int rc ) { - fprintf( stderr, "%s() failed! (%d)\n", funcname, rc ); - abort(); -} -#endif - - -/* -* Returns millisecond timing (in seconds) for the current time. -* -* Note: This function should be called once in single-threaded mode in Win32, -* to get it initialized. -*/ -time_d now_secs(void) { - -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - /* - * Windows FILETIME values are "100-nanosecond intervals since - * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as - * the offset and it seems, so would they: - * - * - */ - SYSTEMTIME st; - FILETIME ft; - ULARGE_INTEGER uli; - static ULARGE_INTEGER uli_epoch; // Jan 1st 1970 0:0:0 - - if (uli_epoch.HighPart==0) { - st.wYear= 1970; - st.wMonth= 1; // Jan - st.wDay= 1; - st.wHour= st.wMinute= st.wSecond= st.wMilliseconds= 0; - - if (!SystemTimeToFileTime( &st, &ft )) - FAIL( "SystemTimeToFileTime", GetLastError() ); - - uli_epoch.LowPart= ft.dwLowDateTime; - uli_epoch.HighPart= ft.dwHighDateTime; - } - - GetSystemTime( &st ); // current system date/time in UTC - if (!SystemTimeToFileTime( &st, &ft )) - FAIL( "SystemTimeToFileTime", GetLastError() ); - - uli.LowPart= ft.dwLowDateTime; - uli.HighPart= ft.dwHighDateTime; - - /* 'double' has less accuracy than 64-bit int, but if it were to degrade, - * it would do so gracefully. In practise, the integer accuracy is not - * of the 100ns class but just 1ms (Windows XP). - */ -# if 1 - // >= 2.0.3 code - return (double) ((uli.QuadPart - uli_epoch.QuadPart)/10000) / 1000.0; -# elif 0 - // fix from Kriss Daniels, see: - // - // - // "seem to be getting negative numbers from the old version, probably number - // conversion clipping, this fixes it and maintains ms resolution" - // - // This was a bad fix, and caused timer test 5 sec timers to disappear. - // --AKa 25-Jan-2009 - // - return ((double)((signed)((uli.QuadPart/10000) - (uli_epoch.QuadPart/10000)))) / 1000.0; -# else - // <= 2.0.2 code - return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0; -# endif -#else - struct timeval tv; - // { - // time_t tv_sec; /* seconds since Jan. 1, 1970 */ - // suseconds_t tv_usec; /* and microseconds */ - // }; - - int rc= gettimeofday( &tv, NULL /*time zone not used any more (in Linux)*/ ); - assert( rc==0 ); - - return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0; -#endif -} - - -/* -*/ -time_d SIGNAL_TIMEOUT_PREPARE( double secs ) { - if (secs<=0.0) return secs; - else return now_secs() + secs; -} - - -#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)) -/* -* Prepare 'abs_secs' kind of timeout to 'timespec' format -*/ -static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { - assert(ts); - assert( abs_secs >= 0.0 ); - - if (abs_secs==0.0) - abs_secs= now_secs(); - - ts->tv_sec= floor( abs_secs ); - ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns -} -#endif - - -/*---=== Threading ===---*/ - -//--- -// It may be meaningful to explicitly limit the new threads' C stack size. -// We should know how much Lua needs in the C stack, all Lua side allocations -// are done in heap so they don't count. -// -// Consequence of _not_ limiting the stack is running out of virtual memory -// with 1000-5000 threads on 32-bit systems. -// -// Note: using external C modules may be affected by the stack size check. -// if having problems, set back to '0' (default stack size of the system). -// -// Win32: 64K (?) -// Win64: xxx -// -// Linux x86: 2MB Ubuntu 7.04 via 'pthread_getstacksize()' -// Linux x64: xxx -// Linux ARM: xxx -// -// OS X 10.4.9: 512K -// valid values N * 4KB -// -#ifndef _THREAD_STACK_SIZE -# if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PLATFORM_CYGWIN) -# define _THREAD_STACK_SIZE 0 - // Win32: does it work with less? -# elif (defined PLATFORM_OSX) -# define _THREAD_STACK_SIZE (524288/2) // 262144 - // OS X: "make test" works on 65536 and even below - // "make perftest" works on >= 4*65536 == 262144 (not 3*65536) -# elif (defined PLATFORM_LINUX) && (defined __i386) -# define _THREAD_STACK_SIZE (2097152/16) // 131072 - // Linux x86 (Ubuntu 7.04): "make perftest" works on /16 (not on /32) -# elif (defined PLATFORM_BSD) && (defined __i386) -# define _THREAD_STACK_SIZE (1048576/8) // 131072 - // FreeBSD 6.2 SMP i386: ("gmake perftest" works on /8 (not on /16) -# endif -#endif - -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - // - void MUTEX_INIT( MUTEX_T *ref ) { - *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); - if (!ref) FAIL( "CreateMutex", GetLastError() ); - } - void MUTEX_FREE( MUTEX_T *ref ) { - if (!CloseHandle(*ref)) FAIL( "CloseHandle (mutex)", GetLastError() ); - *ref= NULL; - } - void MUTEX_LOCK( MUTEX_T *ref ) { - DWORD rc= WaitForSingleObject(*ref,INFINITE); - if (rc!=0) FAIL( "WaitForSingleObject", rc==WAIT_FAILED ? GetLastError() : rc ); - } - void MUTEX_UNLOCK( MUTEX_T *ref ) { - if (!ReleaseMutex(*ref)) - FAIL( "ReleaseMutex", GetLastError() ); - } - /* MSDN: "If you would like to use the CRT in ThreadProc, use the - _beginthreadex function instead (of CreateThread)." - MSDN: "you can create at most 2028 threads" - */ - void - THREAD_CREATE( THREAD_T *ref, - THREAD_RETURN_T (__stdcall *func)( void * ), - // Note: Visual C++ requires '__stdcall' where it is - void *data, int prio /* -3..+3 */ ) { - - HANDLE h= (HANDLE)_beginthreadex( NULL, // security - _THREAD_STACK_SIZE, - func, - data, - 0, // flags (0/CREATE_SUSPENDED) - NULL // thread id (not used) - ); - - if (h == INVALID_HANDLE_VALUE) FAIL( "CreateThread", GetLastError() ); - - if (prio!= 0) { - int win_prio= (prio == +3) ? THREAD_PRIORITY_TIME_CRITICAL : - (prio == +2) ? THREAD_PRIORITY_HIGHEST : - (prio == +1) ? THREAD_PRIORITY_ABOVE_NORMAL : - (prio == -1) ? THREAD_PRIORITY_BELOW_NORMAL : - (prio == -2) ? THREAD_PRIORITY_LOWEST : - THREAD_PRIORITY_IDLE; // -3 - - if (!SetThreadPriority( h, win_prio )) - FAIL( "SetThreadPriority", GetLastError() ); - } - *ref= h; - } - // - bool_t THREAD_WAIT( THREAD_T *ref, double secs ) { - long ms= (long)((secs*1000.0)+0.5); - - DWORD rc= WaitForSingleObject( *ref, ms<0 ? INFINITE:ms /*timeout*/ ); - // - // (WAIT_ABANDONED) - // WAIT_OBJECT_0 success (0) - // WAIT_TIMEOUT - // WAIT_FAILED more info via GetLastError() - - if (rc == WAIT_TIMEOUT) return FALSE; - if (rc != 0) FAIL( "WaitForSingleObject", rc ); - *ref= NULL; // thread no longer usable - return TRUE; - } - // - void THREAD_KILL( THREAD_T *ref ) { - if (!TerminateThread( *ref, 0 )) FAIL("TerminateThread", GetLastError()); - *ref= NULL; - } - // - void SIGNAL_INIT( SIGNAL_T *ref ) { - // 'manual reset' event type selected, to be able to wake up all the - // waiting threads. - // - HANDLE h= CreateEvent( NULL, // security attributes - TRUE, // TRUE: manual event - FALSE, // Initial state - NULL ); // name - - if (h == NULL) FAIL( "CreateEvent", GetLastError() ); - *ref= h; - } - void SIGNAL_FREE( SIGNAL_T *ref ) { - if (!CloseHandle(*ref)) FAIL( "CloseHandle (event)", GetLastError() ); - *ref= NULL; - } - // - bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs ) { - DWORD rc; - long ms; - - if (abs_secs<0.0) - ms= INFINITE; - else if (abs_secs==0.0) - ms= 0; - else { - ms= (long) ((abs_secs - now_secs())*1000.0 + 0.5); - - // If the time already passed, still try once (ms==0). A short timeout - // may have turned negative or 0 because of the two time samples done. - // - if (ms<0) ms= 0; - } - - // Unlock and start a wait, atomically (like condition variables do) - // - rc= SignalObjectAndWait( *mu_ref, // "object to signal" (unlock) - *ref, // "object to wait on" - ms, - FALSE ); // not alertable - - // All waiting locks are woken here; each competes for the lock in turn. - // - // Note: We must get the lock even if we've timed out; it makes upper - // level code equivalent to how PThread does it. - // - MUTEX_LOCK(mu_ref); - - if (rc==WAIT_TIMEOUT) return FALSE; - if (rc!=0) FAIL( "SignalObjectAndWait", rc ); - return TRUE; - } - void SIGNAL_ALL( SIGNAL_T *ref ) { -/* - * MSDN tries to scare that 'PulseEvent' is bad, unreliable and should not be - * used. Use condition variables instead (wow, they have that!?!); which will - * ONLY WORK on Vista and 2008 Server, it seems... so MS, isn't it. - * - * I refuse to believe that; using 'PulseEvent' is probably just as good as - * using Windows (XP) in the first place. Just don't use APC's (asynchronous - * process calls) in your C side coding. - */ - // PulseEvent on manual event: - // - // Release ALL threads waiting for it (and go instantly back to unsignalled - // status = future threads to start a wait will wait) - // - if (!PulseEvent( *ref )) - FAIL( "PulseEvent", GetLastError() ); - } -#else - // PThread (Linux, OS X, ...) - // - // On OS X, user processes seem to be able to change priorities. - // On Linux, SCHED_RR and su privileges are required.. !-( - // - #include - #include - // - static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) { - const char *why= (rc==EINVAL) ? "EINVAL" : - (rc==EBUSY) ? "EBUSY" : - (rc==EPERM) ? "EPERM" : - (rc==ENOMEM) ? "ENOMEM" : - (rc==ESRCH) ? "ESRCH" : - //... - ""; - fprintf( stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why ); - abort(); - } - #define PT_CALL( call ) { int rc= call; if (rc!=0) _PT_FAIL( rc, #call, __FILE__, __LINE__ ); } - // - void SIGNAL_INIT( SIGNAL_T *ref ) { - PT_CALL( pthread_cond_init(ref,NULL /*attr*/) ); - } - void SIGNAL_FREE( SIGNAL_T *ref ) { - PT_CALL( pthread_cond_destroy(ref) ); - } - // - /* - * Timeout is given as absolute since we may have fake wakeups during - * a timed out sleep. A Linda with some other key read, or just because - * PThread cond vars can wake up unwantedly. - */ - bool_t SIGNAL_WAIT( SIGNAL_T *ref, pthread_mutex_t *mu, time_d abs_secs ) { - if (abs_secs<0.0) { - PT_CALL( pthread_cond_wait( ref, mu ) ); // infinite - } else { - int rc; - struct timespec ts; - - assert( abs_secs != 0.0 ); - prepare_timeout( &ts, abs_secs ); - - rc= pthread_cond_timedwait( ref, mu, &ts ); - - if (rc==ETIMEDOUT) return FALSE; - if (rc) { _PT_FAIL( rc, "pthread_cond_timedwait()", __FILE__, __LINE__ ); } - } - return TRUE; - } - // - void SIGNAL_ONE( SIGNAL_T *ref ) { - PT_CALL( pthread_cond_signal(ref) ); // wake up ONE (or no) waiting thread - } - // - void SIGNAL_ALL( SIGNAL_T *ref ) { - PT_CALL( pthread_cond_broadcast(ref) ); // wake up ALL waiting threads - } - // - void THREAD_CREATE( THREAD_T* ref, - THREAD_RETURN_T (*func)( void * ), - void *data, int prio /* -2..+2 */ ) { - pthread_attr_t _a; - pthread_attr_t *a= &_a; - struct sched_param sp; - - PT_CALL( pthread_attr_init(a) ); - -#ifndef PTHREAD_TIMEDJOIN - // We create a NON-JOINABLE thread. This is mainly due to the lack of - // 'pthread_timedjoin()', but does offer other benefits (s.a. earlier - // freeing of the thread's resources). - // - PT_CALL( pthread_attr_setdetachstate(a,PTHREAD_CREATE_DETACHED) ); -#endif - - // Use this to find a system's default stack size (DEBUG) -#if 0 - { size_t n; pthread_attr_getstacksize( a, &n ); - fprintf( stderr, "Getstack: %u\n", (unsigned int)n ); } - // 524288 on OS X - // 2097152 on Linux x86 (Ubuntu 7.04) - // 1048576 on FreeBSD 6.2 SMP i386 -#endif - -#if (defined _THREAD_STACK_SIZE) && (_THREAD_STACK_SIZE > 0) - PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) ); -#endif - - bool_t normal= -#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) - !sudo; // with sudo, even normal thread must use SCHED_RR -#else - prio == 0; // create a default thread if -#endif - if (!normal) { - // NB: PThreads priority handling is about as twisty as one can get it - // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!! - - // "The specified scheduling parameters are only used if the scheduling - // parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED." - // - PT_CALL( pthread_attr_setinheritsched( a, PTHREAD_EXPLICIT_SCHED ) ); - - //--- - // "Select the scheduling policy for the thread: one of SCHED_OTHER - // (regular, non-real-time scheduling), SCHED_RR (real-time, - // round-robin) or SCHED_FIFO (real-time, first-in first-out)." - // - // "Using the RR policy ensures that all threads having the same - // priority level will be scheduled equally, regardless of their activity." - // - // "For SCHED_FIFO and SCHED_RR, the only required member of the - // sched_param structure is the priority sched_priority. For SCHED_OTHER, - // the affected scheduling parameters are implementation-defined." - // - // "The priority of a thread is specified as a delta which is added to - // the priority of the process." - // - // ".. priority is an integer value, in the range from 1 to 127. - // 1 is the least-favored priority, 127 is the most-favored." - // - // "Priority level 0 cannot be used: it is reserved for the system." - // - // "When you use specify a priority of -99 in a call to - // pthread_setschedparam(), the priority of the target thread is - // lowered to the lowest possible value." - // - // ... - - // ** CONCLUSION ** - // - // PThread priorities are _hugely_ system specific, and we need at - // least OS specific settings. Hopefully, Linuxes and OS X versions - // are uniform enough, among each other... - // -#ifdef PLATFORM_OSX - // AK 10-Apr-07 (OS X PowerPC 10.4.9): - // - // With SCHED_RR, 26 seems to be the "normal" priority, where setting - // it does not seem to affect the order of threads processed. - // - // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26, - // but the difference is not so clear with OTHER). - // - // 'sched_get_priority_min()' and '..max()' give 15, 47 as the - // priority limits. This could imply, user mode applications won't - // be able to use values outside of that range. - // - #define _PRIO_MODE SCHED_OTHER - - // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope - //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS - - #define _PRIO_HI 32 // seems to work (_carefully_ picked!) - #define _PRIO_0 26 // detected - #define _PRIO_LO 1 // seems to work (tested) - -#elif defined(PLATFORM_LINUX) - // (based on Ubuntu Linux 2.6.15 kernel) - // - // SCHED_OTHER is the default policy, but does not allow for priorities. - // SCHED_RR allows priorities, all of which (1..99) are higher than - // a thread with SCHED_OTHER policy. - // - // - // - // - // - // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, - // but even Ubuntu does not seem to define it. - // - #define _PRIO_MODE SCHED_RR - - // NTLP 2.5: only system scope allowed (being the basic reason why - // root privileges are required..) - //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS - - #define _PRIO_HI 99 - #define _PRIO_0 50 - #define _PRIO_LO 1 - -#elif defined(PLATFORM_BSD) - // - // - // - // "When control over the thread scheduling is desired, then FreeBSD - // with the libpthread implementation is by far the best choice .." - // - #define _PRIO_MODE SCHED_OTHER - #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS - #define _PRIO_HI 31 - #define _PRIO_0 15 - #define _PRIO_LO 1 - -#elif defined(PLATFORM_CYGWIN) - // - // TBD: Find right values for Cygwin - // -#else - #error "Unknown OS: not implemented!" -#endif - -#ifdef _PRIO_SCOPE - PT_CALL( pthread_attr_setscope( a, _PRIO_SCOPE ) ); -#endif - PT_CALL( pthread_attr_setschedpolicy( a, _PRIO_MODE ) ); - -#define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) ) -#define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) ) - - sp.sched_priority= - (prio == +2) ? _PRIO_HI : - (prio == +1) ? _PRIO_AN : -#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) - (prio == 0) ? _PRIO_0 : -#endif - (prio == -1) ? _PRIO_BN : _PRIO_LO; - - PT_CALL( pthread_attr_setschedparam( a, &sp ) ); - } - - //--- - // Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system - // thread limit (not userland thread). Actual limit for us is way higher. - // PTHREAD_THREADS_MAX is not defined (even though man page refers to it!) - // -# ifndef THREAD_CREATE_RETRIES_MAX - // Don't bother with retries; a failure is a failure - // - { - int rc= pthread_create( ref, a, func, data ); - if (rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__-1 ); - } -# else -# error "This code deprecated" -/* - // Wait slightly if thread creation has exchausted the system - // - { uint_t retries; - for( retries=0; retries=0.0) { -#else - if (secs>0.0) { -#endif - prepare_timeout( &ts_store, now_secs()+secs ); - timeout= &ts_store; - } - -#ifdef PTHREAD_TIMEDJOIN - /* Thread is joinable - */ - if (!timeout) { - PT_CALL( pthread_join( *ref, NULL /*ignore exit value*/ )); - done= TRUE; - } else { - int rc= PTHREAD_TIMEDJOIN( *ref, NULL, timeout ); - if ((rc!=0) && (rc!=ETIMEDOUT)) { - _PT_FAIL( rc, "PTHREAD_TIMEDJOIN", __FILE__, __LINE__-2 ); - } - done= rc==0; - } -#else - /* Since we've set the thread up as PTHREAD_CREATE_DETACHED, we cannot - * join with it. Use the cond.var. - */ - MUTEX_LOCK( mu_ref ); - - // 'secs'==0.0 does not need to wait, just take the current status - // within the 'mu_ref' locks - // - if (secs != 0.0) { - while( *st_ref < DONE ) { - if (!timeout) { - PT_CALL( pthread_cond_wait( signal_ref, mu_ref )); - } else { - int rc= pthread_cond_timedwait( signal_ref, mu_ref, timeout ); - if (rc==ETIMEDOUT) break; - if (rc!=0) _PT_FAIL( rc, "pthread_cond_timedwait", __FILE__, __LINE__-2 ); - } - } - } - done= *st_ref >= DONE; // DONE|ERROR_ST|CANCELLED - - MUTEX_UNLOCK( mu_ref ); -#endif - return done; - } - // - void THREAD_KILL( THREAD_T *ref ) { - pthread_cancel( *ref ); - } -#endif - -static const lua_Alloc alloc_f= 0; diff --git a/src/libraries/lanes/lanes/threading.h b/src/libraries/lanes/lanes/threading.h deleted file mode 100644 index 4a83229b6..000000000 --- a/src/libraries/lanes/lanes/threading.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -* THREADING.H -*/ -#ifndef THREADING_H -#define THREADING_H - -/* Platform detection -*/ -#ifdef _WIN32_WCE - #define PLATFORM_POCKETPC -#elif (defined _WIN32) - #define PLATFORM_WIN32 -#elif (defined __linux__) - #define PLATFORM_LINUX -#elif (defined __APPLE__) && (defined __MACH__) - #define PLATFORM_OSX -#elif (defined __NetBSD__) || (defined __FreeBSD__) || (defined BSD) - #define PLATFORM_BSD -#elif (defined __QNX__) - #define PLATFORM_QNX -#elif (defined __CYGWIN__) - #define PLATFORM_CYGWIN -#else - #error "Unknown platform!" -#endif - -typedef int bool_t; -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -typedef unsigned int uint_t; - -#if defined(PLATFORM_WIN32) && defined(__GNUC__) -/* MinGW with MSVCR80.DLL */ -/* Do this BEFORE including time.h so that it is declaring _mktime32() - * as it would have declared mktime(). - */ -# define mktime _mktime32 -#endif -#include - -/* Note: ERROR is a defined entity on Win32 -*/ -enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; - - -/*---=== Locks & Signals ===--- -*/ - -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - #define WIN32_LEAN_AND_MEAN - // 'SignalObjectAndWait' needs this (targets Windows 2000 and above) - #define _WIN32_WINNT 0x0400 - #include - #include - - // MSDN: http://msdn2.microsoft.com/en-us/library/ms684254.aspx - // - // CRITICAL_SECTION can be used for simple code protection. Mutexes are - // needed for use with the SIGNAL system. - // - #define MUTEX_T HANDLE - void MUTEX_INIT( MUTEX_T *ref ); - #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */ - void MUTEX_FREE( MUTEX_T *ref ); - void MUTEX_LOCK( MUTEX_T *ref ); - void MUTEX_UNLOCK( MUTEX_T *ref ); - - typedef unsigned THREAD_RETURN_T; - - #define SIGNAL_T HANDLE - - #define YIELD() Sleep(0) -#else - // PThread (Linux, OS X, ...) - // - #include - - #ifdef PLATFORM_LINUX - # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP - #else - /* OS X, ... */ - # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE - #endif - - #define MUTEX_T pthread_mutex_t - #define MUTEX_INIT(ref) pthread_mutex_init(ref,NULL) - #define MUTEX_RECURSIVE_INIT(ref) \ - { pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \ - pthread_mutexattr_settype( &a, _MUTEX_RECURSIVE ); \ - pthread_mutex_init(ref,&a); pthread_mutexattr_destroy( &a ); \ - } - #define MUTEX_FREE(ref) pthread_mutex_destroy(ref) - #define MUTEX_LOCK(ref) pthread_mutex_lock(ref) - #define MUTEX_UNLOCK(ref) pthread_mutex_unlock(ref) - - typedef void * THREAD_RETURN_T; - - typedef pthread_cond_t SIGNAL_T; - - void SIGNAL_ONE( SIGNAL_T *ref ); - - // Yield is non-portable: - // - // OS X 10.4.8/9 has pthread_yield_np() - // Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined - // FreeBSD 6.2 has pthread_yield() - // ... - // - #ifdef PLATFORM_OSX - #define YIELD() pthread_yield_np() - #else - #define YIELD() pthread_yield() - #endif -#endif - -void SIGNAL_INIT( SIGNAL_T *ref ); -void SIGNAL_FREE( SIGNAL_T *ref ); -void SIGNAL_ALL( SIGNAL_T *ref ); - -/* -* 'time_d': <0.0 for no timeout -* 0.0 for instant check -* >0.0 absolute timeout in secs + ms -*/ -typedef double time_d; -time_d now_secs(void); - -time_d SIGNAL_TIMEOUT_PREPARE( double rel_secs ); - -bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); - - -/*---=== Threading ===--- -*/ - -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) - - typedef HANDLE THREAD_T; - // - void THREAD_CREATE( THREAD_T *ref, - THREAD_RETURN_T (__stdcall *func)( void * ), - void *data, int prio /* -3..+3 */ ); - -# define THREAD_PRIO_MIN (-3) -# define THREAD_PRIO_MAX (+3) - -#else - /* Platforms that have a timed 'pthread_join()' can get away with a simpler - * implementation. Others will use a condition variable. - */ -# ifdef USE_PTHREAD_TIMEDJOIN -# ifdef PLATFORM_OSX -# error "No 'pthread_timedjoin()' on this system" -# else - /* Linux, ... */ -# define PTHREAD_TIMEDJOIN pthread_timedjoin_np -# endif -# endif - - typedef pthread_t THREAD_T; - - void THREAD_CREATE( THREAD_T *ref, - THREAD_RETURN_T (*func)( void * ), - void *data, int prio /* -2..+2 */ ); - -# if defined(PLATFORM_LINUX) - volatile bool_t sudo; -# ifdef LINUX_SCHED_RR -# define THREAD_PRIO_MIN (sudo ? -2 : 0) -# else -# define THREAD_PRIO_MIN (0) -# endif -# define THREAD_PRIO_MAX (sudo ? +2 : 0) -# else -# define THREAD_PRIO_MIN (-2) -# define THREAD_PRIO_MAX (+2) -# endif -#endif - -/* -* Win32 and PTHREAD_TIMEDJOIN allow waiting for a thread with a timeout. -* Posix without PTHREAD_TIMEDJOIN needs to use a condition variable approach. -*/ -#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN) - bool_t THREAD_WAIT( THREAD_T *ref, double secs ); -#else - bool_t THREAD_WAIT( THREAD_T *ref, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref, double secs ); -#endif - -void THREAD_KILL( THREAD_T *ref ); - -#endif - // THREADING_H diff --git a/src/libraries/lanes/lanes/tools.c b/src/libraries/lanes/lanes/tools.c deleted file mode 100644 index a2ec5179c..000000000 --- a/src/libraries/lanes/lanes/tools.c +++ /dev/null @@ -1,1198 +0,0 @@ -/* - * TOOLS.C Copyright (c) 2002-08, Asko Kauppi - * - * Lua tools to support Lanes. -*/ - -/* -=============================================================================== - -Copyright (C) 2002-08 Asko Kauppi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -=============================================================================== -*/ - -#include "tools.h" - -#include "lualib.h" -#include "lauxlib.h" - -#include -#include -#include -#include - -static volatile lua_CFunction hijacked_tostring; // = NULL - -MUTEX_T deep_lock; -MUTEX_T mtid_lock; - -/*---=== luaG_dump ===---*/ - -void luaG_dump( lua_State* L ) { - - int top= lua_gettop(L); - int i; - - fprintf( stderr, "\n\tDEBUG STACK:\n" ); - - if (top==0) - fprintf( stderr, "\t(none)\n" ); - - for( i=1; i<=top; i++ ) { - int type= lua_type( L, i ); - - fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename(L,type) ); - - // Print item contents here... - // - // Note: this requires 'tostring()' to be defined. If it is NOT, - // enable it for more debugging. - // - STACK_CHECK(L) - STACK_GROW( L, 2 ) - - lua_getglobal( L, "tostring" ); - // - // [-1]: tostring function, or nil - - if (!lua_isfunction(L,-1)) { - fprintf( stderr, "('tostring' not available)" ); - } else { - lua_pushvalue( L, i ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - - // Don't trust the string contents - // - fprintf( stderr, "%s", lua_tostring(L,-1) ); - } - lua_pop(L,1); - STACK_END(L,0) - fprintf( stderr, "\n" ); - } - fprintf( stderr, "\n" ); -} - - -/*---=== luaG_openlibs ===---*/ - -static const luaL_Reg libs[] = { - { LUA_LOADLIBNAME, luaopen_package }, - { LUA_TABLIBNAME, luaopen_table }, - { LUA_IOLIBNAME, luaopen_io }, - { LUA_OSLIBNAME, luaopen_os }, - { LUA_STRLIBNAME, luaopen_string }, - { LUA_MATHLIBNAME, luaopen_math }, - { LUA_DBLIBNAME, luaopen_debug }, - // - { "base", NULL }, // ignore "base" (already acquired it) - { "coroutine", NULL }, // part of Lua 5.1 base package - { NULL, NULL } -}; - -static bool_t openlib( lua_State *L, const char *name, size_t len ) { - - unsigned i; - bool_t all= strncmp( name, "*", len ) == 0; - - for( i=0; libs[i].name; i++ ) { - if (all || (strncmp(name, libs[i].name, len) ==0)) { - if (libs[i].func) { - STACK_GROW(L,2); - lua_pushcfunction( L, libs[i].func ); - lua_pushstring( L, libs[i].name ); - lua_call( L, 1, 0 ); - } - if (!all) return TRUE; - } - } - return all; -} - -/* -* Like 'luaL_openlibs()' but allows the set of libraries be selected -* -* NULL no libraries, not even base -* "" base library only -* "io,string" named libraries -* "*" all libraries -* -* Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. -* -* Returns NULL for ok, position of error within 'libs' on failure. -*/ -#define is_name_char(c) (isalpha(c) || (c)=='*') - -const char *luaG_openlibs( lua_State *L, const char *libs ) { - const char *p; - unsigned len; - - if (!libs) return NULL; // no libs, not even 'base' - - // 'lua.c' stops GC during initialization so perhaps its a good idea. :) - // - lua_gc(L, LUA_GCSTOP, 0); - - // Anything causes 'base' to be taken in - // - STACK_GROW(L,2); - lua_pushcfunction( L, luaopen_base ); - lua_pushliteral( L, "" ); - lua_call( L, 1, 0 ); - - for( p= libs; *p; p+=len ) { - len=0; - while (*p && !is_name_char(*p)) p++; // bypass delimiters - while (is_name_char(p[len])) len++; // bypass name - if (len && (!openlib( L, p, len ))) - break; - } - lua_gc(L, LUA_GCRESTART, 0); - - return *p ? p : NULL; -} - - - -/*---=== Deep userdata ===---*/ - -/* The deep portion must be allocated separately of any Lua state's; it's -* lifespan may be longer than that of the creating state. -*/ -#define DEEP_MALLOC malloc -#define DEEP_FREE free - -/* -* 'registry[REGKEY]' is a two-way lookup table for 'idfunc's and those type's -* metatables: -* -* metatable -> idfunc -* idfunc -> metatable -*/ -#define DEEP_LOOKUP_KEY ((void*)set_deep_lookup) - // any unique light userdata - -static void push_registry_subtable( lua_State *L, void *token ); - -/* -* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. -* Pops the both values off the stack. -*/ -void set_deep_lookup( lua_State *L ) { - - STACK_GROW(L,3); - - STACK_CHECK(L) -#if 1 - push_registry_subtable( L, DEEP_LOOKUP_KEY ); -#else - /* ..to be removed.. */ - lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); - lua_rawget( L, LUA_REGISTRYINDEX ); - - if (lua_isnil(L,-1)) { - // First time here; let's make the lookup - // - lua_pop(L,1); - - lua_newtable(L); - lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); - lua_pushvalue(L,-2); - // - // [-3]: {} (2nd ref) - // [-2]: DEEP_LOOKUP_KEY - // [-1]: {} - - lua_rawset( L, LUA_REGISTRYINDEX ); - // - // [-1]: lookup table (empty) - } -#endif - STACK_MID(L,1) - - lua_insert(L,-3); - - // [-3]: lookup table - // [-2]: A - // [-1]: B - - lua_pushvalue( L,-1 ); // B - lua_pushvalue( L,-3 ); // A - lua_rawset( L, -5 ); // B->A - lua_rawset( L, -3 ); // A->B - lua_pop( L,1 ); - - STACK_END(L,-2) -} - -/* -* Pops the key (metatable or idfunc) off the stack, and replaces with the -* deep lookup value (idfunc/metatable/nil). -*/ -void get_deep_lookup( lua_State *L ) { - - STACK_GROW(L,1); - - STACK_CHECK(L) - lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); - lua_rawget( L, LUA_REGISTRYINDEX ); - - if (!lua_isnil(L,-1)) { - // [-2]: key (metatable or idfunc) - // [-1]: lookup table - - lua_insert( L, -2 ); - lua_rawget( L, -2 ); - - // [-2]: lookup table - // [-1]: value (metatable / idfunc / nil) - } - lua_remove(L,-2); - // remove lookup, or unused key - STACK_END(L,0) -} - -/* -* Return the registered ID function for 'index' (deep userdata proxy), -* or NULL if 'index' is not a deep userdata proxy. -*/ -static -lua_CFunction get_idfunc( lua_State *L, int index ) { - lua_CFunction ret; - - index= STACK_ABS(L,index); - - STACK_GROW(L,1); - - STACK_CHECK(L) - if (!lua_getmetatable( L, index )) - return NULL; // no metatable - - // [-1]: metatable of [index] - - get_deep_lookup(L); - // - // [-1]: idfunc/nil - - ret= lua_tocfunction(L,-1); - lua_pop(L,1); - STACK_END(L,0) - return ret; -} - - -/* -* void= mt.__gc( proxy_ud ) -* -* End of life for a proxy object; reduce the deep reference count and clean -* it up if reaches 0. -*/ -static -int deep_userdata_gc( lua_State *L ) { - DEEP_PRELUDE **proxy= (DEEP_PRELUDE**)lua_touserdata( L, 1 ); - DEEP_PRELUDE *p= *proxy; - int v; - - *proxy= 0; // make sure we don't use it any more - - MUTEX_LOCK( &deep_lock ); - v= --(p->refcount); - MUTEX_UNLOCK( &deep_lock ); - - if (v==0) { - int pushed; - - // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup - // - lua_CFunction idfunc= get_idfunc(L,1); - ASSERT_L(idfunc); - - lua_settop(L,0); // clean stack so we can call 'idfunc' directly - - // void= idfunc( "delete", lightuserdata ) - // - lua_pushliteral( L, "delete" ); - lua_pushlightuserdata( L, p->deep ); - pushed= idfunc(L); - - if (pushed) - luaL_error( L, "Bad idfunc on \"delete\": returned something" ); - - DEEP_FREE( (void*)p ); - } - return 0; -} - - -/* -* Push a proxy userdata on the stack. -* -* Initializes necessary structures if it's the first time 'idfunc' is being -* used in this Lua state (metatable, registring it). Otherwise, increments the -* reference count. -*/ -void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *prelude ) { - DEEP_PRELUDE **proxy; - - MUTEX_LOCK( &deep_lock ); - ++(prelude->refcount); // one more proxy pointing to this deep data - MUTEX_UNLOCK( &deep_lock ); - - STACK_GROW(L,4); - - STACK_CHECK(L) - - proxy= lua_newuserdata( L, sizeof( DEEP_PRELUDE* ) ); - ASSERT_L(proxy); - *proxy= prelude; - - // Get/create metatable for 'idfunc' (in this state) - // - lua_pushcfunction( L, idfunc ); // key - get_deep_lookup(L); - // - // [-2]: proxy - // [-1]: metatable / nil - - if (lua_isnil(L,-1)) { - // No metatable yet; make one and register it - // - lua_pop(L,1); - - // tbl= idfunc( "metatable" ) - // - lua_pushcfunction( L, idfunc ); - lua_pushliteral( L, "metatable" ); - lua_call( L, 1 /*args*/, 1 /*results*/ ); - // - // [-2]: proxy - // [-1]: metatable (returned by 'idfunc') - - if (!lua_istable(L,-1)) - luaL_error( L, "Bad idfunc on \"metatable\": did not return one" ); - - // Add '__gc' method - // - lua_pushcfunction( L, deep_userdata_gc ); - lua_setfield( L, -2, "__gc" ); - - // Memorize for later rounds - // - lua_pushvalue( L,-1 ); - lua_pushcfunction( L, idfunc ); - // - // [-4]: proxy - // [-3]: metatable (2nd ref) - // [-2]: metatable - // [-1]: idfunc - - set_deep_lookup(L); - } - STACK_MID(L,2) - ASSERT_L( lua_isuserdata(L,-2) ); - ASSERT_L( lua_istable(L,-1) ); - - // [-2]: proxy userdata - // [-1]: metatable to use - - lua_setmetatable( L, -2 ); - - STACK_END(L,1) - // [-1]: proxy userdata -} - - -/* -* Create a deep userdata -* -* proxy_ud= deep_userdata( idfunc [, ...] ) -* -* Creates a deep userdata entry of the type defined by 'idfunc'. -* Other parameters are passed on to the 'idfunc' "new" invocation. -* -* 'idfunc' must fulfill the following features: -* -* lightuserdata= idfunc( "new" [, ...] ) -- creates a new deep data instance -* void= idfunc( "delete", lightuserdata ) -- releases a deep data instance -* tbl= idfunc( "metatable" ) -- gives metatable for userdata proxies -* -* Reference counting and true userdata proxying are taken care of for the -* actual data type. -* -* Types using the deep userdata system (and only those!) can be passed between -* separate Lua states via 'luaG_inter_move()'. -* -* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' -*/ -int luaG_deep_userdata( lua_State *L ) { - lua_CFunction idfunc= lua_tocfunction( L,1 ); - int pushed; - - DEEP_PRELUDE *prelude= DEEP_MALLOC( sizeof(DEEP_PRELUDE) ); - ASSERT_L(prelude); - - prelude->refcount= 0; // 'luaG_push_proxy' will lift it to 1 - - STACK_GROW(L,1); - STACK_CHECK(L) - - // Replace 'idfunc' with "new" in the stack (keep possible other params) - // - lua_remove(L,1); - lua_pushliteral( L, "new" ); - lua_insert(L,1); - - // lightuserdata= idfunc( "new" [, ...] ) - // - pushed= idfunc(L); - - if ((pushed!=1) || lua_type(L,-1) != LUA_TLIGHTUSERDATA) - luaL_error( L, "Bad idfunc on \"new\": did not return light userdata" ); - - prelude->deep= lua_touserdata(L,-1); - ASSERT_L(prelude->deep); - - lua_pop(L,1); // pop deep data - - luaG_push_proxy( L, idfunc, prelude ); - // - // [-1]: proxy userdata - - STACK_END(L,1) - return 1; -} - - -/* -* Access deep userdata through a proxy. -* -* Reference count is not changed, and access to the deep userdata is not -* serialized. It is the module's responsibility to prevent conflicting usage. -*/ -void *luaG_todeep( lua_State *L, lua_CFunction idfunc, int index ) { - DEEP_PRELUDE **proxy; - - STACK_CHECK(L) - if (get_idfunc(L,index) != idfunc) - return NULL; // no metatable, or wrong kind - - proxy= (DEEP_PRELUDE**)lua_touserdata( L, index ); - STACK_END(L,0) - - return (*proxy)->deep; -} - - -/* -* Copy deep userdata between two separate Lua states. -* -* Returns: -* the id function of the copied value, or NULL for non-deep userdata -* (not copied) -*/ -static -lua_CFunction luaG_copydeep( lua_State *L, lua_State *L2, int index ) { - DEEP_PRELUDE **proxy; - DEEP_PRELUDE *p; - - lua_CFunction idfunc; - - idfunc= get_idfunc( L, index ); - if (!idfunc) return NULL; // not a deep userdata - - // Increment reference count - // - proxy= (DEEP_PRELUDE**)lua_touserdata( L, index ); - p= *proxy; - - luaG_push_proxy( L2, idfunc, p ); - // - // L2 [-1]: proxy userdata - - return idfunc; -} - - - -/*---=== Inter-state copying ===---*/ - -/*-- Metatable copying --*/ - -/* - * 'reg[ REG_MT_KNOWN ]'= { - * [ table ]= id_uint, - * ... - * [ id_uint ]= table, - * ... - * } - */ - -/* -* Push a registry subtable (keyed by unique 'token') onto the stack. -* If the subtable does not exist, it is created and chained. -*/ -static -void push_registry_subtable( lua_State *L, void *token ) { - - STACK_GROW(L,3); - - STACK_CHECK(L) - - lua_pushlightuserdata( L, token ); - lua_rawget( L, LUA_REGISTRYINDEX ); - // - // [-1]: nil/subtable - - if (lua_isnil(L,-1)) { - lua_pop(L,1); - lua_newtable(L); // value - lua_pushlightuserdata( L, token ); // key - lua_pushvalue(L,-2); - // - // [-3]: value (2nd ref) - // [-2]: key - // [-1]: value - - lua_rawset( L, LUA_REGISTRYINDEX ); - } - STACK_END(L,1) - - ASSERT_L( lua_istable(L,-1) ); -} - -#define REG_MTID ( (void*) get_mt_id ) - -/* -* Get a unique ID for metatable at [i]. -*/ -static -uint_t get_mt_id( lua_State *L, int i ) { - static uint_t last_id= 0; - uint_t id; - - i= STACK_ABS(L,i); - - STACK_GROW(L,3); - - STACK_CHECK(L) - push_registry_subtable( L, REG_MTID ); - lua_pushvalue(L, i); - lua_rawget( L, -2 ); - // - // [-2]: reg[REG_MTID] - // [-1]: nil/uint - - id= lua_tointeger(L,-1); // 0 for nil - lua_pop(L,1); - STACK_MID(L,1) - - if (id==0) { - MUTEX_LOCK( &mtid_lock ); - id= ++last_id; - MUTEX_UNLOCK( &mtid_lock ); - - /* Create two-way references: id_uint <-> table - */ - lua_pushvalue(L,i); - lua_pushinteger(L,id); - lua_rawset( L, -3 ); - - lua_pushinteger(L,id); - lua_pushvalue(L,i); - lua_rawset( L, -3 ); - } - lua_pop(L,1); // remove 'reg[REG_MTID]' reference - - STACK_END(L,0) - - return id; -} - - -static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) { - (void)L; - luaL_addlstring((luaL_Buffer*) B, (const char *)b, n); - return 0; -} - - -/* - * Check if we've already copied the same table from 'L', and - * reuse the old copy. This allows table upvalues shared by multiple - * local functions to point to the same table, also in the target. - * - * Always pushes a table to 'L2'. - * - * Returns TRUE if the table was cached (no need to fill it!); FALSE if - * it's a virgin. - */ -static -bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { - bool_t ret; - - ASSERT_L( hijacked_tostring ); - ASSERT_L( L2_cache_i != 0 ); - - STACK_GROW(L,2); - STACK_GROW(L2,3); - - // Create an identity string for table at [i]; it should stay unique at - // least during copying of the data (then we can clear the caches). - // - STACK_CHECK(L) - lua_pushcfunction( L, hijacked_tostring ); - lua_pushvalue( L, i ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - // - // [-1]: "table: 0x...." - - STACK_END(L,1) - ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); - - // L2_cache[id_str]= [{...}] - // - STACK_CHECK(L2) - - // We don't need to use the from state ('L') in ID since the life span - // is only for the duration of a copy (both states are locked). - // - lua_pushstring( L2, lua_tostring(L,-1) ); - lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) - -//fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); - - lua_pushvalue( L2, -1 ); - lua_rawget( L2, L2_cache_i ); - // - // [-2]: identity string ("table: 0x...") - // [-1]: table|nil - - if (lua_isnil(L2,-1)) { - lua_pop(L2,1); - lua_newtable(L2); - lua_pushvalue(L2,-1); - lua_insert(L2,-3); - // - // [-3]: new table (2nd ref) - // [-2]: identity string - // [-1]: new table - - lua_rawset(L2, L2_cache_i); - // - // [-1]: new table (tied to 'L2_cache' table') - - ret= FALSE; // brand new - - } else { - lua_remove(L2,-2); - ret= TRUE; // from cache - } - STACK_END(L2,1) - // - // L2 [-1]: table to use as destination - - ASSERT_L( lua_istable(L2,-1) ); - return ret; -} - - -/* - * Check if we've already copied the same function from 'L', and reuse the old - * copy. - * - * Always pushes a function to 'L2'. - */ -static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ); - -static -void push_cached_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { - // TBD: Merge this and same code for tables - - ASSERT_L( hijacked_tostring ); - ASSERT_L( L2_cache_i != 0 ); - - STACK_GROW(L,2); - STACK_GROW(L2,3); - - STACK_CHECK(L) - lua_pushcfunction( L, hijacked_tostring ); - lua_pushvalue( L, i ); - lua_call( L, 1 /*args*/, 1 /*retvals*/ ); - // - // [-1]: "function: 0x...." - - STACK_END(L,1) - ASSERT_L( lua_type(L,-1) == LUA_TSTRING ); - - // L2_cache[id_str]= function - // - STACK_CHECK(L2) - - // We don't need to use the from state ('L') in ID since the life span - // is only for the duration of a copy (both states are locked). - // - lua_pushstring( L2, lua_tostring(L,-1) ); - lua_pop(L,1); // remove the 'tostring(tbl)' value (in L!) - -//fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); - - lua_pushvalue( L2, -1 ); - lua_rawget( L2, L2_cache_i ); - // - // [-2]: identity string ("function: 0x...") - // [-1]: function|nil|true (true means: we're working on it; recursive) - - if (lua_isnil(L2,-1)) { - lua_pop(L2,1); - - // Set to 'true' for the duration of creation; need to find self-references - // via upvalues - // - lua_pushboolean(L2,TRUE); - lua_setfield( L2, L2_cache_i, lua_tostring(L2,-2) ); - - inter_copy_func( L2, L2_cache_i, L, i ); // pushes a copy of the func - - lua_pushvalue(L2,-1); - lua_insert(L2,-3); - // - // [-3]: function (2nd ref) - // [-2]: identity string - // [-1]: function - - lua_rawset(L2,L2_cache_i); - // - // [-1]: function (tied to 'L2_cache' table') - - } else if (lua_isboolean(L2,-1)) { - // Loop in preparing upvalues; either direct or via a table - // - // Note: This excludes the case where a function directly addresses - // itself as an upvalue (recursive lane creation). - // - luaL_error( L, "Recursive use of upvalues; cannot copy the function" ); - - } else { - lua_remove(L2,-2); - } - STACK_END(L2,1) - // - // L2 [-1]: function - - ASSERT_L( lua_isfunction(L2,-1) ); -} - - -/* -* Copy a function over, which has not been found in the cache. -*/ -enum e_vt { - VT_NORMAL, VT_KEY, VT_METATABLE -}; -static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt value_type ); - -static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { - - lua_CFunction cfunc= lua_tocfunction( L,i ); - unsigned n; - - ASSERT_L( L2_cache_i != 0 ); - - STACK_GROW(L,2); - - STACK_CHECK(L) - if (!cfunc) { // Lua function - luaL_Buffer b; - const char *s; - size_t sz; - int tmp; - const char *name= NULL; - -#if 0 - // "To get information about a function you push it onto the - // stack and start the what string with the character '>'." - // - { lua_Debug ar; - lua_pushvalue( L, i ); - lua_getinfo(L, ">n", &ar); // fills 'name' and 'namewhat', pops function - name= ar.namewhat; - - fprintf( stderr, "NAME: %s\n", name ); // just gives NULL - } -#endif - // 'lua_dump()' needs the function at top of stack - // - if (i!=-1) lua_pushvalue( L, i ); - - luaL_buffinit(L,&b); - tmp= lua_dump(L, buf_writer, &b); - ASSERT_L(tmp==0); - // - // "value returned is the error code returned by the last call - // to the writer" (and we only return 0) - - luaL_pushresult(&b); // pushes dumped string on 'L' - s= lua_tolstring(L,-1,&sz); - ASSERT_L( s && sz ); - - if (i!=-1) lua_remove( L, -2 ); - - // Note: Line numbers seem to be taken precisely from the - // original function. 'name' is not used since the chunk - // is precompiled (it seems...). - // - // TBD: Can we get the function's original name through, as well? - // - if (luaL_loadbuffer(L2, s, sz, name) != 0) { - // chunk is precompiled so only LUA_ERRMEM can happen - // "Otherwise, it pushes an error message" - // - STACK_GROW( L,1 ); - luaL_error( L, "%s", lua_tostring(L2,-1) ); - } - lua_pop(L,1); // remove the dumped string - STACK_MID(L,0) - } - - /* push over any upvalues; references to this function will come from - * cache so we don't end up in eternal loop. - */ - for( n=0; lua_getupvalue( L, i, 1+n ) != NULL; n++ ) { - if ((!cfunc) && lua_equal(L,i,-1)) { - /* Lua closure that has a (recursive) upvalue to itself - */ - lua_pushvalue( L2, -((int)n)-1 ); - } else { - if (!inter_copy_one_( L2, L2_cache_i, L, lua_gettop(L), VT_NORMAL )) - luaL_error( L, "Cannot copy upvalue type '%s'", luaG_typename(L,-1) ); - } - lua_pop(L,1); - } - // L2: function + 'n' upvalues (>=0) - - STACK_MID(L,0) - - if (cfunc) { - lua_pushcclosure( L2, cfunc, n ); // eats up upvalues - } else { - // Set upvalues (originally set to 'nil' by 'lua_load') - // - int func_index= lua_gettop(L2)-n; - - for( ; n>0; n-- ) { - const char *rc= lua_setupvalue( L2, func_index, n ); - // - // "assigns the value at the top of the stack to the upvalue and returns its name. - // It also pops the value from the stack." - - ASSERT_L(rc); // not having enough slots? - } - } - STACK_END(L,0) -} - - -/* -* Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove -* the original value. -* -* NOTE: Both the states must be solely in the current OS thread's posession. -* -* 'i' is an absolute index (no -1, ...) -* -* Returns TRUE if value was pushed, FALSE if its type is non-supported. -*/ -static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt vt ) -{ - bool_t ret= TRUE; - - STACK_GROW( L2, 1 ); - - STACK_CHECK(L2) - - switch ( lua_type(L,i) ) { - /* Basic types allowed both as values, and as table keys */ - - case LUA_TBOOLEAN: - lua_pushboolean( L2, lua_toboolean(L, i) ); - break; - - case LUA_TNUMBER: - /* LNUM patch support (keeping integer accuracy) */ -#ifdef LUA_LNUM - if (lua_isinteger(L,i)) { - lua_pushinteger( L2, lua_tointeger(L, i) ); - break; - } -#endif - lua_pushnumber( L2, lua_tonumber(L, i) ); - break; - - case LUA_TSTRING: { - size_t len; const char *s = lua_tolstring( L, i, &len ); - lua_pushlstring( L2, s, len ); - } break; - - case LUA_TLIGHTUSERDATA: - lua_pushlightuserdata( L2, lua_touserdata(L, i) ); - break; - - /* The following types are not allowed as table keys */ - - case LUA_TUSERDATA: if (vt==VT_KEY) { ret=FALSE; break; } - /* Allow only deep userdata entities to be copied across - */ - if (!luaG_copydeep( L, L2, i )) { - // Cannot copy it full; copy as light userdata - // - lua_pushlightuserdata( L2, lua_touserdata(L, i) ); - } break; - - case LUA_TNIL: if (vt==VT_KEY) { ret=FALSE; break; } - lua_pushnil(L2); - break; - - case LUA_TFUNCTION: if (vt==VT_KEY) { ret=FALSE; break; } { - /* - * Passing C functions is risky; if they refer to LUA_ENVIRONINDEX - * and/or LUA_REGISTRYINDEX they might work unintended (not work) - * at the target. - * - * On the other hand, NOT copying them causes many self tests not - * to work (timer, hangtest, ...) - * - * The trouble is, we cannot KNOW if the function at hand is safe - * or not. We cannot study it's behaviour. We could trust the user, - * but they might not even know they're sending lua_CFunction over - * (as upvalues etc.). - */ -#if 0 - if (lua_iscfunction(L,i)) - luaL_error( L, "Copying lua_CFunction between Lua states is risky, and currently disabled." ); -#endif - STACK_CHECK(L2) - push_cached_func( L2, L2_cache_i, L, i ); - ASSERT_L( lua_isfunction(L2,-1) ); - STACK_END(L2,1) - } break; - - case LUA_TTABLE: if (vt==VT_KEY) { ret=FALSE; break; } { - - STACK_CHECK(L) - STACK_CHECK(L2) - - /* Check if we've already copied the same table from 'L' (during this transmission), and - * reuse the old copy. This allows table upvalues shared by multiple - * local functions to point to the same table, also in the target. - * Also, this takes care of cyclic tables and multiple references - * to the same subtable. - * - * Note: Even metatables need to go through this test; to detect - * loops s.a. those in required module tables (getmetatable(lanes).lanes == lanes) - */ - if (push_cached_table( L2, L2_cache_i, L, i )) { - ASSERT_L( lua_istable(L2, -1) ); // from cache - break; - } - ASSERT_L( lua_istable(L2,-1) ); - - STACK_GROW( L, 2 ); - STACK_GROW( L2, 2 ); - - lua_pushnil(L); // start iteration - while( lua_next( L, i ) ) { - uint_t val_i= lua_gettop(L); - uint_t key_i= val_i-1; - - /* Only basic key types are copied over; others ignored - */ - if (inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY )) { - /* - * Contents of metatables are copied with cache checking; - * important to detect loops. - */ - if (inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL )) { - ASSERT_L( lua_istable(L2,-3) ); - lua_rawset( L2, -3 ); // add to table (pops key & val) - } else { - luaL_error( L, "Unable to copy over type '%s' (in %s)", - luaG_typename(L,val_i), - vt==VT_NORMAL ? "table":"metatable" ); - } - } - lua_pop( L, 1 ); // pop value (next round) - } - STACK_MID(L,0) - STACK_MID(L2,1) - - /* Metatables are expected to be immutable, and copied only once. - */ - if (lua_getmetatable( L, i )) { - // - // L [-1]: metatable - - uint_t mt_id= get_mt_id( L, -1 ); // Unique id for the metatable - - STACK_GROW(L2,4); - - push_registry_subtable( L2, REG_MTID ); - STACK_MID(L2,2); - lua_pushinteger( L2, mt_id ); - lua_rawget( L2, -2 ); - // - // L2 ([-3]: copied table) - // [-2]: reg[REG_MTID] - // [-1]: nil/metatable pre-known in L2 - - STACK_MID(L2,3); - - if (lua_isnil(L2,-1)) { /* L2 did not know the metatable */ - lua_pop(L2,1); - STACK_MID(L2,2); -ASSERT_L( lua_istable(L,-1) ); - if (inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE )) { - // - // L2 ([-3]: copied table) - // [-2]: reg[REG_MTID] - // [-1]: metatable (copied from L) - - STACK_MID(L2,3); - // mt_id -> metatable - // - lua_pushinteger(L2,mt_id); - lua_pushvalue(L2,-2); - lua_rawset(L2,-4); - - // metatable -> mt_id - // - lua_pushvalue(L2,-1); - lua_pushinteger(L2,mt_id); - lua_rawset(L2,-4); - - STACK_MID(L2,3); - } else { - luaL_error( L, "Error copying a metatable" ); - } - STACK_MID(L2,3); - } - // L2 ([-3]: copied table) - // [-2]: reg[REG_MTID] - // [-1]: metatable (pre-known or copied from L) - - lua_remove(L2,-2); // take away 'reg[REG_MTID]' - // - // L2: ([-2]: copied table) - // [-1]: metatable for that table - - lua_setmetatable( L2, -2 ); - - // L2: [-1]: copied table (with metatable set if source had it) - - lua_pop(L,1); // remove source metatable (L, not L2!) - } - STACK_END(L2,1) - STACK_END(L,0) - } break; - - /* The following types cannot be copied */ - - case LUA_TTHREAD: - ret=FALSE; break; - } - - STACK_END(L2, ret? 1:0) - - return ret; -} - - -/* -* Akin to 'lua_xmove' but copies values between _any_ Lua states. -* -* NOTE: Both the states must be solely in the current OS thread's posession. -* -* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'. -*/ -void luaG_inter_copy( lua_State* L, lua_State *L2, uint_t n ) -{ - uint_t top_L= lua_gettop(L); - uint_t top_L2= lua_gettop(L2); - uint_t i; - - /* steal Lua library's 'luaB_tostring()' from the first call. Other calls - * don't have to have access to it. - * - * Note: multiple threads won't come here at once; this function will - * be called before there can be multiple threads (no locking needed). - */ - if (!hijacked_tostring) { - STACK_GROW( L,1 ); - - STACK_CHECK(L) - lua_getglobal( L, "tostring" ); - // - // [-1]: function|nil - - hijacked_tostring= lua_tocfunction( L, -1 ); - lua_pop(L,1); - STACK_END(L,0) - - if (!hijacked_tostring) { - luaL_error( L, "Need to see 'tostring()' once" ); - } - } - - if (n > top_L) - luaL_error( L, "Not enough values: %d < %d", top_L, n ); - - STACK_GROW( L2, n+1 ); - - /* - * Make a cache table for the duration of this copy. Collects tables and - * function entries, avoiding the same entries to be passed on as multiple - * copies. ESSENTIAL i.e. for handling upvalue tables in the right manner! - */ - lua_newtable(L2); - - for (i=top_L-n+1; i <= top_L; i++) { - if (!inter_copy_one_( L2, top_L2+1, L, i, VT_NORMAL )) { - - luaL_error( L, "Cannot copy type: %s", luaG_typename(L,i) ); - } - } - - /* - * Remove the cache table. Persistant caching would cause i.e. multiple - * messages passed in the same table to use the same table also in receiving - * end. - */ - lua_remove( L2, top_L2+1 ); - - ASSERT_L( (uint_t)lua_gettop(L) == top_L ); - ASSERT_L( (uint_t)lua_gettop(L2) == top_L2+n ); -} - - -void luaG_inter_move( lua_State* L, lua_State *L2, uint_t n ) -{ - luaG_inter_copy( L, L2, n ); - lua_pop( L,(int)n ); -} diff --git a/src/libraries/lanes/lanes/tools.h b/src/libraries/lanes/lanes/tools.h deleted file mode 100644 index d155c65eb..000000000 --- a/src/libraries/lanes/lanes/tools.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* TOOLS.H -*/ -#ifndef TOOLS_H -#define TOOLS_H - -#include "lua.h" -#include "threading.h" - // MUTEX_T - -#include - -// Note: The < -10000 test is to leave registry/global/upvalue indices untouched -// -#define /*int*/ STACK_ABS(L,n) \ - ( ((n) >= 0 || (n) <= -10000) ? (n) : lua_gettop(L) +(n) +1 ) - -#ifdef NDEBUG - #define _ASSERT_L(lua,c) /*nothing*/ - #define STACK_CHECK(L) /*nothing*/ - #define STACK_MID(L,c) /*nothing*/ - #define STACK_END(L,c) /*nothing*/ - #define STACK_DUMP(L) /*nothing*/ - #define DEBUG() /*nothing*/ -#else - #define _ASSERT_L(lua,c) { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); } - // - #define STACK_CHECK(L) { int _oldtop_##L = lua_gettop(L); - #define STACK_MID(L,change) { int a= lua_gettop(L)-_oldtop_##L; int b= (change); \ - if (a != b) luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", a, b, __FILE__, __LINE__ ); } - #define STACK_END(L,change) STACK_MID(L,change) } - - #define STACK_DUMP(L) luaG_dump(L); - #define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ ); -#endif -#define ASSERT_L(c) _ASSERT_L(L,c) - -#define STACK_GROW(L,n) { if (!lua_checkstack(L,n)) luaL_error( L, "Cannot grow stack!" ); } - -#define LUAG_FUNC( func_name ) static int LG_##func_name( lua_State *L ) - -#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d)) -#define luaG_tounsigned(L,i) ((uint_t) lua_tointeger(L,i)) - -#define luaG_isany(L,i) (!lua_isnil(L,i)) - -#define luaG_typename( L, index ) lua_typename( L, lua_type(L,index) ) - -void luaG_dump( lua_State* L ); - -const char *luaG_openlibs( lua_State *L, const char *libs ); - -int luaG_deep_userdata( lua_State *L ); -void *luaG_todeep( lua_State *L, lua_CFunction idfunc, int index ); - -typedef struct { - volatile int refcount; - void *deep; -} DEEP_PRELUDE; - -void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *deep_userdata ); - -void luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n ); -void luaG_inter_move( lua_State *L, lua_State *L2, uint_t n ); - -// Lock for reference counter inc/dec locks (to be initialized by outside code) -// -extern MUTEX_T deep_lock; -extern MUTEX_T mtid_lock; - -#endif - // TOOLS_H diff --git a/src/love.cpp b/src/love.cpp index eeade9de5..53f62a627 100644 --- a/src/love.cpp +++ b/src/love.cpp @@ -55,7 +55,6 @@ // Libraries. #include "libraries/luasocket/luasocket.h" -#include "libraries/lanes/lanes.h" // Scripts #include "scripts/boot.lua.h" @@ -136,7 +135,6 @@ extern "C" LOVE_EXPORT int luaopen_love(lua_State * L) } love::luasocket::__open(L); - love::lanes::open(L); #endif // LOVE_BUILD_STANDALONE