Example #1
0
/** Called after sem_destroy(). */
void DRD_(semaphore_destroy)(const Addr semaphore)
{
   struct semaphore_info* p;

   p = semaphore_get(semaphore);

   if (s_trace_semaphore)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d/%d] semaphore_destroy   0x%lx value %u\n",
                   VG_(get_running_tid)(),
                   DRD_(thread_get_running_tid)(),
                   semaphore,
                   p ? p->value : 0);
   }

   if (p == 0)
   {
      GenericErrInfo GEI = { DRD_(thread_get_running_tid)() };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              GenericErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Not a semaphore",
                              &GEI);
      return;
   }

   DRD_(clientobj_remove)(semaphore, ClientSemaphore);
}
Example #2
0
/** Called after sem_destroy(). */
void semaphore_destroy(const Addr semaphore)
{
  struct semaphore_info* p;

  if (s_trace_semaphore)
  {
    VG_(message)(Vg_UserMsg,
                 "[%d/%d] semaphore_destroy 0x%lx",
                 VG_(get_running_tid)(),
                 thread_get_running_tid(),
                 semaphore);
  }

  p = semaphore_get(semaphore);

  if (p == 0)
  {
    GenericErrInfo GEI;
    VG_(maybe_record_error)(VG_(get_running_tid)(),
                            GenericErr,
                            VG_(get_IP)(VG_(get_running_tid)()),
                            "Not a semaphore",
                            &GEI);
    return;
  }

  clientobj_remove(semaphore, ClientSemaphore);
}
Example #3
0
/** Called before sem_init(). */
struct semaphore_info* DRD_(semaphore_init)(const Addr semaphore,
                                            const Word pshared,
                                            const UInt value)
{
   struct semaphore_info* p;
   Segment* sg;

   if (s_trace_semaphore)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d] sem_init      0x%lx value %u\n",
                   DRD_(thread_get_running_tid)(),
                   semaphore,
                   value);
   }
   p = semaphore_get(semaphore);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      SemaphoreErrInfo SEI = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(vg_tid,
                              SemaphoreErr,
                              VG_(get_IP)(vg_tid),
                              "Semaphore reinitialization",
                              &SEI);
      // Remove all segments from the segment stack.
      while ((sg = drd_segment_pop(p)))
      {
         DRD_(sg_put)(sg);
      }
   }
   else
   {
#if defined(VGO_darwin)
      const ThreadId vg_tid = VG_(get_running_tid)();
      GenericErrInfo GEI = { DRD_(thread_get_running_tid)(), 0 };
      VG_(maybe_record_error)(vg_tid,
			      GenericErr,
			      VG_(get_IP)(vg_tid),
			      "sem_init() is not yet supported on Darwin",
			      &GEI);
      return NULL;
#else
      p = drd_semaphore_get_or_allocate(semaphore);
#endif
   }
   tl_assert(p);
   p->waits_to_skip = value;
   p->value         = value;
   return p;
}
Example #4
0
/** Called before sem_init(). */
struct semaphore_info* DRD_(semaphore_init)(const Addr semaphore,
                                            const Word pshared,
                                            const UInt value)
{
   struct semaphore_info* p;
   Segment* sg;

   if (s_trace_semaphore)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d/%d] semaphore_init      0x%lx value %u\n",
                   VG_(get_running_tid)(),
                   DRD_(thread_get_running_tid)(),
                   semaphore,
                   value);
   }
   p = semaphore_get(semaphore);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      SemaphoreErrInfo SEI = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(vg_tid,
                              SemaphoreErr,
                              VG_(get_IP)(vg_tid),
                              "Semaphore reinitialization",
                              &SEI);
      // Remove all segments from the segment stack.
      while ((sg = DRD_(segment_pop)(p)))
      {
         DRD_(sg_put)(sg);
      }
   }
   else
   {
      p = DRD_(semaphore_get_or_allocate)(semaphore);
   }
   tl_assert(p);
   p->waits_to_skip = value;
   p->value         = value;
   return p;
}
Example #5
0
/** Called before sem_init(). */
struct semaphore_info* semaphore_init(const Addr semaphore,
                                      const Word pshared, const UWord value)
{
  struct semaphore_info* p;

  if (s_trace_semaphore)
  {
    VG_(message)(Vg_UserMsg,
                 "[%d/%d] semaphore_init 0x%lx",
                 VG_(get_running_tid)(),
                 thread_get_running_tid(),
                 semaphore);
  }
  if (semaphore_get(semaphore))
  {
    // To do: print an error message that a semaphore is being reinitialized.
  }
  p = semaphore_get_or_allocate(semaphore);
  p->value = value;
  return p;
}
Example #6
0
/** Called after sem_wait() finished.
 *  @note Do not rely on the value of 'waited' -- some glibc versions do
 *        not set it correctly.
 */
