Skip to content

Commit

Permalink
Revert "Remove exception parameterisation from serialisation (#2524)"
Browse files Browse the repository at this point in the history
This reverts commit d34dce6.

While performance testing the Pony version of Wallaroo's Market Spread
application in a multi worker scenario, it was discovered that the above
commit introduced a performance regression in both throughput and latency.
This regression is not present in a single worker run where serialisation
is not used. It should be noted that this regression only occurs when
consuming messages at a maximum rate and is not present if the sending
worker is not performing at maximum capacity. With this commit reverted,
sending in messages at the same rate resulted in higher throughput
and lower latencies.

If an example application is needed to recreate this behavior we can
provide instructions to run the Wallaroo application or attempt to
create a minimal example.
  • Loading branch information
JONBRWN authored and SeanTAllen committed Jun 6, 2018
1 parent 1025d76 commit e52ef29
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 18 deletions.
6 changes: 4 additions & 2 deletions packages/serialise/serialise.pony
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ class val Serialised
@{(ctx: Pointer[None], size: USize): Pointer[None] =>
@pony_alloc[Pointer[None]](ctx, size)
}
let throw_fn = @{() ? => error }
@pony_serialise[None](@pony_ctx[Pointer[None]](), data, Pointer[None], r,
alloc_fn) ?
alloc_fn, throw_fn) ?
_data = consume r

new input(auth: InputSerialisedAuth, data: Array[U8] val) =>
Expand All @@ -118,8 +119,9 @@ class val Serialised
@{(ctx: Pointer[None], size: USize): Pointer[None] =>
@pony_alloc_final[Pointer[None]](ctx, size)
}
let throw_fn = @{() ? => error }
@pony_deserialise[Any iso^](@pony_ctx[Pointer[None]](), Pointer[None], _data,
alloc_fn, alloc_final_fn) ?
alloc_fn, alloc_final_fn, throw_fn) ?

