Пример #1
0
// pthread_create
PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
         pthread_t *thread, const pthread_attr_t *attr,
         void *(*start) (void *), void *arg)
{
  int    res;
  int    ret;
  OrigFn fn;
  VgPosixThreadArgs vgargs;

  VALGRIND_GET_ORIG_FN(fn);

  vg_start_suppression(&vgargs.wrapper_started,
                       sizeof(vgargs.wrapper_started));
  vgargs.start = start;
  vgargs.arg   = arg;
  vgargs.wrapper_started = 0;
  vgargs.detachstate = PTHREAD_CREATE_JOINABLE;
  if (attr)
  {
    if (pthread_attr_getdetachstate(attr, &vgargs.detachstate) != 0)
    {
      assert(0);
    }
  }
  assert(vgargs.detachstate == PTHREAD_CREATE_JOINABLE
         || vgargs.detachstate == PTHREAD_CREATE_DETACHED);
#if 0
  pthread_mutex_init(&vgargs.mutex, 0);
  pthread_cond_init(&vgargs.cond, 0);
  pthread_mutex_lock(&vgargs.mutex);
#endif
  /* Suppress NPTL-specific conflicts between creator and created thread. */
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_STOP_RECORDING,
                             0, 0, 0, 0, 0);
  CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
  VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_RECORDING,
                             0, 0, 0, 0, 0);
#if 0
  pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
  pthread_mutex_unlock(&vgargs.mutex);
  pthread_cond_destroy(&vgargs.cond);
  pthread_mutex_destroy(&vgargs.mutex);
#else
  // Yes, you see it correctly, busy waiting ... The problem is that
  // POSIX threads functions cannot be called here -- the functions defined
  // in this file (drd_intercepts.c) would be called instead of those in
  // libpthread.so. This loop is necessary because vgargs is allocated on the
  // stack, and the created thread reads it.
  if (ret == 0)
  {
    while (! vgargs.wrapper_started)
    {
      sched_yield();
    }
  }
#endif
  return ret;
}
Пример #2
0
// pthread_create
PTH_FUNC(int, pthreadZucreateZAZa, // pthread_create@*
              pthread_t *thread, const pthread_attr_t *attr,
              void *(*start) (void *), void *arg)
{
   int   ret;
   void* fn;
   VALGRIND_GET_NRADDR(fn);
   fprintf(stderr, "<< pthread_create wrapper"); fflush(stderr);

   CALL_FN_W_WWWW(ret, fn, thread,attr,start,arg);

   fprintf(stderr, " -> %d >>\n", ret);
   return ret;
}
// sem_open
PTH_FUNC(sem_t *, semZuopen, // sem_open
         const char *name, int oflag, mode_t mode, unsigned int value)
{
   sem_t *ret;
   int    res;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_SEM_OPEN,
                              name, oflag, mode, value, 0);
   CALL_FN_W_WWWW(ret, fn, name, oflag, mode, value);
   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_SEM_OPEN,
                              ret != SEM_FAILED ? ret : 0,
                              name, oflag, mode, value);
   return ret;
}
Пример #4
0
static __always_inline
sem_t* sem_open_intercept(const char *name, int oflag, mode_t mode,
                          unsigned int value)
{
   sem_t *ret;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_SEM_OPEN,
                                   name, oflag, mode, value, 0);
   CALL_FN_W_WWWW(ret, fn, name, oflag, mode, value);
   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_SEM_OPEN,
                                   ret != SEM_FAILED ? ret : 0,
                                   name, oflag, mode, value);
   return ret;
}
Пример #5
0
static __always_inline
int pthread_create_intercept(pthread_t* thread, const pthread_attr_t* attr,
                             void* (*start)(void*), void* arg)
{
   int    ret;
   OrigFn fn;
   DrdSema wrapper_started;
   DrdPosixThreadArgs thread_args;

   VALGRIND_GET_ORIG_FN(fn);

   DRD_(sema_init)(&wrapper_started);
   thread_args.start           = start;
   thread_args.arg             = arg;
   thread_args.wrapper_started = &wrapper_started;
   /*
    * Find out whether the thread will be started as a joinable thread
    * or as a detached thread. If no thread attributes have been specified,
    * this means that the new thread will be started as a joinable thread.
    */
   thread_args.detachstate = PTHREAD_CREATE_JOINABLE;
   if (attr)
   {
      if (pthread_attr_getdetachstate(attr, &thread_args.detachstate) != 0)
         assert(0);
   }
   assert(thread_args.detachstate == PTHREAD_CREATE_JOINABLE
          || thread_args.detachstate == PTHREAD_CREATE_DETACHED);

   DRD_(entering_pthread_create)();
   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), &thread_args);
   DRD_(left_pthread_create)();

   if (ret == 0) {
      /* Wait until the thread wrapper started. */
      DRD_(sema_down)(&wrapper_started);
   }

   DRD_(sema_destroy)(&wrapper_started);

   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_START_NEW_SEGMENT,
                                   pthread_self(), 0, 0, 0, 0);

   return ret;
}
Пример #6
0
// pthread_create
PTH_FUNC(int, pthreadZucreateZAZa, // pthread_create@*
              pthread_t *thread, const pthread_attr_t *attr,
              void *(*start) (void *), void *arg)
{
   int    ret;
   OrigFn fn;
   volatile Word xargs[3];

   VALGRIND_GET_ORIG_FN(fn);
   if (TRACE_PTH_FNS) {
      fprintf(stderr, "<< pthread_create wrapper"); fflush(stderr);
   }
   xargs[0] = (Word)start;
   xargs[1] = (Word)arg;
   xargs[2] = 1; /* serves as a spinlock -- sigh */

   CALL_FN_W_WWWW(ret, fn, thread,attr,mythread_wrapper,&xargs[0]);

   if (ret == 0) {
      /* we have to wait for the child to notify the tool of its
         pthread_t before continuing */
      while (xargs[2] != 0) {
         /* Do nothing.  We need to spin until the child writes to
            xargs[2].  However, that can lead to starvation in the
            child and very long delays (eg, tc19_shadowmem on
            ppc64-linux Fedora Core 6).  So yield the cpu if we can,
            to let the child run at the earliest available
            opportunity. */
         sched_yield();
      }
   } else { 
      DO_PthAPIerror( "pthread_create", ret );
   }

   if (TRACE_PTH_FNS) {
      fprintf(stderr, " :: pth_create -> %d >>\n", ret);
   }
   return ret;
}
// pthread_create
PTH_FUNC(int, pthreadZucreateZa, // pthread_create*
         pthread_t *thread, const pthread_attr_t *attr,
         void *(*start) (void *), void *arg)
{
   int    res;
   int    ret;
   OrigFn fn;
#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK)
   DrdPosixThreadArgs thread_args;
#endif
   DrdPosixThreadArgs* thread_args_p;

   VALGRIND_GET_ORIG_FN(fn);

#if defined(ALLOCATE_THREAD_ARGS_ON_THE_STACK)
   thread_args_p = &thread_args;
#else
   thread_args_p = malloc(sizeof(*thread_args_p));
#endif
   assert(thread_args_p);

   thread_args_p->start           = start;
   thread_args_p->arg             = arg;
#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
   DRD_IGNORE_VAR(thread_args_p->wrapper_started);
   thread_args_p->wrapper_started = 0;
#endif
   /*
    * Find out whether the thread will be started as a joinable thread
    * or as a detached thread. If no thread attributes have been specified,
    * this means that the new thread will be started as a joinable thread.
    */
   thread_args_p->detachstate = PTHREAD_CREATE_JOINABLE;
   if (attr)
   {
      if (pthread_attr_getdetachstate(attr, &thread_args_p->detachstate) != 0)
      {
         assert(0);
      }
   }
   assert(thread_args_p->detachstate == PTHREAD_CREATE_JOINABLE
          || thread_args_p->detachstate == PTHREAD_CREATE_DETACHED);


   DRD_(entering_pthread_create)();
   CALL_FN_W_WWWW(ret, fn, thread, attr, DRD_(thread_wrapper), thread_args_p);
   DRD_(left_pthread_create)();

#if defined(WAIT_UNTIL_CREATED_THREAD_STARTED)
   if (ret == 0)
   {
      /*
       * Wait until the thread wrapper started.
       * @todo Find out why some regression tests fail if thread arguments are
       *   passed via dynamically allocated memory and if the loop below is
       *   removed.
       */
      while (! thread_args_p->wrapper_started)
      {
         sched_yield();
      }
   }

#if defined(ALLOCATE_THREAD_ARGS_DYNAMICALLY)
   free(thread_args_p);
#endif

#endif

   VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__DRD_START_NEW_SEGMENT,
                              pthread_self(), 0, 0, 0, 0);

   return ret;
}
Пример #8
0
CUresult I_WRAP_SONAME_FNNAME_ZZ(libcudaZdsoZa, cuMemcpyHtoA)(CUarray dstArray, size_t dstOffset, const void *srcHost, size_t ByteCount) {
   OrigFn fn;
   CUresult result;
   CUcontext ctx = NULL;
   cgCtxListType *nodeCtx;
   cgArrListType *nodeArrDst;
   cgMemListType *nodeMemSrc;
   
   long vgErrorAddress;
   int error = 0;
   
   VALGRIND_GET_ORIG_FN(fn);
   cgLock();
   CALL_FN_W_WWWW(result, fn, dstArray, dstOffset, srcHost, ByteCount);
   
   // Check if actual function parameters are defined
   if (VALGRIND_CHECK_MEM_IS_DEFINED(&dstArray, sizeof(CUarray))) {
      error++;
      VALGRIND_PRINTF("Error: dstArray in call to cuMemcpyAtoD is not defined.\n");
   } else if (!dstArray) {
      error++;
      VALGRIND_PRINTF("Error: dstArray in call to cuMemcpyAtoD is NULL.\n");
   }
   if (VALGRIND_CHECK_MEM_IS_DEFINED(&dstOffset, sizeof(size_t))) {
      error++;
      VALGRIND_PRINTF("Error: dstOffset in call to cuMemcpyAtoD is not defined.\n");
   }
   if (VALGRIND_CHECK_MEM_IS_DEFINED(&srcHost, sizeof(CUdeviceptr))) {
      error++;
      VALGRIND_PRINTF("Error: srcHost in call to cuMemcpyAtoD is not defined.\n");
   } else if (!srcHost) {
      error++;
      VALGRIND_PRINTF("Error: srcDevice in call to cuMemcpyAtoD is NULL");
   }
   if (VALGRIND_CHECK_MEM_IS_DEFINED(&ByteCount, sizeof(size_t))) {
      error++;
      VALGRIND_PRINTF("Error: ByteCount in call to cuMemcpyAtoD is not defined.\n");
   }
   
   cgGetCtx(&ctx);
   
   nodeCtx = cgFindCtx(ctx);
   
   nodeArrDst = cgFindArr(nodeCtx, dstArray);
   
   if (srcHost) {
      vgErrorAddress = VALGRIND_CHECK_MEM_IS_ADDRESSABLE(srcHost, ByteCount);
      // Check if memory referenced by srcHost has been allocated.
      if (vgErrorAddress) {
         error++;
         VALGRIND_PRINTF("Error: Source host memory in cuMemcpyHtoA is not not allocated.\n"
                         "       Expected %l bytes but only found %l.\n",
                         ByteCount, vgErrorAddress - (long)srcHost);
      } else {
         // If allocated, now check if host memory is defined.
         vgErrorAddress = VALGRIND_CHECK_MEM_IS_DEFINED(srcHost, ByteCount);
         if (vgErrorAddress) {
            error++;
            VALGRIND_PRINTF("Error: Source host memory in cuMemcpyHtoA is not defined.\n"
                            "       Expected %l bytes but only found %l.\n",
                            ByteCount, vgErrorAddress - (long)srcHost);
         }
      }
   }
   
   if (nodeArrDst) {
      // Check if array is 1-dimensional or big enough in first dimension
      if (nodeArrDst->desc.Height > 1 || nodeArrDst->desc.Depth > 1) {
         if (nodeArrDst->desc.Width - dstOffset < ByteCount) {
            error++;
            VALGRIND_PRINTF("Error: Destination array in cuMemcpyAtoD is 2-dimensional\n"
                            "       and ByteCount bigger than available width in first dimension.\n");
         } else {
            VALGRIND_PRINTF("Warning: Destination array in cuMemcpyAtoD is 2-dimensional.\n");
         }
      } else if (nodeArrDst->desc.Width - dstOffset < ByteCount) { 
            // If array is 1D, check size.
            VALGRIND_PRINTF("Error: Destination array in cuMemcpyAtoD is too small.\n"
                            "       Expected %l bytes but only found %l.\n", 
                            ByteCount, nodeArrDst->desc.Width - dstOffset);
            error++;
         }
   } else {
      error++;
      VALGRIND_PRINTF("Error: Destination array not allocated in call to cuMemcpyAtoD.\n");
   }
   
   cgUnlock();
   return result;
}