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