Created
October 12, 2017 18:20
-
-
Save Praetonus/e6f9d24d1f88e4d1fbfd97dbdc340fef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git i/src/libponyc/codegen/codegen.c w/src/libponyc/codegen/codegen.c | |
index 0aa8de7fb..484f3948a 100644 | |
--- i/src/libponyc/codegen/codegen.c | |
+++ w/src/libponyc/codegen/codegen.c | |
@@ -336,12 +336,13 @@ static void init_runtime(compile_t* c) | |
# endif | |
#endif | |
- // void pony_sendv(i8*, __object*, $message*, $message*) | |
+ // void pony_sendv(i8*, __object*, $message*, $message*, i1) | |
params[0] = c->void_ptr; | |
params[1] = c->object_ptr; | |
params[2] = c->msg_ptr; | |
params[3] = c->msg_ptr; | |
- type = LLVMFunctionType(c->void_type, params, 4, false); | |
+ params[4] = c->i1; | |
+ type = LLVMFunctionType(c->void_type, params, 5, false); | |
value = LLVMAddFunction(c->module, "pony_sendv", type); | |
#if PONY_LLVM >= 309 | |
LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); | |
@@ -354,12 +355,13 @@ static void init_runtime(compile_t* c) | |
# endif | |
#endif | |
- // void pony_sendv_single(i8*, __object*, $message*, $message*) | |
+ // void pony_sendv_single(i8*, __object*, $message*, $message*, i1) | |
params[0] = c->void_ptr; | |
params[1] = c->object_ptr; | |
params[2] = c->msg_ptr; | |
params[3] = c->msg_ptr; | |
- type = LLVMFunctionType(c->void_type, params, 4, false); | |
+ params[4] = c->i1; | |
+ type = LLVMFunctionType(c->void_type, params, 5, false); | |
value = LLVMAddFunction(c->module, "pony_sendv_single", type); | |
#if PONY_LLVM >= 309 | |
LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); | |
diff --git i/src/libponyc/codegen/gencall.c w/src/libponyc/codegen/gencall.c | |
index d29fbe384..71047a39a 100644 | |
--- i/src/libponyc/codegen/gencall.c | |
+++ w/src/libponyc/codegen/gencall.c | |
@@ -536,7 +536,7 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], | |
arg_ast = ast_sibling(arg_ast); | |
} | |
- LLVMValueRef msg_args[4]; | |
+ LLVMValueRef msg_args[5]; | |
msg_args[0] = LLVMConstInt(c->i32, ponyint_pool_index(msg_size), false); | |
msg_args[1] = LLVMConstInt(c->i32, m->vtable_index, false); | |
@@ -595,12 +595,13 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], | |
msg_args[1] = LLVMBuildBitCast(c->builder, args[0], c->object_ptr, ""); | |
msg_args[2] = msg; | |
msg_args[3] = msg; | |
+ msg_args[4] = LLVMConstInt(c->i1, 1, false); | |
LLVMValueRef send; | |
if(ast_id(m->r_fun) == TK_NEW) | |
- send = gencall_runtime(c, "pony_sendv_single", msg_args, 4, ""); | |
+ send = gencall_runtime(c, "pony_sendv_single", msg_args, 5, ""); | |
else | |
- send = gencall_runtime(c, "pony_sendv", msg_args, 4, ""); | |
+ send = gencall_runtime(c, "pony_sendv", msg_args, 5, ""); | |
LLVMSetMetadataStr(send, "pony.msgsend", md); | |
diff --git i/src/libponyc/codegen/genexe.c w/src/libponyc/codegen/genexe.c | |
index 748d4660f..a646280fc 100644 | |
--- i/src/libponyc/codegen/genexe.c | |
+++ w/src/libponyc/codegen/genexe.c | |
@@ -47,7 +47,7 @@ LLVMValueRef gen_main(compile_t* c, reach_type_t* t_main, reach_type_t* t_env) | |
codegen_startfun(c, func, NULL, NULL, false); | |
- LLVMValueRef args[4]; | |
+ LLVMValueRef args[5]; | |
args[0] = LLVMGetParam(func, 0); | |
LLVMSetValueName(args[0], "argc"); | |
@@ -121,7 +121,8 @@ LLVMValueRef gen_main(compile_t* c, reach_type_t* t_main, reach_type_t* t_env) | |
args[1] = main_actor; | |
args[2] = msg; | |
args[3] = msg; | |
- gencall_runtime(c, "pony_sendv_single", args, 4, ""); | |
+ args[4] = LLVMConstInt(c->i1, 1, false); | |
+ gencall_runtime(c, "pony_sendv_single", args, 5, ""); | |
// Start the runtime. | |
args[0] = LLVMConstInt(c->i32, 0, false); | |
diff --git i/src/libponyrt/actor/actor.c w/src/libponyrt/actor/actor.c | |
index 21905e1a3..0898b5f71 100644 | |
--- i/src/libponyrt/actor/actor.c | |
+++ w/src/libponyrt/actor/actor.c | |
@@ -417,7 +417,7 @@ PONY_API pony_msg_t* pony_alloc_msg_size(size_t size, uint32_t id) | |
} | |
PONY_API void pony_sendv(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
- pony_msg_t* last) | |
+ pony_msg_t* last, bool has_app_msg) | |
{ | |
// The function takes a prebuilt chain instead of varargs because the latter | |
// is expensive and very hard to optimise. | |
@@ -437,7 +437,8 @@ PONY_API void pony_sendv(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
DTRACE2(ACTOR_MSG_SEND, (uintptr_t)ctx->scheduler, last->id); | |
} | |
- ponyint_maybe_mute(ctx, to, first, last); | |
+ if(has_app_msg) | |
+ ponyint_maybe_mute(ctx, to); | |
if(ponyint_messageq_push(&to->q, first, last)) | |
{ | |
@@ -449,7 +450,7 @@ PONY_API void pony_sendv(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
} | |
PONY_API void pony_sendv_single(pony_ctx_t* ctx, pony_actor_t* to, | |
- pony_msg_t* first, pony_msg_t* last) | |
+ pony_msg_t* first, pony_msg_t* last, bool has_app_msg) | |
{ | |
// The function takes a prebuilt chain instead of varargs because the latter | |
// is expensive and very hard to optimise. | |
@@ -469,7 +470,8 @@ PONY_API void pony_sendv_single(pony_ctx_t* ctx, pony_actor_t* to, | |
DTRACE2(ACTOR_MSG_SEND, (uintptr_t)ctx->scheduler, last->id); | |
} | |
- ponyint_maybe_mute(ctx, to, first, last); | |
+ if(has_app_msg) | |
+ ponyint_maybe_mute(ctx, to); | |
if(ponyint_messageq_push_single(&to->q, first, last)) | |
{ | |
@@ -482,8 +484,7 @@ PONY_API void pony_sendv_single(pony_ctx_t* ctx, pony_actor_t* to, | |
} | |
} | |
-void ponyint_maybe_mute(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
- pony_msg_t* last) | |
+void ponyint_maybe_mute(pony_ctx_t* ctx, pony_actor_t* to) | |
{ | |
if(ctx->current != NULL) | |
{ | |
@@ -497,29 +498,7 @@ void ponyint_maybe_mute(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
(atomic_load_explicit(&to->muted, memory_order_relaxed) > 0)) && | |
!has_flag(ctx->current, FLAG_OVERLOADED) && | |
ctx->current != to) | |
- { | |
- if (first == last) | |
- { | |
- if(first->id <= ACTORMSG_APPLICATION_START) | |
- { | |
- ponyint_sched_mute(ctx, ctx->current, to); | |
- return; | |
- } | |
- } | |
- | |
- pony_msg_t* m = first; | |
- | |
- while(m != last) | |
- { | |
- if(m->id <= ACTORMSG_APPLICATION_START) | |
- { | |
- ponyint_sched_mute(ctx, ctx->current, to); | |
- return; | |
- } | |
- | |
- m = atomic_load_explicit(&m->next, memory_order_relaxed); | |
- } | |
- } | |
+ ponyint_sched_mute(ctx, ctx->current, to); | |
} | |
} | |
@@ -532,7 +511,7 @@ PONY_API void pony_chain(pony_msg_t* prev, pony_msg_t* next) | |
PONY_API void pony_send(pony_ctx_t* ctx, pony_actor_t* to, uint32_t id) | |
{ | |
pony_msg_t* m = pony_alloc_msg(POOL_INDEX(sizeof(pony_msg_t)), id); | |
- pony_sendv(ctx, to, m, m); | |
+ pony_sendv(ctx, to, m, m, id <= ACTORMSG_APPLICATION_START); | |
} | |
PONY_API void pony_sendp(pony_ctx_t* ctx, pony_actor_t* to, uint32_t id, | |
@@ -542,7 +521,7 @@ PONY_API void pony_sendp(pony_ctx_t* ctx, pony_actor_t* to, uint32_t id, | |
POOL_INDEX(sizeof(pony_msgp_t)), id); | |
m->p = p; | |
- pony_sendv(ctx, to, &m->msg, &m->msg); | |
+ pony_sendv(ctx, to, &m->msg, &m->msg, id <= ACTORMSG_APPLICATION_START); | |
} | |
PONY_API void pony_sendi(pony_ctx_t* ctx, pony_actor_t* to, uint32_t id, | |
@@ -552,7 +531,7 @@ PONY_API void pony_sendi(pony_ctx_t* ctx, pony_actor_t* to, uint32_t id, | |
POOL_INDEX(sizeof(pony_msgi_t)), id); | |
m->i = i; | |
- pony_sendv(ctx, to, &m->msg, &m->msg); | |
+ pony_sendv(ctx, to, &m->msg, &m->msg, id <= ACTORMSG_APPLICATION_START); | |
} | |
#ifdef USE_ACTOR_CONTINUATIONS | |
diff --git i/src/libponyrt/actor/actor.h w/src/libponyrt/actor/actor.h | |
index 828f1621d..fe3a4aba7 100644 | |
--- i/src/libponyrt/actor/actor.h | |
+++ w/src/libponyrt/actor/actor.h | |
@@ -61,8 +61,7 @@ void ponyint_actor_setoverloaded(pony_actor_t* actor); | |
void ponyint_actor_unsetoverloaded(pony_ctx_t* ctx, pony_actor_t* actor); | |
-void ponyint_maybe_mute(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
- pony_msg_t* last); | |
+void ponyint_maybe_mute(pony_ctx_t* ctx, pony_actor_t* to); | |
PONY_API void ponyint_destroy(pony_actor_t* actor); | |
diff --git i/src/libponyrt/asio/event.c w/src/libponyrt/asio/event.c | |
index 280900f87..4c9aba895 100644 | |
--- i/src/libponyrt/asio/event.c | |
+++ w/src/libponyrt/asio/event.c | |
@@ -118,5 +118,8 @@ PONY_API void pony_asio_event_send(asio_event_t* ev, uint32_t flags, | |
pony_register_thread(); | |
#endif | |
- pony_sendv(pony_ctx(), ev->owner, &m->msg, &m->msg); | |
+ // ASIO messages technically are application messages, but since they have no | |
+ // sender they aren't covered by backpressure. We pass false for an early | |
+ // bailout in the backpressure code. | |
+ pony_sendv(pony_ctx(), ev->owner, &m->msg, &m->msg, false); | |
} | |
diff --git i/src/libponyrt/gc/cycle.c w/src/libponyrt/gc/cycle.c | |
index e289e1c62..90f12f578 100644 | |
--- i/src/libponyrt/gc/cycle.c | |
+++ w/src/libponyrt/gc/cycle.c | |
@@ -922,7 +922,7 @@ void ponyint_cycle_block(pony_ctx_t* ctx, pony_actor_t* actor, gc_t* gc) | |
m->delta = ponyint_gc_delta(gc); | |
pony_assert(gc->delta == NULL); | |
- pony_sendv(ctx, cycle_detector, &m->msg, &m->msg); | |
+ pony_sendv(ctx, cycle_detector, &m->msg, &m->msg, false); | |
} | |
void ponyint_cycle_unblock(pony_ctx_t* ctx, pony_actor_t* actor) | |
diff --git i/src/libponyrt/pony.h w/src/libponyrt/pony.h | |
index 2a6aa9e60..81c8dbfd3 100644 | |
--- i/src/libponyrt/pony.h | |
+++ w/src/libponyrt/pony.h | |
@@ -175,9 +175,11 @@ PONY_API pony_msg_t* pony_alloc_msg_size(size_t size, uint32_t id); | |
* | |
* The first and last messages must either be the same message or the two ends | |
* of a chain built with calls to pony_chain. | |
+ * | |
+ * has_app_msg should be true if there are application messages in the chain. | |
*/ | |
PONY_API void pony_sendv(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
- pony_msg_t* last); | |
+ pony_msg_t* last, bool has_app_msg); | |
/** Single producer version of pony_sendv. | |
* | |
@@ -188,9 +190,11 @@ PONY_API void pony_sendv(pony_ctx_t* ctx, pony_actor_t* to, pony_msg_t* first, | |
* | |
* The first and last messages must either be the same message or the two ends | |
* of a chain built with calls to pony_chain. | |
+ * | |
+ * has_app_msg should be true if there are application messages in the chain. | |
*/ | |
PONY_API void pony_sendv_single(pony_ctx_t* ctx, pony_actor_t* to, | |
- pony_msg_t* first, pony_msg_t* last); | |
+ pony_msg_t* first, pony_msg_t* last, bool has_app_msg); | |
/** Chain two messages together. | |
* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment