Shared memory

class ttor::Threadpool_shared

A set of threads continuously running tasks.

This class represents a set (pool) of threads. Threads in the threadpool continuously receive tasks to run, store them in a queue and run the first one. In general, threads can steal tasks from one another. Once created, a threadpool is started and run until all queues are empty and all tasks are done running.

Subclassed by ttor::Threadpool_dist

Public Functions

Threadpool_shared(int n_threads, int verb = 0, std::string basename = "Wk_", bool start_immediately = true)

Creates a threadpool with a certain number of threads.

Parameters
  • [in] n_threads: the number of threads in the threadpool

  • [in] verb: verbosity level. 0 is quiet, > 0 prints more and more informations to stdout

  • [in] basename: used in logging, this will be used to identify this threadpool

  • [in] start_immediately: if true, the threadpool starts immediately. Otherwise, user is reponsible for calling tp.start() before joining.

void start()

Starts the threadpool.

Should not be called if the threadpool was created with the option start_immediately set to true.

void insert(Task *t, int where, bool binding = false)

Inserts a task.

Inserts a task on a given thread. By default the task can be stolen by another thread, unless binding is set to true.

Parameters
  • [in] t: a pointer to the task to insert. The task ownership is taken by the threadpool and the task will be freed when done.

  • [in] where: the thread to insert the task on

  • [in] binding: if true, the task cannot be stolen by another thread.

void join()

Join all the threads.

This function returns when all threads are finished and have joined with the master thread. All threads are finished when all task queues are empty and no task are currently in the threadpool.

bool is_done()

Wether the threadpool is idle or not.

Return

true if all queues are empty and no tasks are running, false otherwise.

void set_logger(Logger *logger)

Attach a logger.

Parameters
  • [in] logger: a pointer to the Logger. Logger ownership is left to the user.

int size()

The number of threads.

Return

the number of threads in the threadpool.

template<class K>
class ttor::Taskflow

A parametrized task graph.

This represents a parametrized task graph. K is the index with which to index tasks.

Task k is defined by

The Taskflow is reponsible of maniging dependencies, and will automatically run tasks when their dependency count reaches 0. The Taskflow is associated to a Threadpool_shared in which tasks will be inserted.

Public Functions

Taskflow(Threadpool_shared *tp_, int verb_ = 0)

Creates a Taskflow.

A taskflow is associated with a Threadpool_shared in which task will be inserted. Threadpool_shared should be valid and not destroyed while the Taskflow is used.

Pre

verb >= 0

Pre

tp is a pointer to a valid Threadpool_shared.

Parameters
  • [in] tp: the associated Threadpool_shared.

  • [in] verb: the verbosity level. 0 is quiet, > 0 is more printing.

Task *make_task(K k, int &where, bool &binding)

Creates a task.

Creates and returns a task associated with index k and store its mapped thread and binding value.

Return

A pointer to the new Task. The user is responsible for deleting the task.

Parameters
  • [in] k: index of the task

  • [out] where: on what thread should the task be inserted

  • [out] binding: wether the task should be bound to its thread or not

Taskflow &set_task(std::function<void(K)> f)

Set function f as the task computational routine.

Return

this, the taskflow itself.

Parameters
  • [in] (void)f(K): the function running the computational task for task k

Taskflow &set_fulfill(std::function<void(K)> f)

Set function f as the task fulfill routine.

set_task and set_fulfill are distinct for logging purposes, but perform exactly the same. The fulfill function is always ran immediately after the task function.

Return

this, the taskflow itself.

Parameters
  • [in] (void)f(K): the function fulfilling dependencies for task k

Taskflow &set_mapping(std::function<int(K)> f)

Set function f to be the mapping function, returning the thread of any task k.

Return

this the taskflow itself.

Pre

for all k, 0 <= f(k) < tp.size() with tp the Threadpool_shared.

Parameters
  • [in] (int)f(K): the function returning the mapping for task k.

Taskflow &set_binding(std::function<int(K)> f)

Set function f to be the binding function, returning werther task k should be bound to its thread (i.e., cannot be stolen) or not.

Return

this the taskflow itself.

Parameters
  • [in] (bool)f(K): the function returning the binding for task k.

Taskflow &set_indegree(std::function<int(K)> f)

Set function f to be the indegree function, returning the number of incoming dependencies of task k.

Return

this the taskflow itself.

Pre

for all k, 0 <= f(k).

Parameters
  • [in] (int)f(K): the function returning the in-degree for task k

Taskflow &set_name(std::function<std::string(K)> f)

Set function f to be the name function, returning a descriptive name for task k.

Return

this the taskflow itself.

Parameters
  • [in] (string)f(K): the function returning the name for task k.

Taskflow &set_priority(std::function<double(K)> f)

Set function f to be the priority function, returning the priority (a double) of task k.

When multiple tasks are available for a given thread, tasks with the higher priorities will run first.

Return

this the taskflow itself.

Parameters
  • [in] (double)f(K): the function returning the priority for task k.

std::string name(K k)

Returns the name of task k.

Return

task k name.

Parameters
  • [in] k: the task index.

void fulfill_promise(K k)

Fulfills a promise on a given task.

Fulfills a promise for task k and decrease dependency count for task with index k. If task cannot be found in the task map, create a new entry. If it exists, reduce by 1 the dependency count. If count == 0, insert the task in the ready queue of its mapped thread. Thread-safe.

Parameters
  • [in] k: the task index