# HG changeset patch # User Paul Boddie # Date 1593897860 -7200 # Node ID 19a72fed09ce424e5e0f497f581dc4925d84c469 # Parent a2f12c2f7cad6fe8b45ade7d477eb3bf29e3b415 An experiment with "synchronous" completions exposing completion functions to send replies back to the caller. Where outputs are involved, client and server interfaces diverge, and this has not yet been satisfactorily handled. diff -r a2f12c2f7cad -r 19a72fed09ce examples/dataspace.idl --- a/examples/dataspace.idl Sun Apr 26 22:59:15 2020 +0200 +++ b/examples/dataspace.idl Sat Jul 04 23:24:20 2020 +0200 @@ -7,7 +7,9 @@ { /* Map memory within a dataspace. */ - [opcode(0)] void map(in unsigned long offset, in l4_addr_t hot_spot, + [opcode(0), + completion, + sync ] void map(in unsigned long offset, in l4_addr_t hot_spot, in unsigned long flags, out fpage region); /* Clear a dataspace. */ diff -r a2f12c2f7cad -r 19a72fed09ce server.c --- a/server.c Sun Apr 26 22:59:15 2020 +0200 +++ b/server.c Sat Jul 04 23:24:20 2020 +0200 @@ -1,7 +1,7 @@ /* * Server code generation. * - * Copyright (C) 2019 Paul Boddie + * Copyright (C) 2019, 2020 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -88,13 +88,21 @@ { char *opname = get_operation_name(iface, sig); - /* Generate a signature featuring an initiator reference and only "out" and - "inout" parameters. */ + /* Generate a signature featuring an initiator reference (for non-synchronous + completions) and only "out" and "inout" parameters. */ + + int synchronous = have_attribute(sig->attributes, "sync"); - fprintf(fp, server_completion_function_signature_prologue, opname, iface->name); + char *prologue = synchronous ? + server_completion_synchronous_function_signature_prologue : + server_completion_function_signature_prologue; + + fprintf(fp, prologue, opname, iface->name); + + /* Continue from the initial endpoint parameter if not synchronous. */ write_parameters(sig->parameters, fp, SIGNATURE_ROLE, COMPLETION_ROLE, - OUT_PARAMETER, 1); + OUT_PARAMETER, !synchronous); fputs(")", fp); fputs(get_signature_terminator(role), fp); @@ -250,10 +258,16 @@ write_output_initialisation(param, fp, opname, output_words, output_items, COMPLETION_ROLE); - /* Send the response. + /* Send a plain reply for synchronous completions. */ + + if (have_attribute(sig->attributes, "sync")) + fputs(server_completion_synchronous_function_body_epilogue, fp); + + /* Send a response as a new message to the given endpoint. NOTE: The label 0 is employed but an error condition could be communicated. */ - fprintf(fp, server_completion_function_body_epilogue, "0", "_endp"); + else + fprintf(fp, server_completion_function_body_epilogue, "0", "_endp"); /* Free allocated strings. */ diff -r a2f12c2f7cad -r 19a72fed09ce templates.h --- a/templates.h Sun Apr 26 22:59:15 2020 +0200 +++ b/templates.h Sat Jul 04 23:24:20 2020 +0200 @@ -195,6 +195,9 @@ #define server_completion_function_signature_prologue \ "\nlong complete_%s(l4_cap_idx_t _endp" +#define server_completion_synchronous_function_signature_prologue \ +"\nlong complete_%s(" + #define server_completion_function_body_prologue \ " ipc_message_t msg;\n" @@ -202,6 +205,10 @@ "\n ipc_message_send(&msg, %s, %s);\n\n" \ " return l4_error(msg.tag);\n" +#define server_completion_synchronous_function_body_epilogue \ +"\n ipc_message_reply(&msg);\n\n" \ + " return l4_error(msg.tag);\n" + #define server_initiation_function_body_epilogue \ "\n ipc_message_prepare(msg);\n\n" \ " return L4_EOK;\n"