-
Notifications
You must be signed in to change notification settings - Fork 26
Issues in new PonyRT
These are the issues I have encountered when trying to move to the new PonyRT and the proposed solutions:
The pony interface has changed. Pretty much all functions require a new argument of type pony_ctx_t
(opaque type). There's a method for getting the context (pony_ctx()
). The problem is that we need to change all the code generation for the functions that use the ctx
.
Solution: Mimic the old pony.h
(without ctx
) in encore.h
and remove all references to pony_*
. Internally, all pony calls in encore.h
will do a call to pony_ctx()
and, afterwards, call the corresponding pony function. i.e.
//pony.h
pony_actor_t* pony_create(pony_ctx_t* ctx, pony_type_t* type);
//encore.h
pony_actor_t* encore_create(pony_type_t* type);
//encore.c
pony_actor_t* encore_create(pony_type_t* type){
pony_ctx_t* ctx = pony_ctx();
return pony_create(ctx, type);
}
This means changing the code generation in the encore compiler and change the name pony_create
to encore_create
. The number of arguments are the same (less changes). This also means that there is an extra overhead inside each encore method call. The reason is that we might have:
let a = new Actor
b = new Actor
in
a.send(b)
which creates actors and sends messages and, each one will perform a call to get the same ctx
. In this case, we call the same function (at least) 3 times to get the same ctx
.
Global functions are defined as closures and called from the main method:
int main(int argc, char** argv){
_enc__closure_compose = closure_mk(_enc__global_fun_compose, NULL, NULL);
return encore_start(argc, argv, (&(_enc__active_Main_type)));
}
In closure.h
, we do a trick to check if we should use malloc
or pony_alloc
.
#define ALLOC(size) (actor_current() ? pony_alloc(size) : malloc(size))
Currently, actor_current()
would need a context and, since we have no context (a context
should point to the scheduler
and the current actor
, we have no info about these yet) before we run encore_start
, calling the actor_current()
at this point will produce a segfault
.
Solution: Either we use malloc
for now and live with this memory leak or we start refactoring code and make top level functions to not behave as closures
.