void pony_recv_done(pony_ctx_t* ctx) { ponyint_gc_handlestack(ctx); ponyint_gc_done(ponyint_actor_gc(ctx->current)); #ifdef USE_TELEMETRY ctx->time_in_recv_scan += (ponyint_cpu_tick() - ctx->tsc); #endif }
void pony_gc_send(pony_ctx_t* ctx) { assert(ctx->stack == NULL); ctx->trace_object = ponyint_gc_sendobject; ctx->trace_actor = ponyint_gc_sendactor; #ifdef USE_TELEMETRY ctx->tsc = ponyint_cpu_tick(); #endif }
/** * Use mpmcqs to allow stealing directly from a victim, without waiting for a * response. */ static pony_actor_t* steal(scheduler_t* sched, pony_actor_t* prev) { send_msg(0, SCHED_BLOCK, 0); uint64_t tsc = ponyint_cpu_tick(); pony_actor_t* actor; while(true) { scheduler_t* victim = choose_victim(sched); if(victim == NULL) actor = (pony_actor_t*)ponyint_mpmcq_pop(&inject); else actor = pop_global(victim); if(actor != NULL) { DTRACE3(WORK_STEAL_SUCCESSFUL, (uintptr_t)sched, (uintptr_t)victim, (uintptr_t)actor); break; } uint64_t tsc2 = ponyint_cpu_tick(); if(quiescent(sched, tsc, tsc2)) { DTRACE2(WORK_STEAL_FAILURE, (uintptr_t)sched, (uintptr_t)victim); return NULL; } // If we have been passed an actor (implicitly, the cycle detector), and // enough time has elapsed without stealing or quiescing, return the actor // we were passed (allowing the cycle detector to run). if((prev != NULL) && ((tsc2 - tsc) > 10000000000)) { actor = prev; break; } } send_msg(0, SCHED_UNBLOCK, 0); return actor; }
/** * Use mpmcqs to allow stealing directly from a victim, without waiting for a * response. */ static pony_actor_t* steal(scheduler_t* sched, pony_actor_t* prev) { send_msg(0, SCHED_BLOCK, 0); uint64_t tsc = ponyint_cpu_tick(); pony_actor_t* actor; while(true) { scheduler_t* victim = choose_victim(sched); if(victim == NULL) victim = sched; actor = pop_global(victim); if(actor != NULL) break; uint64_t tsc2 = ponyint_cpu_tick(); if(quiescent(sched, tsc, tsc2)) return NULL; // If we have been passed an actor (implicitly, the cycle detector), and // enough time has elapsed without stealing or quiescing, return the actor // we were passed (allowing the cycle detector to run). if((prev != NULL) && ((tsc2 - tsc) > 10000000000)) { actor = prev; break; } } send_msg(0, SCHED_UNBLOCK, 0); return actor; }