io.stdout:setvbuf'no' local ffi = require'ffi' local thread = require'thread' local pthread = require'pthread' local luastate = require'luastate' local time = require'time' local glue = require'glue' local function test_events() local event = thread.event() local t1 = thread.new(function(event) local time = require'time' while true do print'set' event:set() time.sleep(0.1) print'clear' event:clear() time.sleep(1) end end, event) local t2 = thread.new(function(event) local time = require'time' while true do event:wait() print'!' time.sleep(0.1) end end, event) t1:join() t2:join() end local function printtime(s, n, dt) print(string.format('time to create %4d %-10s: %.2fs %6d %s/s', n, s, dt, n/dt, s)) end local function test_pthread_creation() local state = luastate.open() state:openlibs() state:push(function() local ffi = require'ffi' local glue = require'glue' local function worker() end local worker_cb = ffi.cast('void *(*)(void *)', worker) return glue.addr(worker_cb) end) local worker_cb_ptr = glue.ptr(state:call()) local t0 = time.clock() local n = 1000 for i=1,n do local thread = pthread.new(worker_cb_ptr) thread:join() end local dt = time.clock() - t0 state:close() printtime('pthreads', n, dt) end local function test_luastate_creation() local t0 = time.clock() local n = 100 for i=1,n do local state = luastate:open() state:openlibs() state:push(function() end) state:call() state:close() end local dt = time.clock() - t0 printtime('states', n, dt) end local function test_thread_creation() local t0 = time.clock() local n = 10 for i=1,n do thread.new(function() end):join() end local dt = time.clock() - t0 printtime('threads', n, dt) end --pn/pm/cn/cm: producer/consumer threads/messages local function test_queue(qsize, pn, pm, cn, cm, msg) msg = msg or {i = 321, j = 123, s = 'hello', bool = true} local q = thread.queue(qsize) local pt = {} for i = 1, pn do pt[i] = thread.new(function(q, n, msg) for i = 1, n do local z = q:push(msg) --io.stdout:write(table.concat({'push', z}, '\t')..'\n') end end, q, pm, msg) end local ct = {} for i = 1, cn do ct[i] = thread.new(function(q, n, msg) for i = 1, n do local _, v, z = q:shift() --io.stdout:write(table.concat({'pop', v, z}, '\t')..'\n') end end, q, cm, msg) end local t0 = time.clock() for i = 1, #pt do pt[i]:join() end for i = 1, #ct do ct[i]:join() end local t1 = time.clock() assert(q:length() == 0) assert(not q:peek()) assert(not q:peek(-1)) q:free() print(string.format('queue test: %d*%d -> %d*%d, queue size: %d, time: %dms', pn, pm, cn, cm, qsize, (t1 - t0) * 1000)) end local function test_pool() --local q = thread.queue(1) --q:push('hi') --print(q:push('hello', time.time() + 1)) local pool = thread.pool(1) for i=1,100 do --print('pushing', i) print('push result', pool:push(function() print'hello' end, time.time() + 1)) end print'joining' pool:join() end --test_events() test_pthread_creation() --TODO: this crashes on mingw64 !!! test_luastate_creation() test_thread_creation() test_queue(1000, 10, 1000, 10, 1000) test_queue(1000, 1, 10000, 1, 10000) test_queue(1000, 1, 10000, 10, 1000) test_queue(1000, 10, 1000, 1, 10000) test_queue(1, 1, 10000, 10, 1000) test_queue(1, 10, 1000, 1, 10000) --test_pool()