Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 51 additions & 51 deletions test/pthread/test_pthread_barrier.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,63 +20,63 @@ int intermediate[N] = {};
pthread_barrier_t barr;

// Sums a single row of a matrix.
int sum_row(long r)
{
int sum = 0;
for(int i = 0; i < N; ++i)
sum += matrix[r][i];
return sum;
int sum_row(long r) {
int sum = 0;
for (int i = 0; i < N; ++i) {
sum += matrix[r][i];
}
return sum;
}

void *thread_main(void *arg)
{
// Each thread sums individual rows.
long id = (long)arg;
for(long i = id; i < N; i += THREADS)
intermediate[i] = sum_row(i);

// Synchronization point
int rc = pthread_barrier_wait(&barr);
if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)
{
printf("Could not wait on barrier\n");
exit(-1);
}
void* thread_main(void* arg) {
// Each thread sums individual rows.
long id = (long)arg;
for (long i = id; i < N; i += THREADS) {
intermediate[i] = sum_row(i);
}

// Synchronization point
int rc = pthread_barrier_wait(&barr);
if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
printf("Could not wait on barrier\n");
exit(-1);
}

// Then each thread sums the one intermediate vector.
intptr_t totalSum = 0;
for(int i = 0; i < N; ++i)
totalSum += intermediate[i];
// Then each thread sums the one intermediate vector.
intptr_t totalSum = 0;
for (int i = 0; i < N; ++i) {
totalSum += intermediate[i];
}

pthread_exit((void*)totalSum);
pthread_exit((void*)totalSum);
}

int main(int argc, char **argv)
{
pthread_t thr[THREADS];

// Create the matrix and compute the expected result.
int expectedTotalSum = 0;
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
{
matrix[i][j] = rand();
expectedTotalSum += matrix[i][j];
}
printf("The sum of the matrix is %d.\n", expectedTotalSum);

// Barrier initialization
int ret = pthread_barrier_init(&barr, NULL, THREADS);
assert(ret == 0);

for(intptr_t i = 0; i < THREADS; ++i) {
pthread_create(&thr[i], NULL, &thread_main, (void*)i);
}
for(int i = 0; i < THREADS; ++i) {
int totalSum = 0;
pthread_join(thr[i], (void**)&totalSum);
assert(totalSum == expectedTotalSum);
int main(int argc, char** argv) {
pthread_t thr[THREADS];

// Create the matrix and compute the expected result.
int expectedTotalSum = 0;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
matrix[i][j] = rand();
expectedTotalSum += matrix[i][j];
}
}
printf("The sum of the matrix is %d.\n", expectedTotalSum);

// Barrier initialization
int ret = pthread_barrier_init(&barr, NULL, THREADS);
assert(ret == 0);

for (intptr_t i = 0; i < THREADS; ++i) {
pthread_create(&thr[i], NULL, &thread_main, (void*)i);
}

for (int i = 0; i < THREADS; ++i) {
int totalSum = 0;
pthread_join(thr[i], (void**)&totalSum);
assert(totalSum == expectedTotalSum);
}

return 0;
return 0;
}
9 changes: 3 additions & 6 deletions test/pthread/test_pthread_condition_variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ int thread_ids[3] = {0,1,2};
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;

