LCOV - code coverage report
Current view: directory - src/shared/platform/linux - nacl_threads.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 33 24 72.7 %
Date: 2012-02-16 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 threads implementation layer.
       9                 :  */
      10                 : 
      11                 : #include <string.h>
      12                 : #include <stdlib.h>
      13                 : #include <sys/types.h>
      14                 : #include <signal.h>
      15                 : #include <pthread.h>
      16                 : #include <limits.h>
      17                 : /*
      18                 :  * PTHREAD_STACK_MIN should come from pthread.h as documented, but is
      19                 :  * actually pulled in by limits.h.
      20                 :  */
      21                 : 
      22                 : #include "native_client/src/include/portability.h"
      23                 : #include "native_client/src/shared/platform/nacl_log.h"
      24                 : #include "native_client/src/shared/platform/nacl_threads.h"
      25                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      26                 : 
      27                 : #if !defined(__native_client__) && NACL_KERN_STACK_SIZE < PTHREAD_STACK_MIN
      28                 : # error "NaCl service runtime stack size is smaller than PTHREAD_STACK_MIN"
      29                 : #endif
      30                 : 
      31                 : static int NaClThreadCreate(struct NaClThread  *ntp,
      32                 :                             void               (*start_fn)(void *),
      33                 :                             void               *state,
      34                 :                             size_t             stack_size,
      35             260 :                             int                is_detached) {
      36                 :   pthread_attr_t  attr;
      37                 :   int             code;
      38                 :   int             rv;
      39                 :   char            err_string[1024];
      40                 : 
      41             260 :   rv = 0;
      42                 : 
      43             260 :   if (stack_size < PTHREAD_STACK_MIN) {
      44               0 :     stack_size = PTHREAD_STACK_MIN;
      45                 :   }
      46             260 :   if (0 != (code = pthread_attr_init(&attr))) {
      47               0 :     NaClLog(LOG_ERROR,
      48                 :             "NaClThreadCtor: pthread_atr_init returned %d",
      49                 :             code);
      50               0 :     goto done;
      51                 :   }
      52             260 :   if (0 != (code = pthread_attr_setstacksize(&attr, stack_size))) {
      53               0 :     NaClLog(LOG_ERROR,
      54                 :             "NaClThreadCtor: pthread_attr_setstacksize returned %d (%s)",
      55                 :             code,
      56                 :             (strerror_r(code, err_string, sizeof err_string) == 0
      57                 :              ? err_string
      58                 :              : "UNKNOWN"));
      59               0 :     goto done_attr_dtor;
      60                 :   }
      61             260 :   if (is_detached) {
      62             231 :     if (0 != (code = pthread_attr_setdetachstate(&attr,
      63                 :                                                  PTHREAD_CREATE_DETACHED))) {
      64               0 :       NaClLog(LOG_ERROR,
      65                 :               "nacl_thread: pthread_attr_setdetachstate returned %d (%s)",
      66                 :               code,
      67                 :               (strerror_r(code, err_string, sizeof err_string) == 0
      68                 :                ? err_string
      69                 :                : "UNKNOWN"));
      70               0 :       goto done_attr_dtor;
      71                 :     }
      72                 :   }
      73             260 :   if (0 != (code = pthread_create(&ntp->tid,
      74                 :                                   &attr,
      75                 :                                   (void *(*)(void *)) start_fn,
      76                 :                                   state))) {
      77               0 :     NaClLog(LOG_ERROR,
      78                 :             "nacl_thread: pthread_create returned %d (%s)",
      79                 :             code,
      80                 :             (strerror_r(code, err_string, sizeof err_string) == 0
      81                 :              ? err_string
      82                 :              : "UNKNOWN"));
      83               0 :     goto done_attr_dtor;
      84                 :   }
      85             260 :   rv = 1;
      86             260 :  done_attr_dtor:
      87             260 :   (void) pthread_attr_destroy(&attr);  /* often a noop */
      88             260 :  done:
      89             260 :   return rv;
      90                 : }
      91                 : 
      92                 : /*
      93                 :  * Even if ctor fails, it should be okay -- and required -- to invoke
      94                 :  * the dtor on it.
      95                 :  */
      96                 : int NaClThreadCtor(struct NaClThread  *ntp,
      97                 :                    void               (*start_fn)(void *),
      98                 :                    void               *state,
      99             231 :                    size_t             stack_size) {
     100             231 :   return NaClThreadCreate(ntp, start_fn, state, stack_size,
     101                 :                           /* is_detached= */ 1);
     102                 : }
     103                 : 
     104                 : int NaClThreadCreateJoinable(struct NaClThread  *ntp,
     105                 :                              void               (*start_fn)(void *),
     106                 :                              void               *state,
     107              29 :                              size_t             stack_size) {
     108              29 :   return NaClThreadCreate(ntp, start_fn, state, stack_size,
     109                 :                           /* is_detached= */ 0);
     110                 : }
     111                 : 
     112               4 : void NaClThreadDtor(struct NaClThread *ntp) {
     113                 :   /*
     114                 :    * The threads that we create are not joinable, and we cannot tell
     115                 :    * when they are truly gone.  Fortunately, the threads themselves
     116                 :    * and the underlying thread library are responsible for ensuring
     117                 :    * that resources such as the thread stack are properly released.
     118                 :    */
     119                 :   UNREFERENCED_PARAMETER(ntp);
     120               4 : }
     121                 : 
     122              29 : void NaClThreadJoin(struct NaClThread *ntp) {
     123              29 :   pthread_join(ntp->tid, NULL);
     124              29 : }
     125                 : 
     126              11 : void NaClThreadExit(int exit_code) {
     127              11 :   pthread_exit((void *) (uintptr_t) exit_code);
     128                 : }

Generated by: LCOV version 1.7