summaryrefslogtreecommitdiff
path: root/ccan/antithread/_info
blob: 7bde2018a025514aafd90e84b371aa1db03fa075 (plain)
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
#include "config.h"
#include <stdio.h>
#include <string.h>

/**
 * antithread - Accelerated Native Technology Implementation of "threads"
 *
 * On systems with multiple CPUs, it's often faster to split work across
 * different execution units.  Under Unix-like systems, the two methods of
 * doing this are (POSIX) threads or processes.
 *
 * Threads have the disadvantage that they share all of the address space:
 * using software instead of hardware isolation (eg. for malloc) is
 * inefficient and less secure.  Various subtle errors can occur because
 * programmers in one part of the code do not expect concurrency.
 *
 * Processes have the disadvantage that there is no common infrastructure
 * for sharing memory: without this, programmers are faced with the unpalatable
 * options of using slower options or creating their own infrastructure.
 *
 * The antithread module provides memory-sharing infrastructure: the programmer
 * indicates the size of the memory to share, and then creates subprocesses
 * which share the memory.  Pipes are used to hand pointers between the
 * main process and the children: usually pointers into the shared memory.
 *
 * Example:
 *	#include <ccan/antithread/antithread.h>
 *	#include <ccan/talloc/talloc.h>
 *	#include <ctype.h>
 *	#include <stdlib.h>
 *	#include <stdio.h>
 *	#include <string.h>
 *	
 *	// Silly example: child makes rot13 copy.
 *	static void *rot13(struct at_pool *pool, void *unused)
 *	{
 *		char *r, *p;
 *		while ((r = at_read_parent(pool)) != NULL) {
 *			unsigned int i;
 *			// r is inside pool, so talloc off it is also inside.
 *			p = talloc_array(r, char, strlen(r) + 1);
 *			for (i = 0; r[i]; i++) {
 *				if (!isalpha(r[i]))
 *					p[i] = r[i];
 *				else if (toupper(r[i]) < 'N')
 *					p[i] = r[i] + 13;
 *				else
 *					p[i] = r[i] - 13;
 *			}
 *			// Tell parent about our copy.
 *			at_tell_parent(pool, p);
 *		}
 *		return NULL;
 *	}
 *	
 *	#define NUM_CHILDREN 4
 *	
 *	int main(int argc, char *argv[])
 *	{
 *		struct at_pool *pool;
 *		struct athread *child[NUM_CHILDREN];
 *		unsigned int i;
 *	
 *		// Create pool and some children
 *		pool = at_pool(1024*1024);
 *		for (i = 0; i < NUM_CHILDREN; i++)
 *			child[i] = at_run(pool, rot13, NULL);
 *	
 *		// Pass out work to children.
 *		for (i = 1; i < argc; i++)
 *			at_tell(child[i % NUM_CHILDREN],
 *				talloc_strdup(at_pool_ctx(pool), argv[i]));
 *	
 *		// Read back results.
 *		for (i = 1; i < argc; i++)
 *			printf("%s ", (char *)at_read(child[i % NUM_CHILDREN]));
 *		printf("\n");
 *	
 *		// Freeing pool kills children, too.
 *		talloc_free(pool);
 *		return 0;
 *	}
 *
 * License: GPL (v3 or any later version)
 * Author: Rusty Russell <rusty@rustcorp.com.au>
 */
int main(int argc, char *argv[])
{
	if (argc != 2)
		return 1;

	if (strcmp(argv[1], "depends") == 0) {
		printf("ccan/antithread/alloc\n");
		printf("ccan/err\n");
		printf("ccan/list\n");
		printf("ccan/noerr\n");
		printf("ccan/read_write_all\n"); /* For tests */
		printf("ccan/talloc\n");
		printf("ccan/typesafe_cb\n");
		return 0;
	}

	return 1;
}