Commit Graph

23 Commits

Author SHA1 Message Date
Ell
d3e1f50b13 app, meson.build: fix a bunch of warnings in C++ files
(cherry picked from commit 4fc345183b)
2019-09-12 20:05:45 +03:00
127fc91603 Issue #3087: error compiling for Windows.
s/THREAD_MODE_ABOVE_NORMAL/THREAD_PRIORITY_ABOVE_NORMAL/
Thanks to Sylvie Alexandre for noticing and searching this.

(cherry picked from commit ebc3ef3c5e)
2019-03-08 17:36:13 +01:00
Ell
cd159e4bd4 app: fix indepndent-async thread priority on Windows
Positive and negative priorities got swapped...

(cherry picked from commit 190095c97b)
2019-03-06 00:08:05 -05:00
Ell
a3cd8c96d0 app: add gimp_parallel_run_async_independent_full()
... which is equivalent to gimp_parallel_run_async_independent(),
except that it takes an additional "priority" parameter, which
specifies the task's priority, with 0 being the default priority,
and lower values indicating higher priority.  Unlike
gimp_parallel_run_async_full(), the priority parameter doesn't
directly control the task's priority in a queue, but rather, we use
it to control the priority of the task's dedicated thread, on
supported platforms (previously, all independent async tasks would
run with low priority.)

Use low priority when loading fonts, which can take a long time, to
keep the existing behavior.

(cherry picked from commit fa2e4dcce0)
2019-03-06 00:02:10 -05:00
Ell
90292953c3 app: in gimp-parallel, boost priority of waited-upon asyncs
When an async that was created through
gimp_parallel_run_async[_full](), and whose execution is still
pending, is being waited-upon, maximize its priority so that it
gets executed before all other pending asyncs.

Note that we deliberately don't simply execute the async in the
calling thread in this case, to allow timed-waits to fail (which is
especially important for gimp_wait()).

(cherry picked from commit 62baffed98)
2018-11-24 11:07:13 -05:00
Ell
79a44eda6d app: more gimp-parallel fixes
Fix indentation in gimp-parallel.{cc,h}.

Remove unused typedefs in gimp-parallel.h.

s/Gimp/Gegl/ in function-type cast in gimphistogram.c.

(cherry picked from commit 05a4437d9a)
2018-11-24 11:05:10 -05:00
Ell
8fe6645950 app: indentation fix in gimp-parallel.cc
(cherry picked from commit 115fc174f2)
2018-11-24 11:05:10 -05:00
Ell
d4312fd5f7 app: remove gimp_parallel_distribute(); use gegl_parallel_distribute()
The parallel_distribute() family of functions has been migrated to
GEGL.  Remove the gimp_parallel_distribute() functions from
gimp-parallel, and replace all uses of these functions with the
corresponding gegl_parallel_distrubte() functions.

(cherry picked from commit 2736cee577)
2018-11-24 11:05:10 -05:00
Ell
9f86b58a38 app: allow progressive execution of parallel async operations
In the gimp_parallel_run_async() family of functions, allow the
async callback to return without completing the async operation, in
which case the callback will be called again, until the operation
is either completed, or canceled, in which case it is aborted
(previously, returning from the callback without completing the
operation would cause it to be aborted.)  It is guaranteed that all
operations of the same priority will get a chance to run, even if
some of them contuinuosly return without completing.

This allows potentially time-consuming operations to yield
execution in favor of other same-priority operations, and, in
particular, of higher-priority operations, to avoid priority
inversion.  Essentially, this allows a simple form of cooperative
multitasking among async operations.

