File: test_pthread_reltime.cpp

package info (click to toggle)
emscripten 3.1.69%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 121,872 kB
  • sloc: ansic: 636,110; cpp: 425,974; javascript: 78,401; python: 58,404; sh: 49,154; pascal: 5,237; makefile: 3,365; asm: 2,415; lisp: 1,869
file content (79 lines) | stat: -rw-r--r-- 2,049 bytes parent folder | download | duplicates (2)
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
// Copyright 2019 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <iostream>
#include <ctime>
#include <cassert>
#include <condition_variable>
#include <pthread.h>
#include <emscripten.h>

static long now() {
  struct timespec time;
  clock_gettime(CLOCK_MONOTONIC, &time);
  return time.tv_sec * 1000 + time.tv_nsec / 1000 / 1000;
}

static long ping, pong;

static std::mutex mutex;
static std::condition_variable cond_var;
static bool pong_requested = false;

void *thread_main(void *arg) {
  std::cout << "running thread ..." << std::endl;

  std::unique_lock<std::mutex> lock(mutex);
  while (!pong_requested)
    cond_var.wait(lock);
  pong = now(); // Measure time in the pthread
  std::cout << "pong - ping: " << (pong - ping) << std::endl;
  pong_requested = false;
  cond_var.notify_one();

  return NULL;
}

EMSCRIPTEN_KEEPALIVE
extern "C" int notify() {
  {
    std::unique_lock<std::mutex> lock(mutex);
    std::cout << "notifying ..." << std::endl;
    ping = now();
    pong_requested = true;
    cond_var.notify_one();
  }

  {
    std::unique_lock<std::mutex> lock(mutex);
    while (pong_requested)
      cond_var.wait(lock);
    long last = now();
    std::cout << "last - pong: " << (last - ping) << std::endl;

    // Time measured on a worker should be relative to the main thread,
    // so that things are basically monotonic.
    assert((int(pong >= ping) + 2 * int(last >= pong)) == 3);
    emscripten_force_exit(0);
  }

  return 0;
}

int main() {
  std::cout << "running main ..." << std::endl;

  EM_ASM(setTimeout(() => Module._notify()));

  pthread_attr_t attr;
  pthread_attr_init(&attr);

  pthread_t thread;
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  int error = pthread_create(&thread, &attr, thread_main, NULL);
  assert(!error);
  emscripten_exit_with_live_runtime();
  __builtin_trap();
}