1 : /*
2 : * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <pthread.h>
8 : #include <sys/time.h>
9 : #include "native_client/src/shared/platform/nacl_sync.h"
10 : #include "native_client/src/include/nacl_base.h"
11 : #include "native_client/src/include/nacl_macros.h"
12 : #include "native_client/src/trusted/service_runtime/include/sys/time.h"
13 :
14 : static const uint64_t kMicrosecondsPerSecond = 1000 * 1000;
15 : static const uint64_t kNanosecondsPerMicrosecond = 1000;
16 :
17 : /* Condition variable C API */
18 :
19 21719 : int NaClCondVarCtor(struct NaClCondVar *cvp) {
20 21719 : if (0 != pthread_cond_init(&cvp->cv, (pthread_condattr_t *) 0)) {
21 0 : return 0;
22 : }
23 21719 : return 1;
24 21719 : }
25 :
26 20603 : void NaClCondVarDtor(struct NaClCondVar *cvp) {
27 20603 : pthread_cond_destroy(&cvp->cv);
28 20603 : }
29 :
30 43142 : NaClSyncStatus NaClCondVarSignal(struct NaClCondVar *cvp) {
31 43142 : pthread_cond_signal(&cvp->cv);
32 43142 : return NACL_SYNC_OK;
33 : }
34 :
35 1086 : NaClSyncStatus NaClCondVarBroadcast(struct NaClCondVar *cvp) {
36 1086 : pthread_cond_broadcast(&cvp->cv);
37 1086 : return NACL_SYNC_OK;
38 : }
39 :
40 42418 : NaClSyncStatus NaClCondVarWait(struct NaClCondVar *cvp,
41 42418 : struct NaClMutex *mp) {
42 42418 : pthread_cond_wait(&cvp->cv, &mp->mu);
43 42418 : return NACL_SYNC_OK;
44 : }
45 :
46 : NaClSyncStatus NaClCondVarTimedWaitRelative(
47 0 : struct NaClCondVar *cvp,
48 0 : struct NaClMutex *mp,
49 0 : NACL_TIMESPEC_T const *reltime) {
50 0 : uint64_t relative_wait_us =
51 : reltime->tv_sec * kMicrosecondsPerSecond +
52 : reltime->tv_nsec / kNanosecondsPerMicrosecond;
53 0 : uint64_t current_time_us;
54 0 : uint64_t wakeup_time_us;
55 0 : int result;
56 0 : struct timespec ts;
57 0 : struct timeval tv;
58 0 : struct timezone tz = { 0, 0 }; /* UTC */
59 0 : if (gettimeofday(&tv, &tz) == 0) {
60 0 : current_time_us = tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec;
61 0 : } else {
62 0 : return NACL_SYNC_INTERNAL_ERROR;
63 : }
64 0 : wakeup_time_us = current_time_us + relative_wait_us;
65 0 : ts.tv_sec = wakeup_time_us / kMicrosecondsPerSecond;
66 0 : ts.tv_nsec = (wakeup_time_us - ts.tv_sec * kMicrosecondsPerSecond) *
67 : kNanosecondsPerMicrosecond;
68 :
69 0 : result = pthread_cond_timedwait(&cvp->cv, &mp->mu, &ts);
70 0 : if (0 == result) {
71 0 : return NACL_SYNC_OK;
72 : }
73 0 : return NACL_SYNC_CONDVAR_TIMEDOUT;
74 0 : }
75 :
76 : NaClSyncStatus NaClCondVarTimedWaitAbsolute(
77 8 : struct NaClCondVar *cvp,
78 8 : struct NaClMutex *mp,
79 8 : NACL_TIMESPEC_T const *abstime) {
80 8 : struct timespec ts;
81 8 : int result;
82 8 : ts.tv_sec = abstime->tv_sec;
83 8 : ts.tv_nsec = abstime->tv_nsec;
84 8 : result = pthread_cond_timedwait(&cvp->cv, &mp->mu, &ts);
85 8 : if (0 == result) {
86 0 : return NACL_SYNC_OK;
87 : }
88 8 : return NACL_SYNC_CONDVAR_TIMEDOUT;
89 8 : }
|