Skip to content

Issues in new PonyRT

Kiko edited this page Nov 27, 2015 · 2 revisions

These are the issues I have encountered when trying to move to the new PonyRT and the proposed solutions:

Problem1:

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.

Problem2:

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.