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 60161 : int NaClCondVarCtor(struct NaClCondVar *cvp) {
20 60161 : if (0 != pthread_cond_init(&cvp->cv, (pthread_condattr_t *) 0)) {
21 0 : return 0;
22 : }
23 60161 : return 1;
24 : }
25 :
26 59469 : void NaClCondVarDtor(struct NaClCondVar *cvp) {
27 59469 : pthread_cond_destroy(&cvp->cv);
28 59469 : }
29 :
30 82863 : NaClSyncStatus NaClCondVarSignal(struct NaClCondVar *cvp) {
31 82863 : pthread_cond_signal(&cvp->cv);
32 82863 : return NACL_SYNC_OK;
33 : }
34 :
35 1162 : NaClSyncStatus NaClCondVarBroadcast(struct NaClCondVar *cvp) {
36 1162 : pthread_cond_broadcast(&cvp->cv);
37 1162 : return NACL_SYNC_OK;
38 : }
39 :
40 82168 : NaClSyncStatus NaClCondVarWait(struct NaClCondVar *cvp,
41 : struct NaClMutex *mp) {
42 82168 : pthread_cond_wait(&cvp->cv, &mp->mu);
43 82132 : return NACL_SYNC_OK;
44 : }
45 :
46 0 : NaClSyncStatus NaClCondVarTimedWaitRelative(
47 : struct NaClCondVar *cvp,
48 : struct NaClMutex *mp,
49 : NACL_TIMESPEC_T const *reltime) {
50 0 : uint64_t relative_wait_us =
51 0 : reltime->tv_sec * kMicrosecondsPerSecond +
52 0 : reltime->tv_nsec / kNanosecondsPerMicrosecond;
53 : uint64_t current_time_us;
54 : uint64_t wakeup_time_us;
55 : int result;
56 : struct timespec ts;
57 : 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 : } 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 : }
75 :
76 8 : NaClSyncStatus NaClCondVarTimedWaitAbsolute(
77 : struct NaClCondVar *cvp,
78 : struct NaClMutex *mp,
79 : NACL_TIMESPEC_T const *abstime) {
80 : struct timespec ts;
81 : 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 : }
|