On Wed, 24 Apr 2013 16:41:49 +0900 Carsten Haitzler (The Rasterman)
<ras...@rasterman.com> said:

oh.. and i probably should... edit this for.. typos...

> On Wed, 24 Apr 2013 16:19:50 +0900 Carsten Haitzler (The Rasterman)
> <ras...@rasterman.com> said:
> 
> > On Wed, 24 Apr 2013 08:27:01 +0300 "daniel.za...@samsung.com"
> > <daniel.za...@samsung.com> said:
> > 
> > > Hi Jeremy,
> > > 
> > > On 04/24/2013 12:00 AM, Jérémy Zurcher wrote:
> > > > Hi,
> > > > I did enjoy it!
> > > > even if I'wd prefered a pointer then ID_TABLE macro,
> > > > just a matter of taste I suppose ;)
> > > I did it because it was too much with the 
> > > _eo_ids_tables[table_id][int_table_id], I mean not readable. But I am 
> > > sure it can be written better ;-)
> > > >
> > > > a question,
> > > > what did you based your 32 and 64 bits decomposition on?
> > > > equations, benchmarks, moon's CxA ?
> > > no equations.
> > > Well let's say that for the moment, it is not enough optimized. The most 
> > > important was to not have big internal tables and to have enough bits 
> > > for the generation to be efficient.
> > > For 64 bits, well, hum, I don't know what I thought to put 20 bits for a 
> > > table size. Raster already spanked me for that ;-)
> > > 
> > > Concerning optimization, in 32 bits, I think we could increase the 
> > > generation #bits and reduce the tables #bits because we will never reach 
> > > 4M of objects. I never saw more than 5K objects. So we could steal 2 
> > > bits from there (we would have max. 1M objects) for the generation and 
> > > so increase the stability.
> > 
> > really? no more than 5k objects? interesting. i was maybe expecting 20-40k.
> > and yes - i did have to spank a bit on the table sizes on 64bit. i adjusted
> > things so we use 30bits for generation counter on 64bit and thus 34bits for
> > obj id. since the code splits object lookup into a 3 level table (master
> > table array, inter table and then child table),i allocated 11 bits for
> > master and inter tables and 12 for child table. this means our "base cost"
> > for our first 4k objects is 16k+16k+65k. for every extra 4k object we spend
> > another 65k.
> > 
> > now slight catch... i ALSO changed the table allocation to use mmap() of
> > anonymous memory. why? separate memory regions for storign the table away
> > from memory managed by libc (malloc etc.). this means the "chance" of
> > someone finding the memory areas by ccidentally overrunning an existing
> > allocation (walk off the end or beginning of an allocation), OR by
> > accidentally accessing a previously freed pointer that has ben recycled...
> > is basically almost 0. to talk off the end means they will probably have to
> > walk of a valid memry mapping into unmapped space and then segv anyway, so
> > chances of table corruption now are very very very small, UNLESS that
> > corruption problem is inside eo_id code.
> > 
> > now to the catch... to do this i made it mmap and that means it mmapes in
> > units of 4k pages.. so adding in accounting overhead, we actually cost 20k
> > +20k +68k for the base and each new set of 4k objects costs another 68k (on
> > 64bit). these costs on 32bit are moe like 4k+4k+8k for the first 1024
> > objects and an extra 8k for each 1024 objects. i'm actually thinking i
> > should re-jig 32bit.
> > 
> > so we divide the obj id into 3 tables (master.inter.sub):
> > 
> > 32bit: 8.4.10   = 22bits (max 4 million objects)  = 4k+4k+8k (first 1024)
> > 64bit: 11.11.12 = 34bits (max 16 billion objects) = 20k+20k+68k (first 4096)
> > 
> > i think i should adjust 32bit to be maybe 5.5.12 (this brings our costs to
> > 4k+4k+20k for the first 4096 objects, and an extra 20k for the next 4096)...
> > since object COUNTs will be the same on 32 and 64bit i think this works well
> > as given "no more than 5k" for i guess large complex apps (lets pad this up
> > to 8k) we pay the base cost plus an extra leaf table ... on a heavy app (20
> > +20 +68+68 on 64bit or 4+4+20+20 on 32bit - after rejing (before rejig 4+4
> > +(8*8) so we go from 72k to 48k - but if we assume small # of objects we
> > are better off adjusting to 6.7.9 so our base cost is 4k+4k+4k for 512 and
> > 4k for each 512 which is a lower base cost of 12k and then for 8k objects
> > the same as now
> > - 72k).
> > 
> > so the question is.. optimize for 4-8k objects and thus lower our cost for
> > that from 72k to 48k... or optimize for small # of objetcs, which means
> > adjusting the current setup anyway to 6.7.9... for small object counts our
> > base cost goes from 28k to 12k. i think i lean to optimizing for 4-8k
> > objects... because over time i suspect we will use eo more and more and make
> > more objects... a quick look at counting # of objects daniel is right. i'm
> > seeing things like 2-4k for elementary_test (even if i push it) and e17 too
> > (with some pushing)... they break the 4k mark after some pushing ... so i
> > suspect this will be common enough.
> > 
> > (sorry - lots of thinking out aloud here to give reasoning for wanting to
> > change the 32bit obj id allocation division).
> > 
> > so people know... what the obj id vs generation count is... the id is the
> > actoual object identifier number. each object has a unique one. it is
> > literally its entry in a table (0, 1, 2, 3... N). this table has a fixed
> > capacity per architecture (22bits or 4m objects on 32bit, and 34bits or 16b
> > objects on 64bit). objects may, in the c api appear to return a pointer, but
> > stuffed into this pointer is now the id... and all acess is done by looking
> > UP this id in this multi-level table and safely checking the appropriate
> > slot in the table has a valid (non-null) pointer finally pointing to an
> > actual object struct. every table entry is EITHER null OR valid. it can
> > never be non-null and non-valid. on creation of every object it gets a
> > table entry. on freeing (deletion) its entry is released and nulled out. at
> > least that is the theory ASSUMING all object creation points go through
> > this table path as well as deletion paths. if they don't - we have a bug in
> > eo and that must be fixed. this also assumes that efl code that has access
> > to the obj ptr itself is "much more trusted" than "3rd party code" so efl
> > wont accidentally free this obj pointer and thus not go through the
> > deletion path that fixes up the table.
> > 
> > all of this work is a result of observing developer usage of efl over years
> > and finding that there is gnerally a problem in "pointer/memory management"
> > inside apps and that spills over into efl in the form of accessing invalid
> > (deleted) evas objects or deleted timers etc. etc., then using up efl
> > developer time hunting down a bug in an application just because a crash
> > happens inside some object sanity check (eg magic number checking and the
> > magic number is store in the obj struct and if the ptr points to
> > inaccessible memory... we segv). this table indirection does add overhead.
> > we know that. it is a "necessary evil" to address "application developer
> > concerns" and to cut back on time chasing irrelevant bugs. this is WHY eo
> > has this odd eo_do() thing that you can pack MULTIPLE methods/operations
> > for a single object into the args... it means we pay this table lookup cost
> > only ONCE for several method calls - thus ammortising the cost across
> > multiple "old school" method and thus hopefully "breaking even" once
> > everything is using this eo api and batching methods nicely.
> > 
> > so what are the other 10 or 30 bits in the pointer - now become id handle -
> > used for? well it's a sanity check. eveyr time any object is created, a
> > gneration counter ticks over. it loops/repeats every N values (1024 on
> > 32bit, 1billion or so on 64bit). this generation count is no part of the id
> > entry in he table but it IS packed into the pointer returned and so when we
> > do a lookup we strip off the generation count (10 or 30 bits) and then use
> > the id section to do the lookup we then COMPARE the generation count ALSO
> > stored in the table next to the entry to the generation count we stripped
> > out. i they do not match... it is an invalid access. why? we are recycling
> > a table entry. likely an object was deleted, table entry freed, then
> > recycled, and we try access again with an old handle frm the outside. it
> > *IS* possible, in theory, for the generation count to accidentally match (1
> > in 1024 chance on 32bit and 1 in a billion chance on 64bit). then the
> > object dereference goes through and our code calls methods on perhaps the
> > wrong object. this would happen if malloc recycled a pointer address too,
> > so we are no worse off really. we STILL check on object class types (ie the
> > method id has to exist for that object class and since method ides are
> > unique globally and not class-relative) we still have a lot of safety here.
> > no crashing inside efl still, but maybe misbehaviour... but our CHANCES of
> > this should have been drastically reduced... ESPECIALLY on 64bit
> > architectures. rememebr this applies ONLY to invalid object references that
> > ALSO have been recycled AND whose generation id match.
> > 
> > now... we still hve a few things to do here to make safety even more robust.
> > 
> > 1. don't recycle id's so aggressively. have a "zombie pool" of id's with a
> > high and low watermark. this means an object id is not going to be recycled
> > "soon" and thus he most common accesses like del() then use() a few lines
> > later or while walking back up the stack to parent callers, are caught as
> > the id itself simply is forcibly invalud (nulled out) and remains so for a
> > while as its in the zombie trash pool. maybe have 1024 or 2048 zombie
> > entries.
> > 
> > 2. obj ptr and gneration cunt are in 2 separate arrays - thus not continuous
> > in memory. ue to cacheline fetches these should be merged so they are
> > adjacent so we pay only 1 cacheline fetch delay if not already in cache
> > instead of 2.
> > 
> > 3. checksum each table row. we consunme 1 void * size for the pointer in
> > each row AND 1 void * for the generation count. even if gneration count is
> > only 10bit or 30bit, due to alignment and doing #2 above we will spend a
> > void * for alignment reasons. we SHOULD pack a checksum into the generation
> > count region. if a table entry should now be struct { void *ptr; unitptr_t
> > checksum:22; unitptr_t generation:10; } or... similar for 64bit. this
> > checksum should just be a ead simple checksum of pointer+generation count
> > elements (maybe a simple xor or so) to try detect if perhaps someone did
> > accidentally find out table and scribble over parts of it. we chould
> > compare checksum on each access and generate it on each write to that table
> > row. this doesn't help with our master and inter table though which are
> > just raw pointers... no generation count in there. perhaps we should
> > checksum all the pointers in each of these tables too... or checksum
> > sections/ranges. this might be lean enough to ship with production
> > releases, BUT... might not be... we have to see, but it is an option for
> > debug releases (during development) for sanity checks.
> > 
> > 4. since we forcibly took control over our table allocation... and it is
> > always a multiple of pages... we can use mprotect to remove write access
> > UNLESS eo_id is modifying that table. this is expensive as every change has
> > to go into kernel space and change pagetable information, so it wouln't be
> > something we do in production release code, BUT debug code could definitely
> > enable this as a way of catching table corruption instantly via a segv. :)
> > 
> > 5. we currently nver free tables once they are empty. we just keep a bunch
> > of empty tables arund to be re-used. we need to of course keep a zombie
> > table pool around of maybe a few tables.. again - high/low watermark, and
> > then release when we ee we are not going to re-use our spare tables any
> > time soon. given current object counts in things like elementary_test and
> > enlightenmnt, we at most will find ourselves with only 1 spare empty leafe
> > table at the moment... so this is not high priority.
> 
> oh... 6. the trash queue is managed by eina.. in malloced memory - this needs
> to move into probably fixed size buffers inside the table leaf struct so this
> only lives in custom mmaped memory owned by eo_id.
> 
> > 
> > someone... should... blog... about... this... :) i have to say.. the eo id
> > thing is rather cool and unique... you don't see this kind of thing many
> > places in c or c++ toolkits like efl (or gtk+ or qt) and it really can hlp
> > with robustness a LOT. this is all part of some major groundwork overhauling
> > these guys in israel have done and i have to say... it has been done very
> > well, considering how deep in the stack this lives and how many things it
> > affects (not just eo_id but eo in general). so kudos to the team!
> > 
> > > >
> > > > regards
> > > > Jérémy
> > > >
> > > >
> > > > On Tuesday 23 April 2013  09:59, daniel.za...@samsung.com wrote :
> > > >> Hi all,
> > > >>
> > > >> This morning, I pushed the Eo pointers indirection feature. As I wrote
> > > >> in the log, it is not API break. It will help us against bad usage of
> > > >> Eo objects pointers, e.g access an object that has already been
> > > >> deleted... So if you see that the Eo* that you receive from eo_add
> > > >> doesn't seem like a "normal" pointer, but like 0x1000401, just know it
> > > >> is normal. If you need a better explanation on the mechanism used,
> > > >> check the file eo_ptr_indirection.c in src/lib/eo.
> > > >>
> > > >> If you see error messages "obj_id ... is not pointing to a valid
> > > >> object. Maybe it has already been freed.", check your Eo objects or
> > > >> contact me.
> > > >>
> > > >> Enjoy
> > > >> JackDanielZ
> > > >>
> > > >> ------------------------------------------------------------------------------
> > > >> Try New Relic Now & We'll Send You this Cool Shirt
> > > >> New Relic is the only SaaS-based application performance monitoring
> > > >> service that delivers powerful full stack analytics. Optimize and
> > > >> monitor your browser, app, & servers with just a few lines of code. Try
> > > >> New Relic and get this awesome Nerd Life shirt!
> > > >> http://p.sf.net/sfu/newrelic_d2d_apr
> > > >> _______________________________________________ enlightenment-devel
> > > >> mailing list enlightenment-devel@lists.sourceforge.net
> > > >> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> > > >
> > > > ------------------------------------------------------------------------------
> > > > Try New Relic Now & We'll Send You this Cool Shirt
> > > > New Relic is the only SaaS-based application performance monitoring
> > > > service that delivers powerful full stack analytics. Optimize and
> > > > monitor your browser, app, & servers with just a few lines of code. Try
> > > > New Relic and get this awesome Nerd Life shirt!
> > > > http://p.sf.net/sfu/newrelic_d2d_apr
> > > > _______________________________________________ enlightenment-devel
> > > > mailing list enlightenment-devel@lists.sourceforge.net
> > > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> > > 
> > > 
> > > 
> > > ------------------------------------------------------------------------------
> > > Try New Relic Now & We'll Send You this Cool Shirt
> > > New Relic is the only SaaS-based application performance monitoring
> > > service that delivers powerful full stack analytics. Optimize and monitor
> > > your browser, app, & servers with just a few lines of code. Try New Relic
> > > and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
> > > _______________________________________________
> > > enlightenment-devel mailing list
> > > enlightenment-devel@lists.sourceforge.net
> > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> > 
> > 
> > -- 
> > ------------- Codito, ergo sum - "I code, therefore I am" --------------
> > The Rasterman (Carsten Haitzler)    ras...@rasterman.com
> > 
> > 
> > ------------------------------------------------------------------------------
> > Try New Relic Now & We'll Send You this Cool Shirt
> > New Relic is the only SaaS-based application performance monitoring service 
> > that delivers powerful full stack analytics. Optimize and monitor your
> > browser, app, & servers with just a few lines of code. Try New Relic
> > and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
> > _______________________________________________
> > enlightenment-devel mailing list
> > enlightenment-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> 
> 
> -- 
> ------------- Codito, ergo sum - "I code, therefore I am" --------------
> The Rasterman (Carsten Haitzler)    ras...@rasterman.com
> 
> 
> ------------------------------------------------------------------------------
> Try New Relic Now & We'll Send You this Cool Shirt
> New Relic is the only SaaS-based application performance monitoring service 
> that delivers powerful full stack analytics. Optimize and monitor your
> browser, app, & servers with just a few lines of code. Try New Relic
> and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
> _______________________________________________
> enlightenment-devel mailing list
> enlightenment-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    ras...@rasterman.com


------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to