LCOV - code coverage report
Current view: directory - src/shared/platform/win - nacl_sync_win.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 73 50 68.5 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 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                 : /*
       8                 :  * C bindings for C++ implementation of synchronization objects
       9                 :  * (based on Chrome code)
      10                 :  */
      11                 : 
      12                 : /* Beware: there is a delicate requirement here that the untrusted code be able
      13                 :  * to include nacl_abi_* type definitions.  These headers share an include
      14                 :  * guard with the exported versions, which get included first.  Unfortunately,
      15                 :  * tying them to different include guards causes multiple definitions of
      16                 :  * macros.
      17                 :  */
      18                 : #include "native_client/src/include/portability.h"
      19                 : #include <sys/types.h>
      20                 : #include <sys/timeb.h>
      21                 : 
      22                 : #include "native_client/src/include/nacl_macros.h"
      23                 : 
      24                 : #include "native_client/src/shared/platform/nacl_sync.h"
      25                 : 
      26                 : #include "native_client/src/shared/platform/nacl_log.h"
      27                 : #include "native_client/src/shared/platform/nacl_time.h"
      28                 : #include "native_client/src/shared/platform/win/condition_variable.h"
      29                 : #include "native_client/src/shared/platform/win/lock.h"
      30                 : #include "native_client/src/trusted/service_runtime/include/sys/time.h"
      31                 : 
      32                 : /* Mutex */
      33              28 : int NaClMutexCtor(struct NaClMutex *mp) {
      34              28 :   mp->lock = new NaCl::Lock();
      35              28 :   mp->held = 0;
      36              28 :   return NULL != mp->lock;
      37              28 : }
      38                 : 
      39              23 : void NaClMutexDtor(struct NaClMutex *mp) {
      40              23 :   delete reinterpret_cast<NaCl::Lock *>(mp->lock);
      41              23 :   mp->lock = NULL;
      42              23 : }
      43                 : 
      44              28 : NaClSyncStatus NaClMutexLock(struct NaClMutex *mp) {
      45              28 :   reinterpret_cast<NaCl::Lock *>(mp->lock)->Acquire();
      46              28 :   if (!mp->held) {
      47              28 :     mp->held = 1;
      48              28 :     return NACL_SYNC_OK;
      49                 :   } else {
      50                 :     /*
      51                 :      * The only way we can successfully Acquire but have mp->held
      52                 :      * already be true is because this is a recursive lock
      53                 :      * acquisition.  With binary mutexes, this is a trivial deadlock.
      54                 :      * Simulate the deadlock.
      55                 :      */
      56                 :     struct nacl_abi_timespec long_time;
      57                 : 
      58               1 :     long_time.tv_sec = 10000;
      59               1 :     long_time.tv_nsec = 0;
      60                 :     /*
      61                 :      * Note that NaClLog uses mutexes internally, so this log message
      62                 :      * assumes that this error is not being triggered from there.  The
      63                 :      * service runtime should not deadlock in this way -- only
      64                 :      * untrusted user code might.  In any case, this is "safe" in that
      65                 :      * even if the NaClLog module were to have this bug, it would
      66                 :      * result in an infinite log spew -- something that ought to be
      67                 :      * quickly detected in normal testing.
      68                 :      */
      69                 :     NaClLog(LOG_WARNING,
      70                 :             ("NaClMutexLock: recursive lock of binary mutex."
      71               1 :              "  Deadlock being simulated\n"));
      72                 :     for (;;) {
      73               1 :       NaClNanosleep(&long_time, NULL);
      74               0 :     }
      75                 :   }
      76              28 : }
      77                 : 
      78               1 : NaClSyncStatus NaClMutexTryLock(struct NaClMutex *mp) {
      79                 :   NaClSyncStatus status = reinterpret_cast<NaCl::Lock *>(mp->lock)->Try() ?
      80               1 :       NACL_SYNC_OK : NACL_SYNC_BUSY;
      81               1 :   if (status == NACL_SYNC_OK) {
      82               1 :     if (mp->held) {
      83                 :       /* decrement internal recursion count in the underlying lock */
      84               1 :       reinterpret_cast<NaCl::Lock *>(mp->lock)->Release();
      85               1 :       status = NACL_SYNC_BUSY;
      86                 :     }
      87               1 :     mp->held = 1;
      88                 :   }
      89               1 :   return status;
      90               1 : }
      91                 : 
      92              28 : NaClSyncStatus NaClMutexUnlock(struct NaClMutex *mp) {
      93              28 :   mp->held = 0;
      94              28 :   reinterpret_cast<NaCl::Lock *>(mp->lock)->Release();
      95              28 :   return NACL_SYNC_OK;
      96              28 : }
      97                 : 
      98                 : /* Condition variable */
      99                 : 
     100               2 : int NaClCondVarCtor(struct NaClCondVar  *cvp) {
     101               2 :   cvp->cv = new NaCl::ConditionVariable();
     102               2 :   return 1;
     103               2 : }
     104                 : 
     105               2 : void NaClCondVarDtor(struct NaClCondVar *cvp) {
     106               2 :   delete reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv);
     107               2 : }
     108                 : 
     109               2 : NaClSyncStatus NaClCondVarSignal(struct NaClCondVar *cvp) {
     110               2 :   reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv)->Signal();
     111               2 :   return NACL_SYNC_OK;
     112               2 : }
     113                 : 
     114               0 : NaClSyncStatus NaClCondVarBroadcast(struct NaClCondVar *cvp) {
     115               0 :   reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv)->Broadcast();
     116               0 :   return NACL_SYNC_OK;
     117               0 : }
     118                 : 
     119                 : NaClSyncStatus NaClCondVarWait(struct NaClCondVar *cvp,
     120               2 :                                struct NaClMutex   *mp) {
     121               2 :   mp->held = 0;
     122                 :   reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv)->Wait(
     123               2 :       *(reinterpret_cast<NaCl::Lock *>(mp->lock)));
     124               2 :   mp->held = 1;
     125               2 :   return NACL_SYNC_OK;
     126               2 : }
     127                 : 
     128                 : NaClSyncStatus NaClCondVarTimedWaitRelative(
     129                 :     struct NaClCondVar             *cvp,
     130                 :     struct NaClMutex               *mp,
     131               0 :     struct nacl_abi_timespec const *reltime) {
     132                 :   NaCl::TimeDelta relative_wait(
     133                 :       NaCl::TimeDelta::FromMicroseconds(
     134                 :           reltime->tv_sec
     135                 :           * NaCl::Time::kMicrosecondsPerSecond
     136                 :           + reltime->tv_nsec
     137               0 :           / NaCl::Time::kNanosecondsPerMicrosecond));
     138                 :   int result;
     139               0 :   mp->held = 0;
     140                 :   result = (reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv)->TimedWaitRel(
     141                 :                 *(reinterpret_cast<NaCl::Lock *>(mp->lock)),
     142               0 :       relative_wait));
     143               0 :   mp->held = 1;
     144               0 :   if (0 == result) {
     145               0 :     return NACL_SYNC_CONDVAR_TIMEDOUT;
     146                 :   }
     147               0 :   return NACL_SYNC_OK;
     148               0 : }
     149                 : 
     150                 : NaClSyncStatus NaClCondVarTimedWaitAbsolute(
     151                 :     struct NaClCondVar              *cvp,
     152                 :     struct NaClMutex                *mp,
     153               0 :     struct nacl_abi_timespec const  *abstime) {
     154                 :   NaCl::TimeTicks ticks(abstime->tv_sec
     155                 :                         * NaCl::Time::kMicrosecondsPerSecond
     156                 :                         + abstime->tv_nsec
     157               0 :                         / NaCl::Time::kNanosecondsPerMicrosecond);
     158                 :   int result;
     159               0 :   mp->held = 0;
     160                 :   result = reinterpret_cast<NaCl::ConditionVariable*>(cvp->cv)->TimedWaitAbs(
     161                 :       *(reinterpret_cast<NaCl::Lock *>(mp->lock)),
     162               0 :       ticks);
     163               0 :   mp->held = 1;
     164               0 :   if (0 == result) {
     165               0 :     return NACL_SYNC_CONDVAR_TIMEDOUT;
     166                 :   }
     167               0 :   return NACL_SYNC_OK;
     168               0 : }

Generated by: LCOV version 1.7