Removed lanes.

This commit is contained in:
rude
2009-12-14 20:01:22 +01:00
parent c39242a24a
commit 735e4994e9
13 changed files with 0 additions and 6306 deletions
-92
View File
@@ -3909,98 +3909,6 @@
</File>
</Filter>
</Filter>
<Filter
Name="lanes"
>
<File
RelativePath="..\..\src\libraries\lanes\lanes.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\libraries\lanes\lanes.h"
>
</File>
<Filter
Name="lanes"
>
<File
RelativePath="..\..\src\libraries\lanes\lanes\lanes.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\libraries\lanes\lanes\threading.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\src\libraries\lanes\lanes\tools.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\libraries\lanes\lanes\"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="scripts"
-50
View File
@@ -1,50 +0,0 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "lanes.h"
// Lanes open function.
extern "C"
{
int luaopen_lanes( lua_State *L );
}
namespace love
{
namespace lanes
{
// Opens the lanes.lua file.
static int open_lanes(lua_State * L)
{
#include "lanes/lanes.lua.h"
lua_getglobal(L, "lanes");
return 1;
}
int open(lua_State * L)
{
luax_preload(L, open_lanes, "lanes");
luax_preload(L, luaopen_lanes, "lua51-lanes");
return 0;
}
} // lanes
} // love
-36
View File
@@ -1,36 +0,0 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_LANES_LANES_H
#define LOVE_LANES_LANES_H
// LOVE
#include <common/runtime.h>
namespace love
{
namespace lanes
{
int open(lua_State * L);
} // lanes
} // love
#endif // LOVE_LANES_LANES_H
-214
View File
@@ -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,};
-244
View File
@@ -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 <akauppi@gmail.com>
--
--[[
===============================================================================
Copyright (C) 2008 Asko Kauppi <akauppi@gmail.com>
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
File diff suppressed because it is too large Load Diff
-611
View File
@@ -1,611 +0,0 @@
--
-- LANES.LUA
--
-- Multithreading and -core support for Lua
--
-- Author: Asko Kauppi <akauppi@gmail.com>
--
-- 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 <akauppi@gmail.com>
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 <akauppi@gmail.com>",
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
File diff suppressed because it is too large Load Diff
-721
View File
@@ -1,721 +0,0 @@
/*
* THREADING.C Copyright (c) 2007-08, Asko Kauppi
*
* Lua Lanes OS threading specific code.
*
* References:
* <http://www.cse.wustl.edu/~schmidt/win32-cv-1.html>
*/
/*
===============================================================================
Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com>
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 <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include "threading.h"
#include "lua.h"
#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC))
# include <sys/time.h>
#endif
#if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN)
# include <sys/types.h>
# include <unistd.h>
#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:
*
* <http://msdn.microsoft.com/en-us/library/ms724928(VS.85).aspx>
*/
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:
// <http://luaforge.net/forum/forum.php?thread_id=22704&forum_id=1781>
//
// "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 <http://developer.apple.com/qa/qa2005/qa1419.html>
// 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 <errno.h>
#include <sys/time.h>
//
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.
//
// <http://kerneltrap.org/node/6080>
// <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
// <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
//
// 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)
//
// <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
//
// "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<THREAD_CREATE_RETRIES_MAX; retries++ ) {
int rc= pthread_create( ref, a, func, data );
//
// OS X / Linux:
// EAGAIN: ".. lacked the necessary resources to create
// another thread, or the system-imposed limit on the
// total number of threads in a process
// [PTHREAD_THREADS_MAX] would be exceeded."
// EINVAL: attr is invalid
// Linux:
// EPERM: no rights for given parameters or scheduling (no sudo)
// ENOMEM: (known to fail with this code, too - not listed in man)
if (rc==0) break; // ok!
// In practise, exhaustion seems to be coming from memory, not a
// maximum number of threads. Keep tuning... ;)
//
if (rc==EAGAIN) {
//fprintf( stderr, "Looping (retries=%d) ", retries ); // DEBUG
// Try again, later.
Yield();
} else {
_PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ );
}
}
}
*/
# endif
if (a) {
PT_CALL( pthread_attr_destroy(a) );
}
}
//
/*
* Wait for a thread to finish.
*
* 'mu_ref' is a lock we should use for the waiting; initially unlocked.
* Same lock as passed to THREAD_EXIT.
*
* Returns TRUE for succesful wait, FALSE for timed out
*/
#ifdef 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
{
struct timespec ts_store;
const struct timespec *timeout= NULL;
bool_t done;
// Do timeout counting before the locks
//
#ifdef PTHREAD_TIMEDJOIN
if (secs>=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;
-196
View File
@@ -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 <time.h>
/* 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 <windows.h>
#include <process.h>
// 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 <pthread.h>
#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
File diff suppressed because it is too large Load Diff
-72
View File
@@ -1,72 +0,0 @@
/*
* TOOLS.H
*/
#ifndef TOOLS_H
#define TOOLS_H
#include "lua.h"
#include "threading.h"
// MUTEX_T
#include <assert.h>
// 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
-2
View File
@@ -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