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

       1                 : /*
       2                 :  * Copyright 2008 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can
       4                 :  * be found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl semaphore implementation (OSX)
       9                 :  */
      10                 : 
      11                 : #include <errno.h>
      12                 : #include <unistd.h>
      13                 : 
      14                 : #include "native_client/src/include/portability.h"
      15                 : #include "native_client/src/include/nacl_macros.h"
      16                 : 
      17                 : #include "native_client/src/shared/platform/nacl_global_secure_random.h"
      18                 : #include "native_client/src/shared/platform/nacl_log.h"
      19                 : #include "native_client/src/shared/platform/nacl_sync.h"
      20                 : #include "native_client/src/shared/platform/osx/nacl_semaphore.h"
      21                 : /*
      22                 : * NOTE(gregoryd): following Gears in defining SEM_NAME_LEN:
      23                 : * Gears: The docs claim that SEM_NAME_LEN should be defined.  It is not.
      24                 : * However, by looking at the xnu source (bsd/kern/posix_sem.c),
      25                 : * it defines PSEMNAMLEN to be 31 characters.  We'll use that value.
      26                 : */
      27                 : #define SEM_NAME_LEN 31
      28                 : 
      29                 : 
      30                 : #if NACL_USE_NATIVE_SEMAPHORES
      31                 : 
      32                 : int NaClSemCtor(struct NaClSemaphore *sem, int32_t value) {
      33                 :   /*
      34                 :    * There are 62^30 possible names - should be enough.
      35                 :    * 62 = 26*2 + 10 - the number of alphanumeric characters
      36                 :    * 30 = SEM_NAME_LEN - 1
      37                 :    */
      38                 :   char sem_name[SEM_NAME_LEN];
      39                 : 
      40                 :   do {
      41                 :     NaClGenerateRandomPath(&sem_name[0], SEM_NAME_LEN);
      42                 :     sem->sem_descriptor = sem_open(sem_name, O_CREAT | O_EXCL, 700, value);
      43                 :   } while ((SEM_FAILED == sem->sem_descriptor) && (EEXIST == errno));
      44                 :   if (SEM_FAILED == sem->sem_descriptor) {
      45                 :     NaClLog(1, "NaClSemCtor: sem_open failed, errno %d\n", errno);
      46                 :     return 0;
      47                 :   }
      48                 :   sem_unlink(sem_name);
      49                 :   return 1;
      50                 : }
      51                 : 
      52                 : void NaClSemDtor(struct NaClSemaphore *sem) {
      53                 :   sem_close(sem->sem_descriptor);
      54                 : }
      55                 : 
      56                 : NaClSyncStatus NaClSemWait(struct NaClSemaphore *sem) {
      57                 :   sem_wait(sem->sem_descriptor);  /* always returns 0 */
      58                 :   return NACL_SYNC_OK;
      59                 : }
      60                 : 
      61                 : NaClSyncStatus NaClSemTryWait(struct NaClSemaphore *sem) {
      62                 :   if (0 == sem_trywait(sem->sem_descriptor)) {
      63                 :     return NACL_SYNC_OK;
      64                 :   }
      65                 :   return NACL_SYNC_BUSY;
      66                 : }
      67                 : 
      68                 : NaClSyncStatus NaClSemPost(struct NaClSemaphore *sem) {
      69                 :   if (0 == sem_post(sem->sem_descriptor)) {
      70                 :     return NACL_SYNC_OK;
      71                 :   }
      72                 :   /* Posting above SEM_MAX_VALUE does not always fail, but sometimes it may */
      73                 :   if ((ERANGE == errno) || (EOVERFLOW == errno)) {
      74                 :     return NACL_SYNC_SEM_RANGE_ERROR;
      75                 :   }
      76                 :   return NACL_SYNC_INTERNAL_ERROR;
      77                 : }
      78                 : 
      79                 : int32_t NaClSemGetValue(struct NaClSemaphore *sem) {
      80                 :   UNREFERENCED_PARAMETER(sem);
      81                 :   return -1;
      82                 :   /*
      83                 :   * TODO(gregoryd) - sem_getvalue is declared but not implemented on OSX
      84                 :   * Remove it from the API or reimplement.
      85                 :   */
      86                 : #if 0
      87                 :   int32_t value;
      88                 :   sem_getvalue(sem->sem_descriptor, &value);  /* always returns 0 */
      89                 :   return value;
      90                 : #endif
      91                 : }
      92                 : 
      93                 : #else  /* NACL_USE_NATIVE_SEMAPHORES */
      94                 : 
      95               1 : int NaClSemCtor(struct NaClSemaphore *sem, int32_t value) {
      96               1 :   if (value < 0) {
      97               0 :     return 0;
      98                 :   }
      99               1 :   if (!NaClMutexCtor(&sem->mu)) {
     100               0 :     return 0;
     101                 :   }
     102               1 :   if (!NaClCondVarCtor(&sem->cv)) {
     103               0 :     NaClMutexDtor(&sem->mu);
     104               0 :     return 0;
     105                 :   }
     106               1 :   sem->value = value;
     107               1 :   return 1;
     108               1 : }
     109                 : 
     110               1 : void NaClSemDtor(struct NaClSemaphore *sem) {
     111               1 :   NaClCondVarDtor(&sem->cv);
     112               1 :   NaClMutexDtor(&sem->mu);
     113               1 : }
     114                 : 
     115              10 : NaClSyncStatus NaClSemWait(struct NaClSemaphore *sem) {
     116              10 :   NaClXMutexLock(&sem->mu);
     117              28 :   while (0 == sem->value) {
     118               8 :     NaClXCondVarWait(&sem->cv, &sem->mu);
     119               8 :   }
     120              10 :   sem->value--;
     121              10 :   NaClXMutexUnlock(&sem->mu);
     122              10 :   return NACL_SYNC_OK;
     123                 : }
     124                 : 
     125              74 : NaClSyncStatus NaClSemTryWait(struct NaClSemaphore *sem) {
     126              74 :   NaClSyncStatus rv = NACL_SYNC_INTERNAL_ERROR;
     127                 : 
     128              74 :   NaClXMutexLock(&sem->mu);
     129              74 :   if (0 == sem->value) {
     130              68 :     rv = NACL_SYNC_BUSY;
     131              68 :   } else {
     132               6 :     sem->value--;
     133               6 :     rv = NACL_SYNC_OK;
     134                 :   }
     135              74 :   NaClXMutexUnlock(&sem->mu);
     136              74 :   return rv;
     137                 : }
     138                 : 
     139              16 : NaClSyncStatus NaClSemPost(struct NaClSemaphore *sem) {
     140              16 :   NaClSyncStatus rv = NACL_SYNC_INTERNAL_ERROR;
     141                 : 
     142              16 :   NaClXMutexLock(&sem->mu);
     143              16 :   if (NACL_MAX_VAL(int32_t) == sem->value) {
     144               0 :     rv = NACL_SYNC_SEM_RANGE_ERROR;
     145               0 :   } else {
     146              16 :     sem->value++;
     147              16 :     NaClXCondVarSignal(&sem->cv);
     148              16 :     rv = NACL_SYNC_OK;
     149                 :   }
     150              16 :   NaClXMutexUnlock(&sem->mu);
     151              16 :   return rv;
     152                 : }
     153                 : 
     154               0 : int32_t NaClSemGetValue(struct NaClSemaphore *sem) {
     155               0 :   int32_t val;
     156                 : 
     157               0 :   NaClXMutexLock(&sem->mu);
     158               0 :   val = sem->value;
     159               0 :   NaClXMutexUnlock(&sem->mu);
     160               0 :   return val;
     161                 : }
     162                 : 
     163                 : #endif  /* NACL_USE_NATIVE_SEMAPHORES */

Generated by: LCOV version 1.7