From a15aa24d7cee97c30beb7d5f21cbda8fdbc43911 Mon Sep 17 00:00:00 2001 From: Elias Castegren Date: Tue, 3 Feb 2015 09:31:48 +0100 Subject: [PATCH] Futures now store pony_arg_t rather than void* Also fixed the expected output of the test `realfutures` from `2.1` to `2.100000`. --- src/back/CodeGen/ClassDecl.hs | 11 ++++++----- src/back/CodeGen/Expr.hs | 11 ++--------- src/back/CodeGen/Type.hs | 11 +++++++++-- src/runtime/future/future.c | 26 +++++++++++++------------- src/runtime/future/future.h | 26 +++++++++++++------------- src/runtime/stream/stream.c | 10 +++++----- src/tests/encore/basic/realfutures.out | 2 +- 7 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/back/CodeGen/ClassDecl.hs b/src/back/CodeGen/ClassDecl.hs index 5decb37c4..0d8d02ab6 100644 --- a/src/back/CodeGen/ClassDecl.hs +++ b/src/back/CodeGen/ClassDecl.hs @@ -207,16 +207,17 @@ translateActiveClass cdecl@(A.Class{A.cname, A.fields, A.methods}) = then [one_way_send_dispatch_clause m] else [] - mthd_dispatch_clause mdecl@(A.Method{A.mname, A.mparams}) = + mthd_dispatch_clause mdecl@(A.Method{A.mname, A.mparams, A.mtype}) = (method_msg_name cname mname, Seq [Assign (Decl (Ptr $ Typ "future_t", Var "fut")) ((ArrAcc 0 ((Var "argv"))) `Dot` (Nam "p")), Statement $ Call (Nam "future_fulfil") [AsExpr $ Var "fut", - Cast (Ptr void) - (Call (method_impl_name cname mname) - ((AsExpr . Var $ "p") : - (paramdecls_to_argv 1 $ mparams)))]]) + Cast (pony_arg_t) + (UnionInst (pony_arg_t_tag (translate mtype)) $ + Call (method_impl_name cname mname) + ((AsExpr . Var $ "p") : + (paramdecls_to_argv 1 $ mparams)))]]) mthd_dispatch_clause mdecl@(A.StreamMethod{A.mname, A.mparams}) = (method_msg_name cname mname, Seq [Assign (Decl (Ptr $ Typ "future_t", Var "fut")) diff --git a/src/back/CodeGen/Expr.hs b/src/back/CodeGen/Expr.hs index 5e5a0ddc1..dfe49d814 100644 --- a/src/back/CodeGen/Expr.hs +++ b/src/back/CodeGen/Expr.hs @@ -366,7 +366,7 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where | Ty.isFutureType $ A.getType val = do (nval, tval) <- translate val let result_type = translate (Ty.getResultType $ A.getType val) - the_get = Cast result_type $ Call (Nam "future_get_actor") [nval] + the_get = Cast result_type $ Call (Nam "future_get_actor") [nval] `Dot` pony_arg_t_tag result_type tmp <- Ctx.gen_sym return (Var tmp, Seq [tval, Assign (Decl (result_type, Var tmp)) the_get]) | Ty.isStreamType $ A.getType val = @@ -474,11 +474,4 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where | Ty.isRealType ty = Nam "d" | otherwise = Nam "p" - translate other = error $ "Expr.hs: can't translate: '" ++ show other ++ "'" - -pony_arg_t_tag :: CCode Ty -> CCode Name -pony_arg_t_tag (Ptr _) = Nam "p" -pony_arg_t_tag (Typ "int64_t") = Nam "i" -pony_arg_t_tag (Typ "double") = Nam "d" -pony_arg_t_tag other = - error $ "Expr.hs: no pony_arg_t_tag for " ++ show other + translate other = error $ "Expr.hs: can't translate: '" ++ show other ++ "'" \ No newline at end of file diff --git a/src/back/CodeGen/Type.hs b/src/back/CodeGen/Type.hs index fc40806e2..d58f2c05a 100644 --- a/src/back/CodeGen/Type.hs +++ b/src/back/CodeGen/Type.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances, GADTs #-} {-| Make Type (see "AST") an instance of @Translatable@ (see "CodeGen.Typeclasses"). -} @@ -35,4 +35,11 @@ instance Translatable Ty.Type (CCode Ty) where | Ty.isTypeVar ty = Ptr void | Ty.isFutureType ty = future | Ty.isStreamType ty = stream - | otherwise = error $ "I don't know how to translate "++ show ty ++" to pony.c" \ No newline at end of file + | otherwise = error $ "I don't know how to translate "++ show ty ++" to pony.c" + +pony_arg_t_tag :: CCode Ty -> CCode Name +pony_arg_t_tag (Ptr _) = Nam "p" +pony_arg_t_tag (Typ "int64_t") = Nam "i" +pony_arg_t_tag (Typ "double") = Nam "d" +pony_arg_t_tag other = + error $ "Type.hs: no pony_arg_t_tag for " ++ show other diff --git a/src/runtime/future/future.c b/src/runtime/future/future.c index ea896e6cd..791133f29 100644 --- a/src/runtime/future/future.c +++ b/src/runtime/future/future.c @@ -71,7 +71,7 @@ struct actor_entry struct future { - void *value; + pony_arg_t value; bool fulfilled; // Stupid limitation for now actor_entry_t responsibilities[16]; @@ -98,11 +98,11 @@ future_t *future_mk(void) return fut; } -void *run_closure(closure_t *c, void *value, future_t *fut) +pony_arg_t run_closure(closure_t *c, pony_arg_t value, future_t *fut) { - value_t result = closure_call(c, (value_t[1]) { { .p = value } }); - future_fulfil(fut, result.p); - return result.p; + value_t result = closure_call(c, (value_t[1]) { value }); + future_fulfil(fut, result); + return result; } bool future_fulfilled(future_t *fut) @@ -115,16 +115,16 @@ bool future_fulfilled(future_t *fut) return r; } -void *future_read_value(future_t *fut) +pony_arg_t future_read_value(future_t *fut) { perr("future_read_value"); BLOCK; - void *v = fut->value; + pony_arg_t v = fut->value; UNBLOCK; return v; } -void future_fulfil(future_t *fut, void *value) +void future_fulfil(future_t *fut, pony_arg_t value) { perr("future_fulfil"); @@ -145,7 +145,7 @@ void future_fulfil(future_t *fut, void *value) } } if (!blocked) { - pony_arg_t argv[3] = { { .p = current->closure }, { .p = value }, { .p = current->future } }; + pony_arg_t argv[3] = { { .p = current->closure }, value, { .p = current->future } }; pony_sendv(current->actor, FUT_MSG_RUN_CLOSURE, 3, argv); } current = current->next; @@ -167,15 +167,15 @@ void future_fulfil(future_t *fut, void *value) // Intended design: see https://github.com/parapluu/mylittlepony/wiki/Futures case ATTACHED_CLOSURE: { - pony_arg_t argv[3] = { { .p = e.closure.closure }, { .p = value }, { .p = e.closure.future } }; + pony_arg_t argv[3] = { { .p = e.closure.closure }, value, { .p = e.closure.future } }; pony_sendv(e.closure.actor, FUT_MSG_RUN_CLOSURE, 3, argv); break; } // Design 1: current thread executes closures (racy) case DETACHED_CLOSURE: { - value_t result = closure_call(e.closure.closure, (value_t[1]) { { .p = value } }); - future_fulfil(e.closure.future, result.p); + value_t result = closure_call(e.closure.closure, (value_t[1]) { value }); + future_fulfil(e.closure.future, result); break; } default: @@ -190,7 +190,7 @@ void future_fulfil(future_t *fut, void *value) // =============================================================== // Means for actors to get, block and chain // =============================================================== -void *future_get_actor(future_t *fut) +pony_arg_t future_get_actor(future_t *fut) { // early return for simple case if (fut->parent == NULL) { diff --git a/src/runtime/future/future.h b/src/runtime/future/future.h index f0d3633c6..a88ea8b14 100644 --- a/src/runtime/future/future.h +++ b/src/runtime/future/future.h @@ -9,26 +9,26 @@ typedef struct future future_t; // =============================================================== // Create, inspect and fulfil // =============================================================== -future_t *future_mk(void); -bool future_fulfilled (future_t *fut); -void *future_read_value (future_t *fut); -void future_fulfil (future_t *fut, void *value); +future_t *future_mk(void); +bool future_fulfilled (future_t *fut); +pony_arg_t future_read_value (future_t *fut); +void future_fulfil (future_t *fut, pony_arg_t value); // =============================================================== // Means for actors to get, block and chain // =============================================================== -void *future_get_actor(future_t *fut); -future_t *future_chain_actor(future_t *fut, future_t* r, closure_t *c); -void future_block_actor(future_t *fut); // TODO: does this belong in the public interface? -void future_unblock_actor(future_t *fut); +pony_arg_t future_get_actor(future_t *fut); +future_t *future_chain_actor(future_t *fut, future_t* r, closure_t *c); +void future_block_actor(future_t *fut); // TODO: does this belong in the public interface? +void future_unblock_actor(future_t *fut); // =============================================================== // Possibly these functions do not belong in the future library // =============================================================== -void future_suspend(void); -void future_suspend_resume(void *); -void future_await(future_t *); -void future_await_resume(void *); -void *run_closure(closure_t *c, void *value, future_t *fut); +void future_suspend(void); +void future_suspend_resume(void *); +void future_await(future_t *); +void future_await_resume(void *); +pony_arg_t run_closure(closure_t *c, pony_arg_t value, future_t *fut); #endif diff --git a/src/runtime/stream/stream.c b/src/runtime/stream/stream.c index 3f562e15c..b7ee46100 100644 --- a/src/runtime/stream/stream.c +++ b/src/runtime/stream/stream.c @@ -34,27 +34,27 @@ stream_t *stream_put(stream_t *s, pony_arg_t value){ struct scons *scons = scons_mk(); scons->element = value; scons->next = fut; - future_fulfil((future_t *)s, scons); + future_fulfil((future_t *)s, (pony_arg_t){ .p = scons }); return fut; } bool stream_eos(stream_t *s){ - struct scons *scons = future_get_actor((future_t *)s); + struct scons *scons = future_get_actor((future_t *)s).p; return scons->eos; } pony_arg_t stream_get(stream_t *s){ - struct scons *scons = future_get_actor((future_t *)s); + struct scons *scons = future_get_actor((future_t *)s).p; return scons->element; } stream_t *stream_get_next(stream_t *s){ - struct scons *scons = future_get_actor((future_t *)s); + struct scons *scons = future_get_actor((future_t *)s).p; return scons->next; } void stream_close(stream_t *s){ struct scons *scons = scons_mk(); scons->eos = true; - future_fulfil((future_t *)s, scons); + future_fulfil((future_t *)s, (pony_arg_t){ .p = scons }); } \ No newline at end of file diff --git a/src/tests/encore/basic/realfutures.out b/src/tests/encore/basic/realfutures.out index 879b416e6..1cc2d8c4e 100644 --- a/src/tests/encore/basic/realfutures.out +++ b/src/tests/encore/basic/realfutures.out @@ -1 +1 @@ -2.1 +2.100000