void semaphore_post_wait(const DrdThreadId tid, const Addr semaphore,
                         const Bool waited)
{
  struct semaphore_info* p;

  p = semaphore_get(semaphore);
  if (s_trace_semaphore)
  {
    VG_(message)(Vg_UserMsg,
                 "[%d/%d] semaphore_post_wait 0x%lx",
                 VG_(get_running_tid)(),
                 thread_get_running_tid(),
                 semaphore);
  }
  tl_assert(p->waiters > 0);
  p->waiters--;
  tl_assert(p->waiters >= 0);
  tl_assert(p->value >= 0);
  if (p->value == 0)
  {
    SemaphoreErrInfo sei = { semaphore };
    VG_(maybe_record_error)(VG_(get_running_tid)(),
                            SemaphoreErr,
                            VG_(get_IP)(VG_(get_running_tid)()),
                            "Invalid semaphore",
                            &sei);
    return;
  }
  p->value--;
  tl_assert(p->value >= 0);
  if (p->last_sem_post_tid != tid
      && p->last_sem_post_tid != DRD_INVALID_THREADID)
  {
    tl_assert(p->last_sem_post_segment);
    thread_combine_vc2(tid, &p->last_sem_post_segment->vc);
  }
  thread_new_segment(tid);
}
Example #7
0
/** Called after sem_destroy(). */
void DRD_(semaphore_destroy)(const Addr semaphore)
{
   struct semaphore_info* p;

   p = semaphore_get(semaphore);

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_destroy   0x%lx value %u",
                      DRD_(thread_get_running_tid)(), semaphore,
                      p ? p->value : 0);

   if (p == 0)
   {
      GenericErrInfo GEI = {
	 .tid  = DRD_(thread_get_running_tid)(),
	 .addr = semaphore,
      };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              GenericErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Not a semaphore",
                              &GEI);
      return;
   }
Example #8
0
/**
 * Called after sem_wait() finished.
 * @note Do not rely on the value of 'waited' -- some glibc versions do
 *       not set it correctly.
 */
void DRD_(semaphore_post_wait)(const DrdThreadId tid, const Addr semaphore,
                               const Bool waited)
{
   struct semaphore_info* p;
   Segment* sg;

   p = semaphore_get(semaphore);
   if (s_trace_semaphore)
   {
      VG_(message)(Vg_UserMsg,
                   "[%d/%d] semaphore_wait      0x%lx value %u -> %u\n",
                   VG_(get_running_tid)(),
                   DRD_(thread_get_running_tid)(),
                   semaphore,
                   p ? p->value : 0,
                   p ? p->value - 1 : 0);
   }

   if (p)
   {
      p->waiters--;
      p->value--;
   }

   /*
    * Note: if another thread destroyed and reinitialized a semaphore while
    * the current thread was waiting in sem_wait, p->waiters may have been
    * set to zero by DRD_(semaphore_initialize)() after
    * DRD_(semaphore_pre_wait)() has finished before
    * DRD_(semaphore_post_wait)() has been called.
    */
   if (p == NULL || (int)p->value < 0 || (int)p->waiters < 0)
   {
      SemaphoreErrInfo sei = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              SemaphoreErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Invalid semaphore",
                              &sei);
      return;
   }

   if (p->waits_to_skip > 0)
      p->waits_to_skip--;
   else
   {
      sg = DRD_(segment_pop)(p);
      tl_assert(sg);
      if (sg)
      {
         if (p->last_sem_post_tid != tid
             && p->last_sem_post_tid != DRD_INVALID_THREADID)
         {
            DRD_(thread_new_segment_and_combine_vc)(tid, sg);
         }
         else
            DRD_(thread_new_segment)(tid);
         s_semaphore_segment_creation_count++;
         DRD_(sg_put)(sg);
      }
   }
}