LCOV - code coverage report
Current view: directory - src/shared/platform - nacl_interruptible_mutex.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 72 0 0.0 %
Date: 2014-06-18 Functions: 0 0 -

       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                 : /*
       8                 :  * NaCl Server Runtime interruptible binary mutex, based on nacl_sync
       9                 :  * interface.
      10                 :  */
      11                 : 
      12                 : #include "native_client/src/include/portability.h"
      13                 : #include "native_client/src/shared/platform/nacl_interruptible_mutex.h"
      14                 : #include "native_client/src/shared/platform/nacl_log.h"
      15                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      16                 : 
      17                 : 
      18               0 : int NaClIntrMutexCtor(struct NaClIntrMutex *mp) {
      19               0 :   if (!NaClMutexCtor(&mp->mu)) {
      20               0 :     return 0;
      21                 :   }
      22               0 :   if (!NaClCondVarCtor(&mp->cv)) {
      23               0 :     NaClMutexDtor(&mp->mu);
      24               0 :     return 0;
      25                 :   }
      26               0 :   mp->lock_state = NACL_INTR_LOCK_FREE;
      27               0 :   return 1;
      28               0 : }
      29                 : 
      30               0 : void NaClIntrMutexDtor(struct NaClIntrMutex *mp) {
      31               0 :   NaClCondVarDtor(&mp->cv);
      32               0 :   NaClMutexDtor(&mp->mu);
      33               0 : }
      34                 : 
      35               0 : NaClSyncStatus NaClIntrMutexLock(struct NaClIntrMutex *mp) {
      36               0 :   NaClSyncStatus rv = NACL_SYNC_INTERNAL_ERROR;
      37               0 :   NaClXMutexLock(&mp->mu);
      38               0 :   while (NACL_INTR_LOCK_HELD == mp->lock_state) {
      39               0 :     NaClXCondVarWait(&mp->cv, &mp->mu);
      40               0 :   }
      41               0 :   if (NACL_INTR_LOCK_FREE == mp->lock_state) {
      42               0 :     mp->lock_state = NACL_INTR_LOCK_HELD;
      43               0 :     rv = NACL_SYNC_OK;
      44               0 :   }
      45                 : 
      46               0 :   if (NACL_INTR_LOCK_INTERRUPTED == mp->lock_state) {
      47               0 :     rv = NACL_SYNC_MUTEX_INTERRUPTED;
      48               0 :   }
      49               0 :   NaClXMutexUnlock(&mp->mu);
      50               0 :   return rv;
      51                 : }
      52                 : 
      53               0 : NaClSyncStatus NaClIntrMutexTryLock(struct NaClIntrMutex *mp) {
      54               0 :   NaClSyncStatus rv = NACL_SYNC_INTERNAL_ERROR;
      55                 : 
      56               0 :   NaClXMutexLock(&mp->mu);
      57               0 :   switch (mp->lock_state) {
      58                 :     case NACL_INTR_LOCK_FREE:
      59               0 :       mp->lock_state = NACL_INTR_LOCK_HELD;
      60               0 :       rv = NACL_SYNC_OK;
      61               0 :       break;
      62                 :     case NACL_INTR_LOCK_HELD:
      63               0 :       rv = NACL_SYNC_BUSY;
      64               0 :       break;
      65                 :     case NACL_INTR_LOCK_INTERRUPTED:
      66               0 :       rv = NACL_SYNC_MUTEX_INTERRUPTED;
      67               0 :       break;
      68                 :     default:
      69               0 :       rv = NACL_SYNC_INTERNAL_ERROR;
      70               0 :       break;
      71                 :   }
      72               0 :   NaClXMutexUnlock(&mp->mu);
      73               0 :   return rv;
      74                 : }
      75                 : 
      76               0 : NaClSyncStatus NaClIntrMutexUnlock(struct NaClIntrMutex *mp) {
      77               0 :   NaClSyncStatus rv = NACL_SYNC_INTERNAL_ERROR;
      78               0 :   NaClXMutexLock(&mp->mu);
      79               0 :   if (NACL_INTR_LOCK_HELD != mp->lock_state) {
      80               0 :     NaClLog(1, "NaClIntrMutxUnlock: unlocking when lock is not held\n");
      81               0 :     rv = NACL_SYNC_MUTEX_PERMISSION;
      82               0 :   } else {
      83               0 :     rv = NACL_SYNC_OK;
      84                 :   }
      85               0 :   mp->lock_state = NACL_INTR_LOCK_FREE;
      86                 : 
      87               0 :   NaClXCondVarSignal(&mp->cv);
      88               0 :   NaClXMutexUnlock(&mp->mu);
      89               0 :   return rv;
      90                 : }
      91                 : 
      92               0 : void NaClIntrMutexIntr(struct NaClIntrMutex *mp) {
      93               0 :   NaClXMutexLock(&mp->mu);
      94               0 :   if (NACL_INTR_LOCK_HELD == mp->lock_state) {
      95                 :     /* potentially there are threads waiting for this thread */
      96               0 :     mp->lock_state = NACL_INTR_LOCK_INTERRUPTED;
      97               0 :     NaClXCondVarBroadcast(&mp->cv);
      98               0 :   } else {
      99               0 :     mp->lock_state = NACL_INTR_LOCK_INTERRUPTED;
     100                 :   }
     101               0 :   NaClXMutexUnlock(&mp->mu);
     102               0 : }
     103                 : 
     104                 : /*
     105                 :  * Reset the interruptible mutex, presumably after the condition
     106                 :  * causing the interrupt has been cleared.  In our case, this would be
     107                 :  * an E_MOVE_ADDRESS_SPACE induced address space move.
     108                 :  *
     109                 :  * This is safe to invoke only after all threads are known to be in a
     110                 :  * quiescent state -- i.e., will no longer call
     111                 :  * NaClIntrMutex{Try,}Lock on the interruptible mutex -- since there
     112                 :  * is no guarntee that all the threads awaken by NaClIntrMutexIntr
     113                 :  * have actually been run yet.
     114                 :  */
     115               0 : void NaClIntrMutexReset(struct NaClIntrMutex *mp) {
     116               0 :   NaClXMutexLock(&mp->mu);
     117               0 :   if (NACL_INTR_LOCK_INTERRUPTED != mp->lock_state) {
     118               0 :     NaClLog(LOG_FATAL,
     119                 :             "NaClIntrMutexReset: lock at 0x%08"NACL_PRIxPTR" not interrupted\n",
     120                 :             (uintptr_t) mp);
     121               0 :   }
     122               0 :   mp->lock_state = NACL_INTR_LOCK_FREE;
     123               0 :   NaClXMutexUnlock(&mp->mu);
     124               0 : }

Generated by: LCOV version 1.7