Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffi.typeof limit and shm.lua #1405

Open
mestorsi opened this issue Jan 10, 2019 · 3 comments
Open

ffi.typeof limit and shm.lua #1405

mestorsi opened this issue Jan 10, 2019 · 3 comments

Comments

@mestorsi
Copy link

Hello,

I tried to create and open objects with shm many times аnd found the problem (function map from shm.lua - return ffi.cast(ffi.typeof("$&", ctype), mem)) which I tried to reproduce in the following code:

module(..., package.seeall)
local ffi = require "ffi"
function run()
    for i = 1,10000 do
        print("i = " .. tostring(i))
        for n = 0,9999 do
            local type = "struct {uint8_t value[" .. tostring(i*10000 + n) .. "];}"
            local ctype = ffi.typeof(type)
        end
        ffi.C.sleep(1)
    end
end

Result:

./snabb testtypeof
i = 1
i = 2
i = 3
table overflow

Stack Traceback
===============
(1) Lua function 'handler' at file 'core/main.lua:168' (best guess)
        Local variables:
         reason = string: "table overflow"
         (*temporary) = C function: print
(2) field C function 'typeof'
(3) Lua field 'run' at file 'program/testtypeof/testtypeof.lua:10'
        Local variables:
         (for index) = number: 3
         (for limit) = number: 10000
         (for step) = number: 1
         i = number: 3
         (for index) = number: 1373
         (for limit) = number: 9999
         (for step) = number: 1
         n = number: 1373
         type = string: "struct {uint8_t value[31373];}"
(4) Lua function 'main' at file 'core/main.lua:67' (best guess)
        Local variables:
         program = string: "testtypeof"
         args = table: 0x41754ac0  {}
(5) global C function 'xpcall'
(6) main chunk of file 'core/main.lua' at line 238
(7)  C function 'require'
(8) global C function 'pcall'
(9) main chunk of file 'core/startup.lua' at line 3
(10) global C function 'require'
(11) main chunk of [string "require "core.startup""] at line 1
        nil

Of course, after create() and open() I run unmap(), unlink() for every object.

@lukego
Copy link
Member

lukego commented Jan 10, 2019

The FFI is limited to defining max 64K types. Each time you call ffi.typeof("struct ...") you are creating at least one new type (and possibly more for pointers and references.) So it makes sense that after some tens of thousands of iterations this loop will exhaust all of the available 16-bit "ctype-id" values and you will get an error when trying to define a new type.

You probably need to reformulate your program to define fewer types and reuse them. This means at least caching the results of your calls to ffi.typeof(...). You might also find that you only need one type e.g. that you can move the object size from the type into the value with struct { int size; uint8_t values[0]; }.

I don't think this issue touches on operating system shared memory issues -- it's the Lua runtime.

Does that help?

@mestorsi
Copy link
Author

Thanks for the reply, I will try your recommendation. I think struct { int size; uint8_t values[0]; } should help.

@lukego
Copy link
Member

lukego commented Jan 10, 2019

Just remember that every time you call ffi.typeof("struct ...") you will define a new C type, even if the structure definition is the same. So if you only need one type then be careful to only call ffi.typeof() once and to reuse the type object that it returns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants