File: native-api.txt

package info (click to toggle)
massivethreads 1.02-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,924 kB
  • sloc: ansic: 27,814; sh: 4,559; cpp: 3,334; javascript: 1,799; makefile: 1,745; python: 523; asm: 373; perl: 118; lisp: 9
file content (139 lines) | stat: -rw-r--r-- 5,690 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
* About:
native API is a collection of functions with a prefix "myth_". With native API, you can use full functionalities of MassiveThreads such as work stealing strategy customization.

* Tutorial:

** How to compile and link with native API:

Please include myth.h in ${prefix}/include and link libmyth.so or libmyth-native.so in ${prefix}/lib.
${prefix} shows a directory where MassiveThreads is installed. Please change accordingly.

Example:

$ cat foo.c
#include <myth.h>
int main(int argc,char **argv)
{
  myth_init();
  printf("Hello, MassiveThreads!\n");
  myth_fini();
  return 0;
}

$ gcc -o foo foo.c -I${prefix}/include -L${prefix}/lib -lmyth 

** Initialization and cleanup

Before calling main function, the MassiveThreads library is automatically initialized with a default configuration, thus explicit initialization is not essentially needed. By calling initialization function explicitly, several paramteres can be controlled from application.

myth_init initializes the library with a default configuration, and myth_init_withparam takes the number of worker threads and the default stack size.

The order of priority is the following: 
1.myth_init_withparam arguments
2.environmental variables
3.built-in values

Similarly, explicit cleanup is not needed because the MassiveThreads library is automaticaly cleaned up after main function is finished. But programmers can do it explicitly by calling a function myth_fini.

Examples:

/*
 * The simplest example
 * Explicit initialization/cleanup are not needed
 */
int main(int argc, chart **argv)
{
  /* Do something here */
  return 0;
}

/* Explicit initialization with specifying the number of workers and stack size manually */
int main(int argc, chart **argv)
{
  int n_workers;
  size_t stack_size;
  n_workers=atoi(argv[1]);
  stack_size=(size_t)atoi(argv[2]);
  myth_init_withparam(n_workers,stack_size);
  /* Do something here */
  myth_fini();
  return 0;
}

** Thread creation and termination

myth_create and myth_create_ex are functions to create a new thread.
myth_create creates a new thread and calls an entry point function. On success it returns a handle of new thread, otherwise NULL is returned.

myth_create_ex takes an extra argument of structure myth_thread_option which describes the configuration of a thread to be created. By filling the structure, the following parameters can be configured.
* stack_size         : Stack size in bytes
* swtich_immediately : Execution strategy (0: help-first, others:work-first) 
* custom_data_size   : The size of the hint data (described later)
* custom_data        : Initial data of the hint

myth_join is a function to wait for the termination of a thread. It takes two arguments: a handle to thread and a pointer to store the return value of the entry point function. If return value is not needed, NULL can be specified as second argument.

myth_detach is a function to release the resource of the thread after it is finished.   

These semantics are similar to those of pthread. Specifically, myth_detach or myth_join must be called ONCE for every thread.

Example:

/* Create threads recursively */
void *threadfn(void* arg)
{
	myth_thread_t th[2];
	int i;
	int depth=(int)arg;
	if (depth<=0) return NULL;
	for (i=0;i<2;i++){
		th[i]=myth_create(threadfn,(void*)(depth-1));
	}
	for (i=0;i<2;i++){
		myth_join(th[i],NULL);
	}
	return NULL;
}

* Thread and worker properties

The MassiveThreads library provides 3 functions to acquire properties of thread and its underlying worker thread.
myth_get_worker_num returns an ID of the underlying worker thread of the current thread.
myth_get_num_workers returns the number of worker threads.
myth_self returns a handle of the current thread. 

* Work stealing strategy customization

Programmers can customize the strategy of work stealing by implementing an user-defined callback function invoked on work stealing. Typically, an user-defined work stealing function is implemented by the following 5 steps:

1. Select the candidates of worker threads to steal
2. Read hint data of tasks that are available from candidates
3. Choose one candidate as target of work stealing
3. Try to steal
4. (Optional) commit the steal if an actually stolen task is good to be executed 

The following subsections describe building blocks to implement a customized work stealing function.

** Thread-local hint data

Prgrammers can give data for each thread as a hint of work stealing.
myth_wsapi_set_hint function gives hint data to a thread and returns the previous hint data.
myth_create_ex can also be used to give hint data. (see "Thread creation and termination")

myth_wsapi_get_hint_ptr returns a pointer to the hint data. Similarly, myth_wsapi_get_hint_size returns a size of the hint.

** Candidate selection

myth_wsapi_rand gives a random integer from 0 to (myth_get_num_workers()-1).
myth_wsapi_randarr gives a non-duplicated list of random integers from 0 to (myth_get_num_workers()-1).

** Runqueue operation

myth_wsapi_runqueue_peek reads a hint from a task which can be stolen from the specified worker thread, and returns a copy of it.

myth_wsapi_runquque_take tries to steal a task from the specified victim. Programmers can also specify a user-defined callback function which is called when the steal attempt is about to be succeeded. The purpose of the callback function is to check whether an actually stolen task is good to be executed on the worker thread. If the function returns non-zero, the steal is committed, otherwise it is cancelled.

** Work stealing function override

By calling myth_wsapi_set_stealfunc, programmers can override the default work stealing function to user-defined one.