static void* _profile_stream_thread(void* arg) { FOUNDATION_UNUSED(arg); thread_yield(); while (!thread_try_wait(4)) { profile_log(STRING_CONST("Thread message")); profile_begin_block(STRING_CONST("Thread block")); { profile_update_block(); profile_begin_block(STRING_CONST("Thread subblock")); { profile_log(STRING_CONST("Sub message")); profile_trylock(STRING_CONST("Trylock")); profile_lock(STRING_CONST("Trylock")); profile_wait(STRING_CONST("Wait")); profile_signal(STRING_CONST("Signal")); thread_sleep(2); profile_unlock(STRING_CONST("Trylock")); profile_log(STRING_CONST("End sub")); } profile_end_block(); profile_begin_block(STRING_CONST("Thread second subblock")); { profile_update_block(); profile_begin_block(STRING_CONST("Thread subblock")); { } profile_end_block(); } profile_end_block(); profile_trylock(STRING_CONST("Trylock")); thread_sleep(1); profile_lock(STRING_CONST("Trylock")); thread_sleep(4); profile_unlock(STRING_CONST("Trylock")); } profile_end_block(); atomic_add64(&_profile_generated_blocks, 14); } return 0; }
static void* _profile_stream_thread( object_t thread, void* arg ) { FOUNDATION_UNUSED( arg ); thread_yield(); while( !thread_should_terminate( thread ) ) { profile_log( "Thread message" ); profile_begin_block( "Thread block" ); { profile_update_block(); profile_begin_block( "Thread subblock" ); { profile_log( "Sub message" ); profile_trylock( "Trylock" ); profile_lock( "Trylock" ); profile_wait( "Wait" ); profile_signal( "Signal" ); thread_sleep( 2 ); profile_unlock( "Trylock" ); profile_log( "End sub" ); } profile_end_block(); profile_trylock( "Trylock" ); thread_sleep( 1 ); profile_lock( "Trylock" ); thread_sleep( 4 ); profile_unlock( "Trylock" ); } profile_end_block(); thread_sleep( 4 ); atomic_add64( &_profile_generated_blocks, 12 ); } return 0; }
bool mutex_unlock(mutex_t* mutex) { if (!mutex->lockcount) { log_warnf(0, WARNING_SUSPICIOUS, STRING_CONST("Unable to unlock unlocked mutex %.*s"), (int)mutex->name.length, mutex->name.str); return false; } FOUNDATION_ASSERT(mutex->lockedthread == thread_id()); --mutex->lockcount; #if !BUILD_DEPLOY profile_unlock(mutex->name.str, mutex->name.length); #endif #if FOUNDATION_PLATFORM_WINDOWS LeaveCriticalSection((CRITICAL_SECTION*)mutex->csection); #elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL if (pthread_mutex_unlock(&mutex->mutex) != 0) { FOUNDATION_ASSERT_FAILFORMAT("unable to unlock mutex %s", mutex->name.str); return false; } #else # error mutex_unlock not implemented #endif return true; }
void LJ_FASTCALL lj_profile_hook_leave(global_State *g) { ProfileState *ps = &profile_state; if (ps->g) { profile_lock(ps); hook_leave(g); profile_unlock(ps); } else { hook_leave(g); } }
/* Callback from profile hook (HOOK_PROFILE already cleared). */ void LJ_FASTCALL lj_profile_interpreter(lua_State *L) { ProfileState *ps = &profile_state; global_State *g = G(L); uint8_t mask; profile_lock(ps); mask = (g->hookmask & ~HOOK_PROFILE); if (!(mask & HOOK_VMEVENT)) { int samples = ps->samples; ps->samples = 0; g->hookmask = HOOK_VMEVENT; lj_dispatch_update(g); profile_unlock(ps); ps->cb(ps->data, L, samples, ps->vmstate); /* Invoke user callback. */ profile_lock(ps); mask |= (g->hookmask & HOOK_PROFILE); } g->hookmask = mask; lj_dispatch_update(g); profile_unlock(ps); }
/* Trigger profile hook. Asynchronous call from OS-specific profile timer. */ static void profile_trigger(ProfileState *ps) { global_State *g = ps->g; uint8_t mask; profile_lock(ps); ps->samples++; /* Always increment number of samples. */ mask = g->hookmask; if (!(mask & (HOOK_PROFILE|HOOK_VMEVENT))) { /* Set profile hook. */ int st = g->vmstate; ps->vmstate = st >= 0 ? 256+st : st == ~LJ_VMST_INTERP ? 'I' : st == ~LJ_VMST_C ? 'C' : st == ~LJ_VMST_GC ? 'G' : 'J'; g->hookmask = (mask | HOOK_PROFILE); lj_dispatch_update(g); } profile_unlock(ps); }
static void* _profile_fail_thread(void* arg) { FOUNDATION_UNUSED(arg); thread_sleep(10); while (!thread_try_wait(1)) { profile_log(STRING_CONST("Thread message")); profile_begin_block(STRING_CONST("Thread block")); { profile_update_block(); profile_begin_block(STRING_CONST("Thread subblock")); { profile_log(STRING_CONST("Sub message")); profile_trylock(STRING_CONST("Trylock")); profile_lock(STRING_CONST("Trylock")); profile_wait(STRING_CONST("Wait")); profile_signal(STRING_CONST("Signal")); profile_unlock(STRING_CONST("Trylock")); profile_log(STRING_CONST("End sub")); thread_yield(); } profile_end_block(); } profile_end_block(); } return 0; }