void *inc_count(void *t)
{
void* inc_count(void* t) {
int i;
long my_id = (long)t;

Expand All @@ -44,8 +43,7 @@ void *inc_count(void *t)
pthread_exit(NULL);
}

void *watch_count(void *t)
{
void *watch_count(void *t) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this new style doesn't match inc_count above.

long my_id = (long)t;

emscripten_outf("Starting watch_count(): thread %ld\n", my_id);
Expand All @@ -68,8 +66,7 @@ void *watch_count(void *t)
pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
int main (int argc, char *argv[]) {
int i, rc;
long t1=1, t2=2, t3=3;
pthread_t threads[3];
Expand Down
11 changes: 5 additions & 6 deletions test/pthread/test_pthread_gcc_atomics.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// See https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Atomic-Builtins.html

#define NUM_THREADS 8
#define NUM_THREADS_ODD (NUM_THREADS-1)

#define T int

Expand Down Expand Up @@ -71,13 +72,12 @@ int main() {
T y = nand_and_fetch(&x, 9);
assert(y == -2);
assert(x == -2);
const int oddNThreads = NUM_THREADS-1;
for (int x = 0; x < 100; ++x) { // Test a few times for robustness, since this test is so short-lived.
nand_and_fetch_data = 0;
__sync_synchronize(); // This has no effect in this code, but called in here just to test that the compiler generates a valid expression for this.
if (emscripten_has_threading_support()) {
for (int i = 0; i < oddNThreads; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch, (void*)-1);
for (int i = 0; i < oddNThreads; ++i) pthread_join(thread[i], NULL);
for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch, (void*)-1);
for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_join(thread[i], NULL);
assert(nand_and_fetch_data == -1);
}
}
Expand All @@ -87,12 +87,11 @@ int main() {
T y = nand_and_fetch_bool(&x, 9);
assert(y == -2);
assert(x == -2);
const int oddNThreads = NUM_THREADS-1;
for (int x = 0; x < 100; ++x) { // Test a few times for robustness, since this test is so short-lived.
nand_and_fetch_data = 0;
if (emscripten_has_threading_support()) {
for (int i = 0; i < oddNThreads; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch_bool, (void*)-1);
for (int i = 0; i < oddNThreads; ++i) pthread_join(thread[i], NULL);
for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_create(&thread[i], NULL, thread_nand_and_fetch_bool, (void*)-1);
for (int i = 0; i < NUM_THREADS_ODD; ++i) pthread_join(thread[i], NULL);
assert(nand_and_fetch_data == -1);
}
}
Expand Down
15 changes: 8 additions & 7 deletions test/pthread/test_pthread_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ int main (int argc, char *argv[]) {
locale_t main_loc = do_test();
locale_t child_loc;

if (emscripten_has_threading_support()) {
long id = 1;
pthread_t thread;
pthread_t thread;
int rtn;

pthread_create(&thread, NULL, thread_test, (void *)id);
rtn = pthread_create(&thread, NULL, thread_test, (void *)NULL);
printf("create: %d\n", rtn);
assert(!rtn);
rtn = pthread_join(thread, (void**)&child_loc);
assert(!rtn);

pthread_join(thread, (void**)&child_loc);
assert(main_loc == child_loc);
}
assert(main_loc == child_loc);

return 0;
}
11 changes: 5 additions & 6 deletions test/pthread/test_pthread_once.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
#include <emscripten.h>
#include <emscripten/threading.h>

_Atomic int numInitialized = 0;
int numInitialized = 0;

void once_init() {
numInitialized++;
}

#define NUM_THREADS 8

void *thread_main(void *arg)
{
void *thread_main(void *arg) {
static pthread_once_t control = PTHREAD_ONCE_INIT;
pthread_once(&control, &once_init);
assert(numInitialized == 1);
Expand All @@ -33,10 +32,10 @@ int main() {
pthread_create(&thread[i], NULL, thread_main, 0);
}

if (emscripten_has_threading_support()) {
for(int i = 0; i < NUM_THREADS; ++i) pthread_join(thread[i], NULL);
assert(numInitialized == 1);
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(thread[i], NULL);
}
assert(numInitialized == 1);

return 0;
}
64 changes: 28 additions & 36 deletions test/pthread/test_pthread_proxy_hammer.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,44 @@
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <emscripten.h>
#include <stdio.h>

class random_device
{
int __f_;
public:
// constructors
explicit random_device();
~random_device();

// generating functions
unsigned operator()();
};
class random_device {
int __f_;

random_device::random_device()
{
public:
// constructors
explicit random_device() {
__f_ = open("/dev/urandom", O_RDONLY);
if (__f_ < 0) abort();
}
assert(__f_ >= 0);
}

random_device::~random_device()
{
~random_device() {
close(__f_);
}
}

unsigned
random_device::operator()()
{
unsigned r;
size_t n = sizeof(r);
char* p = reinterpret_cast<char*>(&r);
while (n > 0)
{
ssize_t s = read(__f_, p, 1);
if (s == 0) abort();
if (s == -1)
{
if (errno != EINTR) abort();
continue;
}
n -= static_cast<size_t>(s);
p += static_cast<size_t>(s);
// generating functions
unsigned operator()();
};

unsigned random_device::operator()() {
unsigned r;
size_t n = sizeof(r);
char* p = reinterpret_cast<char*>(&r);
while (n > 0) {
ssize_t s = read(__f_, p, 1);
assert(s > 0);
if (s == -1) {
assert(errno == EINTR);
continue;
}
return r;
n -= static_cast<size_t>(s);
p += static_cast<size_t>(s);
}
return r;
}

int main() {
Expand Down
68 changes: 33 additions & 35 deletions test/pthread/test_pthread_proxying_in_futex_wait.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,40 @@
#include <assert.h>

_Atomic uint32_t main_thread_wait_val = 1;
_Atomic int result = 1;
_Atomic bool thread_done = false;

void *ThreadMain(void *arg)
{
for(int i = 0; i < 10; ++i)
{
char str[256];
sprintf(str, "file%d.txt", i);
printf("Writing file %s..\n", str); // Prints out to page console, this is a proxied operation.
FILE *handle = fopen(str, "w"); // fopen, fputs and fclose are currently proxied operations too (although hopefully not in the future)
fputs(str, handle);
fclose(handle);
}
main_thread_wait_val = 0;
emscripten_futex_wake(&main_thread_wait_val, 1);
result = 0;
pthread_exit(0);
void* ThreadMain(void* arg) {
for (int i = 0; i < 10; ++i) {
char str[256];
sprintf(str, "file%d.txt", i);
// Prints out to page console, this is a proxied operation.
printf("Writing file %s..\n", str);
// fopen, fputs and fclose are currently proxied operations too (although hopefully not in the future)
FILE* handle = fopen(str, "w");
fputs(str, handle);
fclose(handle);
}
main_thread_wait_val = 0;
emscripten_futex_wake(&main_thread_wait_val, 1);
thread_done = true;
return NULL;
}

int main()
{
pthread_t thread;
int rc = pthread_create(&thread, NULL, ThreadMain, 0);
assert(rc == 0);
while (main_thread_wait_val != 0) {
rc = emscripten_futex_wait(&main_thread_wait_val, 1, 15 * 1000);
// An rc of 0 means no error, and of EWOULDBLOCK means that the value is
// not the expected one, which can happen if the pthread manages to set it
// before we reach the futex_wait.
if (rc != 0 && rc != -EWOULDBLOCK)
{
printf("ERROR! futex wait errored %d!\n", rc);
return 2;
}
}
pthread_join(thread, 0);

return result;
int main() {
pthread_t thread;
int rc = pthread_create(&thread, NULL, ThreadMain, 0);
assert(rc == 0);
while (main_thread_wait_val != 0) {
rc = emscripten_futex_wait(&main_thread_wait_val, 1, 15 * 1000);
// An rc of 0 means no error, and of EWOULDBLOCK means that the value is
// not the expected one, which can happen if the pthread manages to set it
// before we reach the futex_wait.
if (rc != 0 && rc != -EWOULDBLOCK) {
printf("ERROR! futex wait errored %d!\n", rc);
return 2;
}
}
pthread_join(thread, 0);
assert(thread_done);
return 0;
}
Loading
Loading