LCOV - code coverage report
Current view: directory - src/trusted/threading - nacl_thread_interface.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 77 36 46.8 %
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                 : #include "native_client/src/trusted/threading/nacl_thread_interface.h"
       8                 : 
       9                 : #include "native_client/src/include/nacl_compiler_annotations.h"
      10                 : 
      11                 : #include "native_client/src/shared/platform/nacl_check.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_threads.h"
      14                 : #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
      15                 : 
      16              11 : void WINAPI NaClThreadInterfaceStart(void *data) {
      17                 :   struct NaClThreadInterface  *tif =
      18              11 :       (struct NaClThreadInterface *) data;
      19                 :   void                        *thread_return;
      20                 : 
      21              11 :   NaClLog(4,
      22                 :           ("Entered NaClThreadInterfaceStart: thread object 0x%"NACL_PRIxPTR
      23                 :            " starting.\n"),
      24                 :           (uintptr_t) tif);  /* NaClThreadId() implicitly printed */
      25              11 :   (*NACL_VTBL(NaClThreadInterface, tif)->LaunchCallback)(tif);
      26              11 :   thread_return = (*tif->fn_ptr)(tif);
      27               5 :   NaClLog(4,
      28                 :           ("NaClThreadInterfaceStart: thread object 0x%"NACL_PRIxPTR
      29                 :            " returned 0x%"NACL_PRIxPTR".\n"),
      30                 :           (uintptr_t) tif,
      31                 :           (uintptr_t) thread_return);  /* NaClThreadId() implicitly printed */
      32               5 :   (*NACL_VTBL(NaClThreadInterface, tif)->Exit)(tif, thread_return);
      33               0 :   NaClLog(LOG_FATAL,
      34                 :           "NaClThreadInterface: Exit member function did not exit thread\n");
      35               0 : }
      36                 : 
      37                 : int NaClThreadInterfaceCtor_protected(
      38                 :     struct NaClThreadInterface    *self,
      39                 :     NaClThreadIfFactoryFunction   factory,
      40                 :     void                          *factory_data,
      41                 :     NaClThreadIfStartFunction     fn_ptr,
      42                 :     void                          *thread_data,
      43              11 :     size_t                        thread_stack_size) {
      44                 : 
      45              11 :   NaClLog(3, "Entered NaClThreadInterfaceThreadPlacementFactory\n");
      46              11 :   if (!NaClRefCountCtor((struct NaClRefCount *) self)) {
      47               0 :     NaClLog(3,
      48                 :             "NaClThreadInterfaceThreadPlacementFactory,"
      49                 :             " NaClRefCountCtor base class ctor failed\n");
      50               0 :     return 0;
      51                 :   }
      52                 : 
      53              11 :   self->factory = factory;
      54              11 :   self->factory_data = factory_data;
      55              11 :   self->thread_stack_size = thread_stack_size;
      56              11 :   self->fn_ptr = fn_ptr;
      57              11 :   self->thread_data = thread_data;
      58              11 :   self->thread_started = 0;
      59              11 :   NACL_VTBL(NaClRefCount, self) =
      60                 :       (struct NaClRefCountVtbl const *) &kNaClThreadInterfaceVtbl;
      61              11 :   NaClLog(3,
      62                 :           "Leaving NaClThreadInterfaceThreadPlacementFactory, returning 1\n");
      63              11 :   return 1;
      64                 : }
      65                 : 
      66                 : int NaClThreadInterfaceThreadFactory(
      67                 :     void                        *factory_data,
      68                 :     NaClThreadIfStartFunction   fn_ptr,
      69                 :     void                        *thread_data,
      70                 :     size_t                      thread_stack_size,
      71               0 :     struct NaClThreadInterface  **out_new_thread) {
      72                 :   struct NaClThreadInterface  *new_thread;
      73                 :   int                         rv;
      74                 : 
      75               0 :   NaClLog(3, "Entered NaClThreadInterfaceThreadFactory\n");
      76               0 :   new_thread = malloc(sizeof *new_thread);
      77               0 :   if (NULL == new_thread) {
      78               0 :     NaClLog(3, "NaClThreadInterfaceThreadFactory: no memory!\n");
      79               0 :     return 0;
      80                 :   }
      81               0 :   if (0 != (rv =
      82                 :             NaClThreadInterfaceCtor_protected(
      83                 :                 new_thread,
      84                 :                 NaClThreadInterfaceThreadFactory,
      85                 :                 factory_data,
      86                 :                 fn_ptr,
      87                 :                 thread_data,
      88                 :                 thread_stack_size))) {
      89               0 :     *out_new_thread = new_thread;
      90               0 :     NaClLog(3,
      91                 :             "NaClThreadInterfaceThreadFactory: new thread object"
      92                 :             " 0x%"NACL_PRIxPTR" (not started)\n",
      93                 :             (uintptr_t) new_thread);
      94               0 :     new_thread = NULL;
      95                 :   }
      96               0 :   free(new_thread);
      97               0 :   NaClLog(3,
      98                 :           "Leaving NaClThreadInterfaceThreadFactory, returning %d\n",
      99                 :           rv);
     100               0 :   return rv;
     101                 : }
     102                 : 
     103               0 : void NaClThreadInterfaceDtor(struct NaClRefCount *vself) {
     104                 :   struct NaClThreadInterface *self =
     105               0 :       (struct NaClThreadInterface *) vself;
     106               0 :   CHECK(self->thread_started == 0);
     107               0 :   self->fn_ptr = NULL;
     108               0 :   self->thread_data = NULL;
     109               0 :   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
     110               0 :   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
     111               0 : }
     112                 : 
     113              11 : int NaClThreadInterfaceStartThread(struct NaClThreadInterface  *self) {
     114                 :   int rv;
     115                 : 
     116              11 :   NaClLog(3,
     117                 :           "Entered NaClThreadInterfaceStartThread: self 0x%"NACL_PRIxPTR"\n",
     118                 :           (uintptr_t) self);
     119              11 :   CHECK(self->thread_started == 0);
     120                 : 
     121              11 :   rv = NaClThreadCtor(&self->thread,
     122                 :                       NaClThreadInterfaceStart,
     123                 :                       self,
     124                 :                       self->thread_stack_size);
     125              11 :   if (rv) {
     126              11 :     self->thread_started = 1;
     127                 :   }
     128              11 :   NaClLog(3, "Leaving NaClThreadInterfaceStartThread, rv=%d\n", rv);
     129              11 :   return rv;
     130                 : }
     131                 : 
     132                 : /*
     133                 :  * Default LaunchCallback does nothing.  We could have made this "pure
     134                 :  * virtual" by doing NaClLog(LOG_FATAL, ...) in the body (at least
     135                 :  * detected at runtime).
     136                 :  */
     137               0 : void NaClThreadInterfaceLaunchCallback(struct NaClThreadInterface *self) {
     138               0 :   NaClLog(3,
     139                 :           "NaClThreadInterfaceLaunchCallback: thread 0x%"NACL_PRIxPTR"\n",
     140                 :           (uintptr_t) self);
     141               0 : }
     142                 : 
     143                 : void NaClThreadInterfaceExit(struct NaClThreadInterface *self,
     144               0 :                              void                       *exit_code) {
     145               0 :   NaClLog(3,
     146                 :           "NaClThreadInterfaceExit: thread 0x%"NACL_PRIxPTR"\n",
     147                 :           (uintptr_t) self);
     148               0 :   self->thread_started = 0;  /* on way out */
     149               0 :   NaClRefCountUnref((struct NaClRefCount *) self);
     150                 :   /* only keep low order bits of the traditional void* return */
     151               0 :   NaClThreadExit((int) (uintptr_t) exit_code);
     152               0 : }
     153                 : 
     154                 : struct NaClThreadInterfaceVtbl const kNaClThreadInterfaceVtbl = {
     155                 :   {
     156                 :     NaClThreadInterfaceDtor,
     157                 :   },
     158                 :   NaClThreadInterfaceStartThread,
     159                 :   NaClThreadInterfaceLaunchCallback,
     160                 :   NaClThreadInterfaceExit,
     161                 : };
     162                 : 
     163                 : int NaClThreadInterfaceConstructAndStartThread(
     164                 :     NaClThreadIfFactoryFunction factory_fn,
     165                 :     void                        *factory_data,
     166                 :     NaClThreadIfStartFunction   thread_fn_ptr,
     167                 :     void                        *thread_data,
     168                 :     size_t                      thread_stack_size,
     169              11 :     struct NaClThreadInterface  **out_new_thread) {
     170                 :   struct NaClThreadInterface  *new_thread;
     171                 : 
     172              11 :   NaClLog(3,
     173                 :           "NaClThreadInterfaceConstructAndStartThread: invoking factory"
     174                 :           " function 0x%"NACL_PRIxPTR", factory data 0x%"NACL_PRIxPTR"\n",
     175                 :           (uintptr_t) factory_fn, (uintptr_t) factory_data);
     176              11 :   if (!(*factory_fn)(factory_data,
     177                 :                      thread_fn_ptr,
     178                 :                      thread_data,
     179                 :                      thread_stack_size,
     180                 :                      &new_thread)) {
     181               0 :     NaClLog(3,
     182                 :             ("NaClThreadInterfaceConstructAndStartThread:"
     183                 :              " factory 0x%"NACL_PRIxPTR" failed to produce!\n"),
     184                 :             (uintptr_t) factory_fn);
     185               0 :     new_thread = NULL;
     186               0 :     goto abort;
     187                 :   }
     188              11 :   NaClLog(3,
     189                 :           "NaClThreadInterfaceConstructAndStartThread: StartThread vfn\n");
     190              11 :   if (!(*NACL_VTBL(NaClThreadInterface, new_thread)->StartThread)(
     191                 :           new_thread)) {
     192               0 :     NaClLog(3,
     193                 :             ("NaClThreadInterfaceConstructAndStartThread:"
     194                 :              " factory 0x%"NACL_PRIxPTR" produced a thread 0x%"NACL_PRIxPTR
     195                 :              " that won't start!\n"),
     196                 :             (uintptr_t) factory_fn,
     197                 :             (uintptr_t) new_thread);
     198               0 :     NaClRefCountUnref((struct NaClRefCount *) new_thread);
     199               0 :     new_thread = NULL;
     200               0 :     goto abort;
     201                 :   }
     202              11 :   NaClLog(4,
     203                 :           ("NaClThreadInterfaceConstructAndStartThread: thread 0x%"NACL_PRIxPTR
     204                 :            " started\n"),
     205                 :           (uintptr_t) new_thread);
     206              11 : abort:
     207              11 :   *out_new_thread = new_thread;
     208              11 :   return new_thread != NULL;
     209                 : }

Generated by: LCOV version 1.7