fun output(auth: OutputSerialisedAuth): Array[U8] val =>
"""
Expand Down
8 changes: 7 additions & 1 deletion src/libponyc/pkg/package.c
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,12 @@ static void* s_alloc_fn(pony_ctx_t* ctx, size_t size)
}


static void s_throw_fn()
{
pony_assert(false);
}


// TODO: Make group signature indiependent of package load order.
const char* package_group_signature(package_group_t* group)
{
Expand All @@ -1530,7 +1536,7 @@ const char* package_group_signature(package_group_t* group)
char* buf = (char*)ponyint_pool_alloc_size(SIGNATURE_LENGTH);

pony_serialise(&ctx, group, package_group_signature_pony_type(), &array,
s_alloc_fn);
s_alloc_fn, s_throw_fn);
int status = blake2b(buf, SIGNATURE_LENGTH, array.ptr, array.size, NULL, 0);
(void)status;
pony_assert(status == 0);
Expand Down
22 changes: 15 additions & 7 deletions src/libponyrt/gc/serialise.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ void ponyint_serialise_actor(pony_ctx_t* ctx, pony_actor_t* actor)
(void)ctx;
(void)actor;
serialise_cleanup(ctx);
pony_error();
ctx->serialise_throw();
abort();
}

PONY_API void pony_serialise_reserve(pony_ctx_t* ctx, void* p, size_t size)
Expand Down Expand Up @@ -197,14 +198,16 @@ PONY_API size_t pony_serialise_offset(pony_ctx_t* ctx, void* p)
}

PONY_API void pony_serialise(pony_ctx_t* ctx, void* p, pony_type_t* t,
ponyint_array_t* out, serialise_alloc_fn alloc_fn)
ponyint_array_t* out, serialise_alloc_fn alloc_fn,
serialise_throw_fn throw_fn)
{
// This can raise an error.
pony_assert(ctx->stack == NULL);
ctx->trace_object = ponyint_serialise_object;
ctx->trace_actor = ponyint_serialise_actor;
ctx->serialise_size = 0;
ctx->serialise_alloc = alloc_fn;
ctx->serialise_throw = throw_fn;

if(t != NULL)
pony_traceknown(ctx, p, t, PONY_TRACE_MUTABLE);
Expand Down Expand Up @@ -269,7 +272,8 @@ PONY_API void* pony_deserialise_offset(pony_ctx_t* ctx, pony_type_t* t,
if((offset + sizeof(uintptr_t)) > ctx->serialise_size)
{
serialise_cleanup(ctx);
pony_error();
ctx->serialise_throw();
abort();
}

// Turn the type id into a descriptor pointer.
Expand All @@ -285,7 +289,8 @@ PONY_API void* pony_deserialise_offset(pony_ctx_t* ctx, pony_type_t* t,
if((offset + t->size) > ctx->serialise_size)
{
serialise_cleanup(ctx);
pony_error();
ctx->serialise_throw();
abort();
}

// Allocate the object, memcpy to it.
Expand Down Expand Up @@ -321,7 +326,8 @@ PONY_API void* pony_deserialise_block(pony_ctx_t* ctx, uintptr_t offset,
if((offset + size) > ctx->serialise_size)
{
serialise_cleanup(ctx);
pony_error();
ctx->serialise_throw();
abort();
}

void* block = ctx->serialise_alloc(ctx, size);
Expand Down Expand Up @@ -350,7 +356,8 @@ PONY_API void* pony_deserialise_raw(pony_ctx_t* ctx, uintptr_t offset,
if(object == NULL)
{
serialise_cleanup(ctx);
pony_error();
ctx->serialise_throw();
abort();
}

// Store a mapping of offset to object.
Expand All @@ -367,13 +374,14 @@ PONY_API void* pony_deserialise_raw(pony_ctx_t* ctx, uintptr_t offset,

PONY_API void* pony_deserialise(pony_ctx_t* ctx, pony_type_t* t,
ponyint_array_t* in, serialise_alloc_fn alloc_fn,
serialise_alloc_fn alloc_final_fn)
serialise_alloc_fn alloc_final_fn, serialise_throw_fn throw_fn)
{
// This can raise an error.
ctx->serialise_buffer = in->ptr;
ctx->serialise_size = in->size;
ctx->serialise_alloc = alloc_fn;
ctx->serialise_alloc_final = alloc_final_fn;
ctx->serialise_throw = throw_fn;

void* object = pony_deserialise_offset(ctx, t, 0);
ponyint_gc_handlestack(ctx);
Expand Down
7 changes: 5 additions & 2 deletions src/libponyrt/gc/serialise.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ typedef struct

typedef void* (*serialise_alloc_fn)(pony_ctx_t* ctx, size_t size);

typedef void (*serialise_throw_fn)();

typedef void* (*deserialise_raw_fn)(void* buf, size_t remaining_size);

typedef struct serialise_t serialise_t;
Expand All @@ -29,13 +31,14 @@ void ponyint_serialise_object(pony_ctx_t* ctx, void* p, pony_type_t* t,
void ponyint_serialise_actor(pony_ctx_t* ctx, pony_actor_t* actor);

PONY_API void pony_serialise(pony_ctx_t* ctx, void* p, pony_type_t* t,
ponyint_array_t* out, serialise_alloc_fn alloc_fn);
ponyint_array_t* out, serialise_alloc_fn alloc_fn,
serialise_throw_fn throw_fn);
PONY_API size_t pony_serialise_offset(pony_ctx_t* ctx, void* p);
PONY_API void pony_serialise_reserve(pony_ctx_t* ctx, void* p, size_t size);

PONY_API void* pony_deserialise(pony_ctx_t* ctx, pony_type_t* t,
ponyint_array_t* in, serialise_alloc_fn alloc_fn,
serialise_alloc_fn alloc_final_fn);
serialise_alloc_fn alloc_final_fn, serialise_throw_fn throw_fn);
PONY_API void* pony_deserialise_block(pony_ctx_t* ctx, uintptr_t offset,
size_t size);
PONY_API void* pony_deserialise_offset(pony_ctx_t* ctx, pony_type_t* t,
Expand Down
1 change: 1 addition & 0 deletions src/libponyrt/sched/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef struct pony_ctx_t
ponyint_serialise_t serialise;
serialise_alloc_fn serialise_alloc;
serialise_alloc_fn serialise_alloc_final;
serialise_throw_fn serialise_throw;
} pony_ctx_t;

struct scheduler_t
Expand Down
13 changes: 9 additions & 4 deletions test/libponyc/compiler_serialisation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ static void* s_alloc_fn(pony_ctx_t* ctx, size_t size)
return ponyint_pool_alloc_size(size);
}

static void s_throw_fn()
{
throw std::exception{};
}

struct pool_size_deleter
{
size_t size;
Expand Down Expand Up @@ -94,11 +99,11 @@ void CompilerSerialisationTest::test_pass_ast(const char* pass)
ponyint_array_t array;
memset(&array, 0, sizeof(ponyint_array_t));

pony_serialise(&ctx, program, ast_pony_type(), &array, s_alloc_fn);
pony_serialise(&ctx, program, ast_pony_type(), &array, s_alloc_fn, s_throw_fn);
auto array_guard = manage_array(array);
std::unique_ptr<ast_t, ast_deleter> new_guard{
(ast_t*)pony_deserialise(&ctx, ast_pony_type(), &array, s_alloc_fn,
s_alloc_fn)};
s_alloc_fn, s_throw_fn)};

ast_t* new_program = new_guard.get();

Expand Down Expand Up @@ -134,12 +139,12 @@ void CompilerSerialisationTest::test_pass_reach(const char* pass)
ponyint_array_t array;
memset(&array, 0, sizeof(ponyint_array_t));

pony_serialise(&ctx, r, reach_pony_type(), &array, s_alloc_fn);
pony_serialise(&ctx, r, reach_pony_type(), &array, s_alloc_fn, s_throw_fn);
auto array_guard = manage_array(array);
array_guard.get_deleter().size = array.size;
std::unique_ptr<reach_t, reach_deleter> new_guard{
(reach_t*)pony_deserialise(&ctx, reach_pony_type(), &array, s_alloc_fn,
s_alloc_fn)};
s_alloc_fn, s_throw_fn)};

reach_t* new_r = new_guard.get();

Expand Down
5 changes: 3 additions & 2 deletions test/libponyrt/ds/hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -429,17 +429,18 @@ TEST_F(HashMapTest, Serialisation)
(void)ctx;
return ponyint_pool_alloc_size(size);
};
auto throw_fn = [](){throw std::exception{}; };

pony_ctx_t ctx;
memset(&ctx, 0, sizeof(pony_ctx_t));
ponyint_array_t array;
memset(&array, 0, sizeof(ponyint_array_t));

pony_serialise(&ctx, &_map, testmap_pony_type(), &array, alloc_fn);
pony_serialise(&ctx, &_map, testmap_pony_type(), &array, alloc_fn, throw_fn);
auto array_guard = manage_array(array);
std::unique_ptr<testmap_t, testmap_deleter> out_guard{
(testmap_t*)pony_deserialise(&ctx, testmap_pony_type(), &array, alloc_fn,
alloc_fn)};
alloc_fn, throw_fn)};

testmap_t* out = out_guard.get();

Expand Down

0 comments on commit e52ef29

Please sign in to comment.