diff --git a/doc/RTD/source/Task/index.rst b/doc/RTD/source/Task/index.rst index 98442108894c355fc14c44d0bca3161d33eaeb67..2a7882ece04e4d765853457c2a44ebfa1d2c2dde 100644 --- a/doc/RTD/source/Task/index.rst +++ b/doc/RTD/source/Task/index.rst @@ -21,3 +21,4 @@ Everything is described in :ref:`Analysis_Tools`. adding_your_own adding_your_own_neighbour_loop adding_to_dependency_plotting_tool + locks diff --git a/doc/RTD/source/Task/locks.rst b/doc/RTD/source/Task/locks.rst new file mode 100644 index 0000000000000000000000000000000000000000..5da48146d9c02cf12de3b47438b8979b6277530d --- /dev/null +++ b/doc/RTD/source/Task/locks.rst @@ -0,0 +1,65 @@ +.. locks + Mladen Ivkovic Feb 2021 + +.. _task_locks: +.. highlight:: c + + +Task Locks +============= + +Swift doesn't only deal with dependencies, but with data conflicts as +well. We can't have two independent tasks working on the same data +concurrently, even if the tasks have no dependencies between them. +For this reason, each task locks the data it works on when it begins, +and unlocks the data again once it's finished. Data here refers to the +particle (gas, gravity, stars,...) content of a cell as well as of the +hierarchy of cells in the tree at levels closer to the root that. By +default, it is assumed that the task is doing work on hydro +particles. If your task requires other particle types, you will need +to specify that in ``src/task.c``. Suppose you have implemented a task +with type ``task_type_new`` that requires both stars and hydro +particles: :: + + + /** + * @brief Try to lock the cells associated with this task. + * + * @param t the #task. + */ + int task_lock(struct task *t) { + + const enum task_types type = t->type; + const enum task_subtypes subtype = t->subtype; + struct cell *ci = t->ci, *cj = t->cj; + + switch (type) { + /* lots of stuff */ + + case task_type_new: + + /* is the data locked already? */ + if (ci->hydro.hold || ci->stars.hold) return 0; + + /* if it's not locked already, lock first particle type (hydro) + * if something locked it in the meantime, exit with failure. */ + if (cell_locktree(ci) != 0) return 0; + + /* if it's not locked already, lock first particle type (stars) + * if something locked it in the meantime, first unlock what you + * locked, and then exit with failure. */ + if (cell_slocktree(ci) != 0) { + cell_unlocktree(ci); + return 0; + } + + /* lots of other stuff */ + } + + /* lots of other stuff */ + + } + + + +Similarly, don't forget to write your unlocking routines in ``task_unlock()`` !