(cherry picked from commit 4969d75785)
2018-10-09 12:49:42 -04:00
Ell
e8fef315c5 app: in gimp-parallel, cancel ongoing async operations upon exit
When shutting-down gimp-parallel, cancel and/or abort any ongoing
and queued async operations, instead of finishing them (async
operations that already started executing will be canceled, but
execution will be blocked until they're finished.)  This is
especially important since we're shutting down gimp-parallel before
the destruction of data factories.  This commit causes any ongoing
async operations of the factories to be canceled on shutdown,
rather than waiting for them to finish normally.

(cherry picked from commit e46fdc714e)
2018-10-01 05:24:59 -04:00
Ell
e1b85e1109 Revert "app: disable parallel asynchronous operations when GEGL_THREADS=1"
This reverts commit 1c435f313b, which
is no longer necessary after GEGL commit
c8a0b9eff07c8d9122f55f7b7527d51788ae4575.
2018-09-20 08:10:47 -04:00
Ell
bc312531fb app: flush async-operations queue when setting async thread count to 0
In gimp-parallel, always flush the async-operations queue (by
executing all remaining operations on the caller thread) when
setting the async-pool thread count to 0 (as happens when setting
GEGL_THREADS=1, per the previous commit,) and not only when
shutting GIMP down.  Otherwise, pending asynchronous operations
can "get lost" when setting GEGL_THREADS to 1.

Additionally, in gimp_gegl_init(), initialize gimp-parallel before
before connecting to GimpGeglConfig's "notify::num-processors"
signal, so that the number of async threads is set *before*
GEGL_THREADS, in order to avoid setting GEGL_THREADS to 1 while
async operations are still executing.

Also, allow setting the number of gimp-parallel-distribute threads
while a gimp-parallel-distribute function is running (which can
happen if gimp-parallel-distribute is used in an async operation,
as is the case for histogram calculation), by waiting for the
parallel-distribute function to finish before setting the number of
threads.

(cherry picked from commit 432a884715)
2018-07-15 05:07:46 -04:00
Ell
1c435f313b app: disable parallel asynchronous operations when GEGL_THREADS=1
When GEGL_THREADS=1, concurrent access to the same buffer is not
safe, which can result in errors if asynchronous operations are
allowed to run in parallel to the main thread (see
https://gitlab.gnome.org/GNOME/gimp/issues/1721#note_265898.)

Disable parallel execution of asynchronous operations when
GEGL_THREADS=1 for now, to fix this.  Ultimately, GEGL should be
able to remain thread-safe even when GEGL_THREADS=1.  Note that we
want to execute asynchronous operations on a separate thread even
when GEGL_THREADS=1, since the goal here is mainly to avoid
blocking the main thread during their execution, rather than
speeding their execution up (in particular, it's benecifical to run
asynchronous operations in parallel even on a single-core machine,
while parallelizing GEGL operations generally isn't.)

(cherry picked from commit 408540659f)
2018-07-15 03:44:33 -04:00
a88c0ffb93 Change the license URL from http://www.gnu.org/licenses/ to https:// 2018-07-11 23:47:19 +02:00
Ell
fac91ddad4 app: add gimp_parallel_run_async_{full,independent}()
Remove the "independent" parameter of gimp_parallel_run_async(),
and have the function always execute the passed callback in the
shared async thread-pool.

Add a new gimp_parallel_run_async_full() function, taking, in
addition to a callback and a data pointer:

  - A priority value, controlling the priority of the callback in
    the async thread-pool queue.  0 is the default priority (used
    by gimp_parallel_run_async()), negative values have higher
    priority, and positive values have lower priority.

  - A destructor function for the data pointer.  This function is
    called to free the user data in case the async operation is
    canceled before execution of the callback function begins, and
    the operation is dropped from the queue and aborted without
    executing the callback.  Note that if the callback *is*
    executed, the destructor is *not* used -- it's the callback's
    responsibility to free/recycle the user data.

Add a separate gimp_parallel_run_async_independent() function,
taking the same parameters, and executing the passed callback in
an independent thread, rather than the thread pool.  This function
doesn't take a priority value or a destructor (and there's no
corresponding "_full()" variant that does), since they're pointless
for independent threads.

Adapt the rest of the code to the changes.

(cherry picked from commit b74e600c12)
2018-07-04 16:12:21 -04:00
Ell
d20170ed6c app: in gimp-parallel, fix async-thread shutdown
... to prevent a potential deadlock.

(cherry picked from commit ff679c66a1)
2018-07-04 14:05:49 -04:00
Ell
85a1b1ece7 app: lower thread priority of independent async operations
In gimp_parallel_run_async(), lower the priority of threads
executing independent async operations.  Independent operations
are generally potentially long-standing background tasks, which we
don't want to bog down the rest of the program.

This is currently only implemented on Linux and Windows.
2018-05-29 16:07:48 -04:00
Ell
1dff8d40c1 app: fix gimp_parallel_run_async() cancelation
In gimp_parallel_run_async(), when aborting a GimpAsync operation
in reponse to its "cancel" signal, properly clean up internal data
attached to the object, to avoid use-after-free if the signal is
emitted again.

(cherry picked from commit 3fa4c01bcf)
2018-05-27 13:59:42 -04:00
Ell
ddc9daceca app: add "independent" parameter to gimp_parallel_run_async()
Add a boolean "independent" parameter to gimp_parallel_run_async().
When FALSE, the passed function is run in the shared async thread
pool; when TRUE, the passed function is run in an independent
thread.

Generally, async operations should run in the async pool, however,
it might be desirable to run long-standing operations, especially
ones that can't be canceled, in independent threads.  This avoids
stalling quicker operations, and shutdown.

Adapt the rest of the code for the change.  In particular,
initialize the font cache in an independent thread.

(cherry picked from commit ad8add6808)
2018-05-27 13:18:56 -04:00
Ell
3ae1eec240 app: abort canceled pending operations in gimp_parallel_run_async()
In gimp_parallel_run_async(), connect to the returned GimpAsync's
"cancel" signal, and abort the operation in response if it's still
enqueued, i.e., if its execution hasn't started yet.

(cherry picked from commit 3958ffbe50)
2018-05-27 13:18:56 -04:00
Ell
4c767b4f03 app: fix gimp-parallel shutdown
Some leftover from an earlier version.  Caused gimp_parallel_exit()
to hang, although we could only notice that in GIMP_UNSTABLE
builds.
2018-05-13 11:55:16 -04:00
Ell
1b646804ea app: add gimp_parallel_run_async()
... which runs a user-provided function asynchronously, returning a
corresponding GimpAsync object.  This can be used to execute code
off the main thread, using the GimpAsync object to synchronize as
necessary.

Note that while the code allows for running multiple asynchronous
functions in parallel in a thread pool, we currently limit the pool
to a single thread, queueing overlapping async function, since we
have no use for parallel asynchronous functions at the moment.
2018-05-11 14:01:42 -04:00
Ell
86b89cf62a app: add gimp-parallel
Add gimp-parallel.[cc,h], which provides a set of parallel
algorithms.

These currently include:

  - gimp_parallel_distribute():  Calls a callback function in
    parallel on multiple threads, passing it the current thread
    index, and the total number of threads.  Allows specifying the
    maximal number of threads used.

  - gimp_parallel_distribute_range():  Splits a range of integers
    between multiple threads, passing the sub-range to a callback
    function.  Allows specifying the minimal sub-range size.

  - gimp_parallel_distribute_area():  Splits a rectangular area
    between multiple threads, passing the sub-area to a callback
    function.  Allows specifying the minimal sub-area.

The callback function is passed using an appropriately-typed
function pointer, and a user-data pointer.  Additionally, when used
in a C++ file, each of the above functions has an overloaded
template version, taking the callback through a generic parameter,
without a user-data pointer, which allows using function objects.
2018-04-04 17:49:46 -04:00