aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--03_threads/index.html2
-rw-r--r--03_threads/program.mjs2
-rwxr-xr-x04_no_block/build.sh6
-rw-r--r--04_no_block/index.html19
-rw-r--r--04_no_block/mime.txt1
-rw-r--r--04_no_block/primes.c53
-rwxr-xr-x04_no_block/run-server.sh6
-rw-r--r--04_no_block/script.mjs14
-rw-r--r--04_no_block/worker.mjs8
-rwxr-xr-x05_callback/build.sh8
-rw-r--r--05_callback/index.html19
-rw-r--r--05_callback/mime.txt1
-rw-r--r--05_callback/primes.c55
-rw-r--r--05_callback/program.mjs11
-rwxr-xr-x05_callback/run-node.sh3
-rwxr-xr-x05_callback/run-server.sh7
-rw-r--r--05_callback/script.mjs13
-rw-r--r--05_callback/worker.mjs12
-rw-r--r--README.md12
19 files changed, 250 insertions, 2 deletions
diff --git a/03_threads/index.html b/03_threads/index.html
index 29cfaf8..7a1fba7 100644
--- a/03_threads/index.html
+++ b/03_threads/index.html
@@ -3,7 +3,7 @@
3<head> 3<head>
4 <meta charset="utf-8" /> 4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width" /> 5 <meta name="viewport" content="width=device-width" />
6 <title>Multiply two numbers</title> 6 <title>Primes in a range</title>
7 <script src="./script.mjs" type="module" defer></script> 7 <script src="./script.mjs" type="module" defer></script>
8</head> 8</head>
9 9
diff --git a/03_threads/program.mjs b/03_threads/program.mjs
index a5a89ce..db0a2c6 100644
--- a/03_threads/program.mjs
+++ b/03_threads/program.mjs
@@ -3,4 +3,4 @@ import Primes from "./build/primes.mjs"
3var primes = await Primes(); 3var primes = await Primes();
4 4
5const count = primes._primes_in_range(1, 100); 5const count = primes._primes_in_range(1, 100);
6console.log("There are " + count + " primes betwees 1 and 100"); 6console.log("There are " + count + " primes between 1 and 100");
diff --git a/04_no_block/build.sh b/04_no_block/build.sh
new file mode 100755
index 0000000..2f08909
--- /dev/null
+++ b/04_no_block/build.sh
@@ -0,0 +1,6 @@
1#!/bin/sh
2
3mkdir -p build
4emcc -sEXPORTED_FUNCTIONS=_primes_in_range -sMODULARIZE -sEXPORT_NAME=Primes \
5 -pthread -sPTHREAD_POOL_SIZE=16 \
6 -o build/primes.mjs primes.c
diff --git a/04_no_block/index.html b/04_no_block/index.html
new file mode 100644
index 0000000..7a1fba7
--- /dev/null
+++ b/04_no_block/index.html
@@ -0,0 +1,19 @@
1<!doctype html>
2<html lang="en-US">
3<head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width" />
6 <title>Primes in a range</title>
7 <script src="./script.mjs" type="module" defer></script>
8</head>
9
10<body>
11 <label for="aInput">Lower bound (included)</label><br />
12 <input id="aInput" name="aInput" /> x <br />
13 <label for="bInput">Upper bound (excluded)</label><br />
14 <input id="bInput" name="bInput" /> <br />
15 <button id="goButton">Compute</button> <br />
16 <p id="resultText"></p>
17</body>
18
19</html>
diff --git a/04_no_block/mime.txt b/04_no_block/mime.txt
new file mode 100644
index 0000000..6a9a425
--- /dev/null
+++ b/04_no_block/mime.txt
@@ -0,0 +1 @@
text/javascript mjs
diff --git a/04_no_block/primes.c b/04_no_block/primes.c
new file mode 100644
index 0000000..a5076c6
--- /dev/null
+++ b/04_no_block/primes.c
@@ -0,0 +1,53 @@
1#include <stdbool.h>
2#include <pthread.h>
3
4#define NTHREADS 16
5
6bool isprime(int);
7void *pthread_routine(void *);
8
9struct interval { int low; int high; int count; };
10
11int primes_in_range(int low, int high) {
12 pthread_t threads[NTHREADS];
13 struct interval args[NTHREADS];
14
15 if (low < 0 || high < low)
16 return 0;
17
18 int interval_size = (high-low)/NTHREADS + 1;
19 for (int i = 0; i < NTHREADS; i++) {
20 args[i].low = low + i*interval_size;
21 args[i].high = args[i].low + interval_size;
22 pthread_create(&threads[i], NULL, pthread_routine, &args[i]);
23 }
24
25 int result = 0;
26 for (int i = 0; i < NTHREADS; i++) {
27 pthread_join(threads[i], NULL);
28 result += args[i].count;
29 }
30
31 return result;
32}
33
34bool isprime(int n) {
35 if (n < 2)
36 return false;
37
38 for (int i = 2; i*i <= n; i++)
39 if (n % i == 0)
40 return false;
41 return true;
42}
43
44void *pthread_routine(void *arg) {
45 struct interval *interval = arg;
46
47 interval->count = 0;
48 for (int i = interval->low; i < interval->high; i++)
49 if (isprime(i))
50 interval->count++;
51
52 return NULL;
53}
diff --git a/04_no_block/run-server.sh b/04_no_block/run-server.sh
new file mode 100755
index 0000000..3a526f3
--- /dev/null
+++ b/04_no_block/run-server.sh
@@ -0,0 +1,6 @@
1#!/bin/sh
2
3darkhttpd . \
4 --mimetypes mime.txt \
5 --header 'Cross-Origin-Opener-Policy: same-origin' \
6 --header 'Cross-Origin-Embedder-Policy: require-corp'
diff --git a/04_no_block/script.mjs b/04_no_block/script.mjs
new file mode 100644
index 0000000..b9c27ea
--- /dev/null
+++ b/04_no_block/script.mjs
@@ -0,0 +1,14 @@
1var aInput = document.getElementById("aInput");
2var bInput = document.getElementById("bInput");
3var button = document.getElementById("goButton");
4var resultText = document.getElementById("resultText");
5
6var worker = new Worker("./worker.mjs", { type: "module" });
7
8button.addEventListener("click", () => worker.postMessage({
9 a: Number(aInput.value),
10 b: Number(bInput.value)
11}));
12
13worker.onmessage = (e) => resultText.innerText = "There are " +
14 e.data.result + " primes between " + e.data.a + " and " + e.data.b;
diff --git a/04_no_block/worker.mjs b/04_no_block/worker.mjs
new file mode 100644
index 0000000..6476203
--- /dev/null
+++ b/04_no_block/worker.mjs
@@ -0,0 +1,8 @@
1import Primes from "./build/primes.mjs";
2
3var primes = await Primes();
4
5onmessage = (e) => {
6 const count = primes._primes_in_range(e.data.a, e.data.b);
7 postMessage({ result: count, a: e.data.a, b: e.data.b });
8};
diff --git a/05_callback/build.sh b/05_callback/build.sh
new file mode 100755
index 0000000..998ebd1
--- /dev/null
+++ b/05_callback/build.sh
@@ -0,0 +1,8 @@
1#!/bin/sh
2
3mkdir -p build
4emcc -sEXPORTED_FUNCTIONS=_primes_in_range -sMODULARIZE -sEXPORT_NAME=Primes \
5 -sEXPORTED_RUNTIME_METHODS=addFunction,UTF8ToString \
6 -sALLOW_TABLE_GROWTH \
7 -pthread -sPTHREAD_POOL_SIZE=16 \
8 -o build/primes.mjs primes.c
diff --git a/05_callback/index.html b/05_callback/index.html
new file mode 100644
index 0000000..7a1fba7
--- /dev/null
+++ b/05_callback/index.html
@@ -0,0 +1,19 @@
1<!doctype html>
2<html lang="en-US">
3<head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width" />
6 <title>Primes in a range</title>
7 <script src="./script.mjs" type="module" defer></script>
8</head>
9
10<body>
11 <label for="aInput">Lower bound (included)</label><br />
12 <input id="aInput" name="aInput" /> x <br />
13 <label for="bInput">Upper bound (excluded)</label><br />
14 <input id="bInput" name="bInput" /> <br />
15 <button id="goButton">Compute</button> <br />
16 <p id="resultText"></p>
17</body>
18
19</html>
diff --git a/05_callback/mime.txt b/05_callback/mime.txt
new file mode 100644
index 0000000..6a9a425
--- /dev/null
+++ b/05_callback/mime.txt
@@ -0,0 +1 @@
text/javascript mjs
diff --git a/05_callback/primes.c b/05_callback/primes.c
new file mode 100644
index 0000000..f581161
--- /dev/null
+++ b/05_callback/primes.c
@@ -0,0 +1,55 @@
1#include <stdbool.h>
2#include <pthread.h>
3
4#define NTHREADS 16
5
6bool isprime(int);
7void *pthread_routine(void *);
8
9struct interval { int low; int high; int count; };
10
11int primes_in_range(int low, int high, void (*log)(const char *)) {
12 pthread_t threads[NTHREADS];
13 struct interval args[NTHREADS];
14
15 if (low < 0 || high < low)
16 return 0;
17
18 int interval_size = (high-low)/NTHREADS + 1;
19 for (int i = 0; i < NTHREADS; i++) {
20 args[i].low = low + i*interval_size;
21 args[i].high = args[i].low + interval_size;
22 pthread_create(&threads[i], NULL, pthread_routine, &args[i]);
23 }
24
25 log("All threads have started, computing...");
26
27 int result = 0;
28 for (int i = 0; i < NTHREADS; i++) {
29 pthread_join(threads[i], NULL);
30 result += args[i].count;
31 }
32
33 return result;
34}
35
36bool isprime(int n) {
37 if (n < 2)
38 return false;
39
40 for (int i = 2; i*i <= n; i++)
41 if (n % i == 0)
42 return false;
43 return true;
44}
45
46void *pthread_routine(void *arg) {
47 struct interval *interval = arg;
48
49 interval->count = 0;
50 for (int i = interval->low; i < interval->high; i++)
51 if (isprime(i))
52 interval->count++;
53
54 return NULL;
55}
diff --git a/05_callback/program.mjs b/05_callback/program.mjs
new file mode 100644
index 0000000..fd85a58
--- /dev/null
+++ b/05_callback/program.mjs
@@ -0,0 +1,11 @@
1import Primes from "./build/primes.mjs"
2
3var primes = await Primes();
4const logPtr = primes.addFunction((cstr) => {
5 console.log(primes.UTF8ToString(cstr));
6}, 'vp');
7
8const a = 1;
9const b = 10000000;
10const count = primes._primes_in_range(a, b, logPtr);
11console.log("There are " + count + " primes between " + a + " and " + b);
diff --git a/05_callback/run-node.sh b/05_callback/run-node.sh
new file mode 100755
index 0000000..a6c9aa8
--- /dev/null
+++ b/05_callback/run-node.sh
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3node program.mjs
diff --git a/05_callback/run-server.sh b/05_callback/run-server.sh
new file mode 100755
index 0000000..6e75760
--- /dev/null
+++ b/05_callback/run-server.sh
@@ -0,0 +1,7 @@
1#!/bin/sh
2
3darkhttpd . \
4--port 8082 \
5 --mimetypes mime.txt \
6 --header 'Cross-Origin-Opener-Policy: same-origin' \
7 --header 'Cross-Origin-Embedder-Policy: require-corp'
diff --git a/05_callback/script.mjs b/05_callback/script.mjs
new file mode 100644
index 0000000..9fce6fe
--- /dev/null
+++ b/05_callback/script.mjs
@@ -0,0 +1,13 @@
1var aInput = document.getElementById("aInput");
2var bInput = document.getElementById("bInput");
3var button = document.getElementById("goButton");
4var resultText = document.getElementById("resultText");
5
6var worker = new Worker("./worker.mjs", { type: "module" });
7
8button.addEventListener("click", () => worker.postMessage({
9 a: Number(aInput.value),
10 b: Number(bInput.value)
11}));
12
13worker.onmessage = (e) => resultText.innerText = e.data.message;
diff --git a/05_callback/worker.mjs b/05_callback/worker.mjs
new file mode 100644
index 0000000..736e9f8
--- /dev/null
+++ b/05_callback/worker.mjs
@@ -0,0 +1,12 @@
1import Primes from "./build/primes.mjs";
2
3var primes = await Primes();
4const logPtr = primes.addFunction((cstr) => {
5 postMessage({ message: primes.UTF8ToString(cstr) });
6}, "vp");
7
8onmessage = (e) => {
9 const count = primes._primes_in_range(e.data.a, e.data.b, logPtr);
10 postMessage({ message: "There are " + count + " primes between " +
11 e.data.a + " and " + e.data.b });
12};
diff --git a/README.md b/README.md
index 4326298..582cd4d 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,9 @@ scripts, for convenience:
24 [localhost:8080](http://localhost:8080) running an example web page 24 [localhost:8080](http://localhost:8080) running an example web page
25 (require darkhttpd, see below). 25 (require darkhttpd, see below).
26 26
27If one of the `run-*` scripts is missing, it means that that example
28is only meant to run in Node.js, or only as a script in a web page.
29
27The examples have been tested only on Linux, but should work on any 30The examples have been tested only on Linux, but should work on any
28UNIX system, and should be easy to adapt to Windows or other OSes. 31UNIX system, and should be easy to adapt to Windows or other OSes.
29Pull requests are welcome. 32Pull requests are welcome.
@@ -63,3 +66,12 @@ In `03_threads` we build a more complicated example based on
63[pthreads](https://en.wikipedia.org/wiki/Pthreads). To run this 66[pthreads](https://en.wikipedia.org/wiki/Pthreads). To run this
64example, the web server has to be configured to provide the correct 67example, the web server has to be configured to provide the correct
65`Cross-Origin-*` headers, see `03_threads/run-server.sh` for details. 68`Cross-Origin-*` headers, see `03_threads/run-server.sh` for details.
69
70## 4. Don't block the main thread
71
72In `04_no_block` we avoid our calculations blocking the main browser
73thread by using a web worker.
74
75## 5. Callback functions
76
77In `05_callback` the example is extended to include a callback function.

Generated with cgit - Back to sebastiano.tronto.net