Date | Commit message (Collapse) |
|
Might as well be able to see and inspect what allocations
are alive when developing a Rack application.
Demo is available at https://80x24.org/MWRAP/each/2000 (note:
"MWRAP" is capitalized) This is also running "repobrowse",
which will eventually replace cgit on 80x24.org, but is NOT
running the main HTTPS termination at https://80x24.org/
Note: this demo machine is 32-bit, so yes, it will overflow
|
|
Tracking memory used for monitoring code itself is noise,
so give users the power to omit it.
|
|
Users will still pay the cost in memory overhead, but this
gets rid of misleading statistics. Tracking actual Ruby
object allocations is better left to Ruby itself.
|
|
There's nothing a user can do about allocations which happen
in our constructor (aside from not using mwrap), so do not
track them.
|
|
glibc will place the (virtual) address at the end, and this allows us to
find addresses for programs which put '[' in their progname (e.g. ssh,
mogilefsd, unicorn, avahi, ...)
|
|
PTHREAD_MUTEX_INITIALIZER is incomplete, in that it does lazy
initialization when pthread_mutex_init is called. So we call
pthread_mutex_init explicitly, as well as calling rcu_read_lock
during the constructor to initialize mutexes used by urcu-bp.
|
|
An "int" length is enough for the source location length, as
it's not going to exceed PATH_MAX by much.
|
|
Knowing the average/max lifespan (in terms of GC.count) of
allocations can be useful.
|
|
It is not safe to use the new Mwrap[] method with Mwrap.clear,
and the rcu_head overhead in src_loc structs was not worth it.
|
|
This can be useful in apps to analyze what's live and
what's not.
|
|
cmake (as run by the Ruby test suite for RubyGems) uses libjson
and libtasn1, which respectively call malloc (via `new') and
free before our constructor can even fire. Apparently, C++
variable initialization may call "new" outside of any functions;
and those run before any functions with the GCC constructor
attribute.
Disclaimer: I don't know C++
|
|
Ruby source locations can be extremely long and use excessive
stack space. Move it off stack for the temporary key lookup
to reduce the likelyhood of stack overflows. No need to use
TSD (which is stored on stack with GCC anyways); as we have
GVL at that point.
|
|
And rework our internal_memalign interface to mimic the
posix_memalign API; since that's what Ruby favors and
avoids touching errno on errors.
|
|
rcu_read_unlock may clobber errno, so it's our responsibility
to preserve it. Fortunately, ENOMEM is the only error which
real_malloc can fail with.
Also, do not set errno for posix_memalign.
|
|
Oops :x
|
|
We shouldn't try to read NULL pointers :x
|
|
We need to hold the RCU read lock to ensure the liveness
of the associated src_loc struct we'll be inserting into.
|
|
This reduces portability concerns about the various names of
memalign-related functions and should let us save some memory by
not requiring the malloc implementation to align-away the data.
|
|
This increases costs even more, but will allow leak finding.
It will be made optional in the future.
|
|
OK, Ruby blindly closing file descriptors it doesn't know about
is really getting on my nerves, now.
|
|
Users may screw up ordering of arguments :x
|
|
This should avoid indirect function call overhead as the
symbol can be resolved at link time instead of at runtime
with a constructor.
|
|
|
|
|
|
|
|
|
|
|
|
Most of this code is independent of Ruby. synchronize_rcu in
Mwrap#clear can take a while, and I would not rule out having a
version of this which works with Perl5 :>
|
|
And drop redundant versions in case people upgrade
by replacing a running process.
|
|
Hopefully this improves readability somewhat.
|
|
|
|
|