Commit Graph

184 Commits

Author SHA1 Message Date
Cedric BAIL 526415d903 eo: make efl_provider_find a @const function. 2018-01-04 11:45:10 -08:00
Jean-Philippe Andre 3e9825cb96 eo: Remove trailing newline in ERR message 2017-12-08 16:02:23 +09:00
Jean-Philippe Andre 207a0cf3e3 eo: Move hacky API auto_unref to C only
This API is meant to be used by parts only, and by bindings dealing with
part objects. This patch fixes make check which got broken in the after
the previous one (cxx).
2017-12-05 15:06:34 +09:00
Jean-Philippe Andre df304d0155 eo: Add beta API for auto_unref after a call
Before screaming in horror (C++...) here's why we may need this:
Efl.Part.part API returns an object that is by definition valid for a
single function call only. Enforcing this in practice is actually quite
hard as all implementation functions must manually take care of the
life-cycle. This is a lot of code in many places and a lot of
opportunities to forget to properly handle that life-cycle. Also, this
means any invalid function call on a part will leak an object.

This API absolutely must remain either "internal" or "beta" and
definitely not become abused by applications. On top of that such an API
can cause great trouble for bindings like C++. As a consequence, only
specially crafted APIs like efl_part() should return an object marked as
auto_unref.

Alternatively this API could be defined in Eo.h or some other
Eo_Internal.h. I placed it in efl_object.eo because it's much more
convenient :) (read: I'm lazy)

****

Performance notes:

Tested with clang & gcc (with -O2), I had a look at the output of perf
top, in particular the asm view. I used eo_bench in a loop. My
conclusions are:

- EINA_LIKELY/UNLIKELY actually works. The jump statement varies
  according to the expectation. I highly doubt all those ugly goto in
  eo.c / Eo.h are even useful.

- The impact of auto_unref on a call_resolve is so small it doesn't even
  appear in the trace. It is significant inside call_end, though
  (obviously, that function is just a few lines long). That function
  accounts for ~1% to ~4% of all CPU time. The impact of auto_unref in
  call_end is ~4% of the function time. This means ~0.16% of all CPU
  time (worst measured case). _efl_object_op_api_id_get simply doesn't
  show up because of caching, so the extra check there is negligible.

PS: I also tested EINA_LIKELY/UNLIKELY by compiling with -O2 and looking
at the output with objdump. The flag is well respected, and the jump
instructions are what you would expect (no jump for LIKELY and jump for
UNLIKELY). Conclusion: The goto's in eo.c only make the code harder to
read...
2017-10-18 11:02:16 +09:00
Jean-Philippe Andre ccee1c0944 eo: Simplify debug_name_override
Simply pass in the strbuf and don't expect the callee to own it. This
makes things simpler and safer (it'll crash only if the callee frees
said strbuf, and shouldn't leak). efl_ebug_name is new in the upcoming
release, EFL 1.21.

Realised this after talking with Amitesh. Thanks.

See 999dbd9764
And c4769ff898
2017-10-13 10:57:00 +09:00
Jean-Philippe Andre d3436af616 eo: Add API to allow deletion by unref
This allows deleting an object by simply calling efl_unref() on it, even
if there is a parent. Normally the parent is in charge, and you can
request deletion by calling efl_del() or efl_parent_set(NULL).

But in some rare cases, you want to give ownership of an object (@owned)
and still give a parent to that object. efl_unref() should be used (and
would be used by bindings when going out of scope or on garbage
collection), which would then print an error message. This API allows
the specific behaviour.

@feature
2017-09-28 16:42:04 +09:00
Guilherme Iscaro d12c652a96 Efl_Object: Add integration with Eina_Future.
This commit adds the EO support for the new future infra.
From now on there's no need to efl_future_link()/efl_future_unlink()
object and futures since the new API already handles that internally.
2017-09-04 10:24:00 -03:00
Jean-Philippe Andre c071fd453b eo: Mark name_find as const
The search should not require a mutable object.
See the previous commit on elm_widget.
2017-08-23 20:53:20 +09:00
Jean-Philippe Andre 999dbd9764 eo debug name: Use strbuf instead of slstr
This should be a little bit more efficient, even if more "risky"
in terms of leaks. The final API still looks exactly the same.
2017-08-04 10:24:03 +09:00
Jean-Philippe Andre c4769ff898 eo: Add debug_name read-only property to ease debugging
This will include the following information, by default:
 - class name
 - whether the class is an override
 - eo id (pointer)
 - refcount
 - name if one was set (Efl.Object property)

This also supports classes, which is why it's an EAPI in eo.c
and not only a method of Efl.Object

This can be overriden by subclasses using the empty method
Efl.Object.debug_name_override.get

If the function is overriden, then the returned string is used
as is and so it is left to the subclass to include all the
necessary information (as above). This can easily be achieved
by calling efl_debug_name_get(efl_super()) and then concatenating
the strings.

Think of this function as something like Java's toString(), but
only for debugging (i.e. a string class should not just return
its string value).

@feature
2017-08-04 10:24:03 +09:00
Marcel Hollerbach 5b8421c550 eo: fix missing event emission
There have been cases where the logic of _event_callback_call break'ed
too early in the event submission.
Reason for that was the line ((const unsigned char *) desc -
(const unsigned char *) it->desc) producing a overflow.

This means the if statement

if (!legacy_compare &&
   ((const unsigned char *) desc - (const unsigned char *) it->desc) < 0)

was true while the pointer desc was smaller than it->desc, which means
the event subscription got aborted, even if it should not.

This turned out on two 32 bit maschines. And led to not rendering apps
anymore.

It was introduced by commit in 605fec91ee.

@fix
2017-05-04 20:44:42 +02:00
Daniel Kolesa 6af8527117 eo: move all the key_ properties to C 2017-04-26 16:19:06 +02:00
Daniel Kolesa 20d1cf94c3 eo: move wref_add/wref_del to C 2017-04-26 16:19:06 +02:00
Daniel Kolesa 67c7eb3134 eo: move future_link to C 2017-04-26 16:19:06 +02:00
Daniel Kolesa 3fb4bc336e eo: hide dbg_info from eo files
Continues b780cf2af2.
2017-04-21 17:59:32 +02:00
Daniel Kolesa b780cf2af2 eo: move unbindable event APIs to C
In a few classes, this requires some manual expansion. This should
not break anything but it's also fairly ugly; a better solution
would be appreciated, for now we do this.

Similar changes will be done to a few other Efl.Object APIs as
well at later point.
2017-04-20 18:24:38 +02:00
Jean-Philippe Andre 86d1f2b6cd eo: Use COW to save 8~16 bytes per object
Summary:
This uses Eina_Cow to implement support for rarely used features
in EO objects. This covers:
- composite objects (eg. UI widgets: combobox, text, video, win)
- vtable for efl_object_override
- del_intercept

All of these features are quite tricky to get right and while
very useful, should still be used with great care. With this patch,
the size of an _Eo_Object struct comes down from 80 bytes (rounded
up from 72b) to 64 bytes (rounded up from 56b) on 64 bits.

Also I haven't measured precisely but I don't expect any performance
impact since the COW data is more likely to remain in L1/L2 cache,
as the default one will be used most often. Unfortunately, the
results of "make benchmark" have been quite inconsistent over
multiple runs.

This saves ~64kb in elementary_test (>4k objects) at the cost of
~100 calls to COW write (del intercept on some events).

@optimization

Reviewers: raster, cedric

Differential Revision: https://phab.enlightenment.org/D4796
2017-04-18 18:52:27 +09:00
Marcel Hollerbach ae80040331 eo: ensure the generation is correctly clamped
Summary:
when a few recursive event emissions are happening, and in some deep
recursive level a subscription to the same object is happening, the
subscription would just be executed when the complete recursion is done.
that is wrong. The subscription needs to be executed when the event is
called after the subscription is added, undepended from any recursive
level. That fixes that and adds a regression test for it.

This was discovered in e, since e gives a lot of error messages about a eo object
that is already freed. It turned out this object is returned from evas, and exactly
the above happened to the EFL_EVENT_DEL subscription of that object.

Test Plan: make check

Reviewers: tasn, cedric, stefan_schmidt

Subscribers: stefan_schmidt, netstar, zmike, raster, jpeg

Differential Revision: https://phab.enlightenment.org/D4656

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
2017-02-16 13:37:19 -08:00
Carsten Haitzler eb3f6f06f1 efl base class - fix warning about comparing differing sizes
yes - we compare a difference between 2 ptrs and an index which is a
uint. the safe thing here is to promote the unit to the ptrdiff_t
type. reality is we cant have more than 2^32 cb's on an object
anyway... so this should be ok.
2017-02-11 23:13:00 +09:00
Carsten Haitzler a817d2f632 eo event callback frame make them single linked to save a bit of overhead
this makes the callback event frame single linked with a little less
inlist overhead asa result.
2016-12-02 21:28:15 +09:00
Marcel Hollerbach 2ce2a65148 eo: adjust generation count
raster suggested a few optimizations
2016-12-02 12:27:37 +01:00
Marcel Hollerbach a2e90e522b eo: optimize generation increase
doing it by hand here saves a function call which showed up pretty happy
on perf.
2016-12-02 12:27:37 +01:00
Marcel Hollerbach 0f72c8a031 eo: use the event stack to define behaviour
subscriptions are only executed if they were already subscriped at the
start of the event emission.
2016-12-02 12:27:37 +01:00
Marcel Hollerbach a035bc1292 eo: fix event emission for subscription while emission
This fixes T4907

The problem was that in efl_event_callback_add the internal array was
changed. If this was happening while a efl_event_callback_call was
happening the for loop got confused and skipped one event subscription.
Which led to a bug in e where the idler ufnction was not executed
probebly and so the canvas stayed frozen.
2016-12-02 12:27:37 +01:00
Andy Williams c5181470c1 eo: safety in string comparison
Avoid potential for Eo to crash if app manages to unset key
@fix
2016-11-28 00:10:30 +00:00
Carsten Haitzler ad985e73f3 eo base class - clean up some formatting around callback add/del code
just formatting changes really.
2016-11-26 18:33:56 +09:00
Cedric Bail 6b165089a6 eo: make it possible to disable batch allocation for callbacks. 2016-11-23 18:50:19 -08:00
Cedric Bail f4527c7283 eo: when there is no more callbacks, let's clean up. 2016-11-23 18:50:19 -08:00
Marcel Hollerbach 70b24abff7 eo: inc the special count
if there is a event the callback counter should be incremented not
decremented. This should fix a few crashes i found in edje, since edje
did not knew that a element was deletion.
2016-11-23 13:42:27 +01:00
Cedric Bail f511c64269 eo: refactor callback delayed cleaning code. 2016-11-21 16:03:27 -08:00
Carsten Haitzler ce8e085d6d efl object events - track del, cb add and cb del callback counts
so hunting another callback issue i noticed some of THE most popular
callbacks are:

     1411  tick
     1961  move
     4157  pointer,move
     7524  dirty
     8090  damage
    13052  render,flush,post
    13052  render,flush,pre
    13205  render,post
    13205  render,pre
    21706  recalc
    21875  idle
    27224  resize
    27779  del
    31011  idle,enter
    31011  idle,exit
    60461  callback,del
   104546  callback,add
   126400  animator,tick

as you can see callback del, add and the general obj del cb's are
right up there... so it is very likely a good idea to CHECK to see if
anyone is listening before calling the callback for these very very
very common calls.

this is ifdef'd and turned on for now. it can be turned off. it
shouldnt use more memory due to the way memory alignment works (likely
all allocations will be multiples of 8 bytes anyway) so we're using
spare unused space. the only q is - is management of the counts AND
checking them worth it in general? it's really hard to tell given we
dont have a lot of benchmarks that cover a lot of use cases... it
doesnt seem to slow or speed anything up much in the genlist bounce
test... so i think i need something more specific.

@optimize
2016-11-17 18:41:32 +09:00
Carsten Haitzler 200490a850 eo src formatting - line up struct member 2016-11-17 18:41:32 +09:00
Carsten Haitzler 036cfc32e4 event callback call - move 0 check early before any var init
a LOT of callback calls call on objects with no cb's at all so the
earlier we check for 0 the better before we do ANYTHING.

@optimize
2016-11-17 18:41:32 +09:00
Carsten Haitzler 1ac86bb878 eo - fix ever growing callback list by actually flagging waiting dels
i found a massive slowdown that over time ended up with 10000's of
cb's in objects like the ecore loop object. this fixes that by
ACTUALLY flagging event deletions waiting to be true rather than false.
2016-11-17 18:41:32 +09:00
Carsten Haitzler 45771d47ab eo - use free queue for at least some eo core memory and pointers
this should help improve robusteness by keeping memory around for a
bit until the free queue flushes or is full

@feature
2016-11-06 13:13:10 +09:00
Tom Hacohen f736946d10 Eo: Add a method to mark objects for reuse.
This informas eo an object is going to get reused/cached, so eo can
reset the object appropriately.

@feature.
2016-10-28 13:19:10 +01:00
Cedric Bail ab18b01e1c eo: do not track NULL future. 2016-10-25 18:51:12 -07:00
Tom Hacohen 25242e6af9 Eo: Fix references of objects 2016-10-21 15:29:39 +01:00
Jean-Philippe Andre 9c95eda748 eo: Fix deadlocks with composite objects
This happens with shared objects.

The situation seems to be:
1. object has composited object a of class A in thread 1
2. call something on object a from thread 2, deadlock
In fact, do anything from thread 2 on a shared object and you deadlock.
2016-10-06 17:57:45 +09:00
Jean-Philippe Andre 6ce60a0de5 eo: Fix deadlock in efl_parent_set
If the object is shared and the given parent is invalid (eg. deleted)
then we will deadlock later. This also adds a test case with it.
2016-10-06 16:19:12 +09:00
Jean-Philippe Andre 258cfbbe80 eo: Fix deadlock with shared objects
The object pointer was passed to EO_OBJ_DONE, rather than its
eo id.
2016-10-06 12:24:59 +09:00
Carsten Haitzler 6a5ae00ffa eo - goto-ify a chunk iof code moving debug printfs out of hot paths
this moves a lot of error case handling into goto's so the code gets
out of the hot path and this should help expecially since variou
smacros do things like:

   do { char buf[256]; sprintf(buf, fmt, ptr); _eo_pointer_error(buf); } while (0)

   _Efl_Class *klass; \
   do { \
      klass = _eo_class_pointer_get(klass_id); \
      if (!klass) { \
         _EO_POINTER_ERR("Class (%p) is an invalid ref.", klass_id); \
      return ret; \
   } \
} while (0)

so putting quite a chunk of code inside a rare "if this errors"
handler that will cause l1 cache misses and this we don't want, thus
moving stuff in eo core out of hot paths to cut down on overhead. yes
it might not be pretty but it's kind of the right thing at such a core
level of efl. this also does the same to the eo base class as this is
also going to be relatively hot given it's the core of every other
object.
2016-09-29 17:45:47 +09:00
Carsten Haitzler 0f929f5546 eo id and shared domain objects - do locking properly and better
so there were a few issues. one we had a spinlokc on the eoid table
for shared objects AND then had a mutex for accessing those objects
(released on return from any eo function). BUT this missed some funcs
like eo_ref, eo_unref and so on in eo.c ... oops. so fixed. but then i
realized there was a race condition. we locked the eoid table then
unlocked with our pointer THEN locked the sharted object mutex ...
then unlocked it. that was a race condtion gap. so we should share the
same lock anyway - if it's a shared object, grab the shared object
mutex then do a lookup and if the lookup does not fail, KEEP the lock
until it is released by the return from eo function or by some special
macro/funcs that released a matching lock. since its a recursive lock
this is all fine. as its also a universal single lock for all objects
we just need the eoid to know if it's shared and needs locking based
on the domain bits. so now do this locking properly with just a single
mutex, not both a spinlock and mutex and keep the lock around until
totally done with the object. this plugs the race condition holes and
goes from 1 spinlock lock and unlock then a mutex lock and unlokc to
just a single mutex lock and unlock. this means shared objects are
actually truly safe across threads and only have the overhead of a
single recursive mutex to lock and unlock in every api call.
2016-09-28 13:38:46 +09:00
Cedric BAIL 6f2cad6439 efl: add a possibility to link death of Eo object with a future. 2016-09-08 14:58:05 -07:00
Carsten Haitzler 09f19c3c73 eo - make eo id table TLS private data for thread safety and speed
This moved all the eoid tables, eoid lookup caches, generation count
information ad eo_isa cache into a TLS segment of memory that is
thread private. There is also a shared domain for EO objects that all
threads can access, but it has an added cost of a lock. This means
objects accessed outside the thread they were created in cannot be
accessed by another thread unless they are adopted in temporarily, or
create4d with the shared domain active at the time of creation. child
objects will use their parent object domain if created with a parent
object passed in. If you were accessing EO (EFL) objects across threads
before then this will actually now cause your code to fail as it was
invalid before to do this as no actual objects were threadsafe in EFL,
so this will force things to "fail early".
ecore_thread_main_loop_begin() and end() still work as this uses the
eo domain adoption features to temporarily adopt a domain during this
section and then return it when done.

This returns speed back to eo brining the overhead in my tests of
lookup for the elm genlist autobounce test in elementary from about
5-7% down to 2.5-2.6%. A steep drop.

This does not mean everything is perfect. Still to do are:

1. Tests in the test suite
2. Some API's to help for sending objects from thread to thread
3. Make the eo call cache TLS data to make it also safe
4. Look at other locks in eo and probably move them to TLS data
5. Make eo resolve and call wrappers that call the real method func do
   recursive mutex wrapping of the given object IF it is a shared object
   to provide threadsafety transparently for shared objects (but adding
   some overhead as a result)
6. Test test est, and that is why this commit is going in now for wider
   testing
7. Decide how to make this work with sending IPC (between threads)
8. Deciding what makes an object sendable (a sendable property in base?)
9. Deciding what makes an object shareable (a sharable property in base?)
2016-09-07 18:17:10 +09:00
Carsten Haitzler e14a11d9fa eo base - fix free of all callbacks to set callbacks to NULL
we set count to 0 but not ptr to NULL. this we must do after free so
when other destructors run dont go relying on this ptr to be valid!
2016-09-06 22:12:23 +09:00
Tom Hacohen f13bb9d9f5 Efl object: rename shadowing variable. 2016-09-05 16:22:33 +01:00
Cedric BAIL 3ab60a1564 eo: store registered callbacks in an array instead of a single chained list. 2016-09-02 10:19:45 -07:00
Cedric BAIL 605fec91ee eo: improve speed of walking callback array by sorting them during creation.
This improve speed of processing events in genlist scrolling benchmark by 30%
inside the efl_object_event_callback_call code. Not a really big deal as it
goes from 0.9% to 0.6% of the total time spend. Welcome to micro optimization.
2016-09-02 10:19:45 -07:00
Carsten Haitzler 90acc0216b eo - make eoid table access threadsafe - was missing a lock around it
this now makes at least eoid deref and ojbect access safe across
threads. the downside is that oeid lookup goes from 2% to ~5% of cpu.
ugh.
2016-09-01 18:59:56 +09:00