/** 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; }
/** * Free the memory that was allocated by semaphore_initialize(). Called by * DRD_(clientobj_remove)(). */ static void semaphore_cleanup(struct semaphore_info* p) { Segment* sg; if (p->waiters > 0) { SemaphoreErrInfo sei = { DRD_(thread_get_running_tid)(), p->a1 }; VG_(maybe_record_error)(VG_(get_running_tid)(), SemaphoreErr, VG_(get_IP)(VG_(get_running_tid)()), "Destruction of semaphore that is being waited" " upon", &sei); } while ((sg = drd_segment_pop(p))) DRD_(sg_put)(sg); VG_(deleteXA)(p->last_sem_post_seg); }