From f7669511dbd0ea516d79d4e56f638e5cabfbac27 Mon Sep 17 00:00:00 2001 From: mquinson Date: Wed, 24 Nov 2010 16:18:35 +0000 Subject: [PATCH] Completely reimplement the spawn example: speaking with spawned agents cannot be reliable since they share their listener thread git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@8638 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- .gitignore | 3 +- examples/gras/spawn/CMakeLists.txt | 43 +++------- examples/gras/spawn/spawn.c | 127 +++++++++++++++++++++++++++++ examples/gras/spawn/spawn.xml | 4 +- examples/gras/spawn/spawn_child.c | 72 ---------------- examples/gras/spawn/spawn_common.c | 17 ---- examples/gras/spawn/spawn_father.c | 106 ------------------------ examples/gras/spawn/test_rl | 3 +- examples/gras/spawn/test_sg_32 | 29 +------ examples/gras/spawn/test_sg_64 | 31 +------ 10 files changed, 146 insertions(+), 289 deletions(-) create mode 100644 examples/gras/spawn/spawn.c delete mode 100644 examples/gras/spawn/spawn_child.c delete mode 100644 examples/gras/spawn/spawn_common.c delete mode 100644 examples/gras/spawn/spawn_father.c diff --git a/.gitignore b/.gitignore index 4117f167c8..e7bcf26493 100644 --- a/.gitignore +++ b/.gitignore @@ -173,8 +173,7 @@ examples/gras/properties/properties_slave examples/gras/rpc/rpc_client examples/gras/rpc/rpc_forwarder examples/gras/rpc/rpc_server -examples/gras/spawn/spawn_child -examples/gras/spawn/spawn_father +examples/gras/spawn/spawn_server examples/gras/synchro/synchro_philosopher examples/gras/timer/timer_client examples/gras/replay/replay_simulator diff --git a/examples/gras/spawn/CMakeLists.txt b/examples/gras/spawn/CMakeLists.txt index de6047e166..8434053ca0 100644 --- a/examples/gras/spawn/CMakeLists.txt +++ b/examples/gras/spawn/CMakeLists.txt @@ -1,43 +1,26 @@ cmake_minimum_required(VERSION 2.6) set_source_files_properties(${PROJECT_DIRECTORY}/examples/gras/spawn/_spawn_simulator.c - ${PROJECT_DIRECTORY}/examples/gras/spawn/_spawn_child.c - ${PROJECT_DIRECTORY}/examples/gras/spawn/_spawn_father.c - PROPERTIES GENERATED true) + ${PROJECT_DIRECTORY}/examples/gras/spawn/_spawn_server.c + PROPERTIES GENERATED true) set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_SOURCE_DIR}") add_executable(spawn_simulator ${CMAKE_CURRENT_BINARY_DIR}/_spawn_simulator.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_father.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_child.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_common.c) -add_executable(spawn_child ${CMAKE_CURRENT_BINARY_DIR}/_spawn_child.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_child.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_common.c) -add_executable(spawn_father ${CMAKE_CURRENT_BINARY_DIR}/_spawn_father.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_father.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_child.c - ${CMAKE_CURRENT_SOURCE_DIR}/spawn_common.c) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_spawn_child.c - ${CMAKE_CURRENT_BINARY_DIR}/_spawn_father.c - ${CMAKE_CURRENT_BINARY_DIR}/_spawn_simulator.c - DEPENDS gras_stub_generator ${CMAKE_CURRENT_SOURCE_DIR}/spawn.xml - COMMAND ${CMAKE_BINARY_DIR}/bin/gras_stub_generator --extra-process=child spawn ${CMAKE_CURRENT_SOURCE_DIR}/spawn.xml - ) - + ${CMAKE_CURRENT_SOURCE_DIR}/spawn.c) +add_executable(spawn_server ${CMAKE_CURRENT_BINARY_DIR}/_spawn_server.c + ${CMAKE_CURRENT_SOURCE_DIR}/spawn.c) + +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_spawn_server.c + DEPENDS gras_stub_generator ${CMAKE_CURRENT_SOURCE_DIR}/spawn.xml + COMMAND ${CMAKE_BINARY_DIR}/bin/gras_stub_generator spawn ${CMAKE_CURRENT_SOURCE_DIR}/spawn.xml + ) + ### Add definitions for compile if(NOT WIN32) target_link_libraries(spawn_simulator simgrid pthread m ) -target_link_libraries(spawn_child gras pthread m ) -target_link_libraries(spawn_father gras pthread m ) +target_link_libraries(spawn_server gras pthread m ) else(NOT WIN32) target_link_libraries(spawn_simulator simgrid) -target_link_libraries(spawn_child gras) -target_link_libraries(spawn_father gras) +target_link_libraries(spawn_server gras) endif(NOT WIN32) - - - - diff --git a/examples/gras/spawn/spawn.c b/examples/gras/spawn/spawn.c new file mode 100644 index 0000000000..4b3489cf96 --- /dev/null +++ b/examples/gras/spawn/spawn.c @@ -0,0 +1,127 @@ +/* spawn - demo of the gras_agent_spawn function */ + +/* The server process wants to compute all prime numbers between 0 and maxint. + For that, it spawns amount of child processes and communicate with them + through 2 queues (one for the things to do, and another for the things done). + Beware, using sockets to speak between main thread and spawned agent + is unreliable because they share the same incoming listener thread. */ + +/* Copyright (c) 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "xbt/log.h" +#include "xbt/strbuff.h" +#include "gras.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(Spawn, "Messages specific to this example"); + +/* defines an interval to be searched */ +typedef struct { + int min, max; + xbt_dynar_t primes; +} s_work_chunk_t,*work_chunk_t; +xbt_queue_t todo; /* The queue in which the server puts the work to do */ +xbt_queue_t done; /* the queue in which the workers puts the result of their work; */ + +int worker(int argc, char *argv[]); +int worker(int argc, char *argv[]) { + work_chunk_t chunk; + int moretodo = 1; + while (moretodo) { + xbt_ex_t e; + TRY { + xbt_queue_shift_timed(todo,&chunk,0); + } CATCH(e) { + if (e.category != timeout_error) { + RETHROW; + } + moretodo = 0; + } + if (!moretodo) + break; // Do not break from within the CATCH, exceptions don't like it. + + INFO2("Got [%d;%d] to do",chunk->min,chunk->max); + GRAS_BENCH_ALWAYS_BEGIN(); + int i; + for (i=chunk->min;imax;i++) { + int j; + for (j=2;jprimes,&i); + } + GRAS_BENCH_ALWAYS_END(); + xbt_queue_push(done,&chunk); + } + INFO0("No more work for me; bailing out"); + + return 0; +} + +/* ********************************************************************** */ +/* The server */ +/* ********************************************************************** */ +int server(int argc, char *argv[]); +int server(int argc, char *argv[]) +{ + int maxint = 1000; + int perchunk = 50; + int child_amount = 5; + char **worker_args; + int i; + work_chunk_t chunk; + + gras_init(&argc, argv); + + todo = xbt_queue_new(-1,sizeof(work_chunk_t)); + done = xbt_queue_new(-1,sizeof(work_chunk_t)); + + + INFO0("Prepare some work"); + for (i=0;imin = i*perchunk; + chunk->max = (i+1)*perchunk; + chunk->primes = xbt_dynar_new(sizeof(int),NULL); + xbt_queue_push(todo,&chunk); + } + + INFO0("Spawn the kids"); + for (i = 0; i < child_amount; i++) { + worker_args = xbt_new0(char *, 1); + worker_args[0] = xbt_strdup("child"); + worker_args[1] = NULL; + gras_agent_spawn(bprintf("child%d",i), NULL, worker, 1, worker_args, NULL); + } + + INFO0("Fetch their answers"); + for (i=0;iprimes,cursor,data) { + char number[100]; + sprintf(number,"%d",data); + if (first) + first = 0; + else + xbt_strbuff_append(buff,","); + xbt_strbuff_append(buff,number); + } + INFO3("Primes in [%d,%d]: %s",chunk->min,chunk->max,buff->data); + xbt_strbuff_free(buff); + } + xbt_queue_free(&todo); + xbt_queue_free(&done); + + gras_exit(); + + return 0; +} diff --git a/examples/gras/spawn/spawn.xml b/examples/gras/spawn/spawn.xml index 20ddb8cbec..d035b41f5d 100644 --- a/examples/gras/spawn/spawn.xml +++ b/examples/gras/spawn/spawn.xml @@ -1,8 +1,8 @@ - - + + diff --git a/examples/gras/spawn/spawn_child.c b/examples/gras/spawn/spawn_child.c deleted file mode 100644 index acc35238e8..0000000000 --- a/examples/gras/spawn/spawn_child.c +++ /dev/null @@ -1,72 +0,0 @@ -/* spawn - demo of the gras_agent_spawn function */ - -/* Copyright (c) 2007, 2009, 2010. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "spawn.h" -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(Spawn); - -int child(int argc, char *argv[]) -{ - xbt_ex_t e; - gras_socket_t dady = NULL; /* peer */ - - gras_socket_t from; - int ping, pong; - - const char *host = gras_os_myname(); - int port = 4000; - - /* 1. Init the GRAS's infrastructure */ - gras_init(&argc, argv); - - /* 2. Get the server's address. The command line override defaults when specified */ - if (argc == 2) { - port = atoi(argv[1]); - } - - gras_socket_server_range(4000, 5000, 0, 0); - - /* 3. Connect back to my father */ - TRY { - dady = gras_socket_client(host, port); - } - CATCH(e) { - RETHROW0("Unable to connect to my dady: %s"); - } - INFO4("I (%s:%d) have found my dady on %s:%d.", - gras_os_myname(), gras_os_myport(), host, port); - - - /* 4. Register the messages. */ - spawn_register_messages(); - - /* 5. Ping my dady */ - ping = 1234; - TRY { - gras_msg_send(dady, "ping", &ping); - } - CATCH(e) { - gras_socket_close(dady); - RETHROW0("Failed to ping my dady: %s"); - } - - /* 6. Wait for the answer from the server, and deal with issues */ - TRY { - gras_msg_wait(6000, "pong", &from, &pong); - } - CATCH(e) { - gras_socket_close(dady); - RETHROW0("Dad don't want to speak with me! : %s"); - } - INFO2("Pinged dad with %d, he answered with %d; leaving now.", ping, - pong); - - /* 7. Free the allocated resources, and shut GRAS down */ - gras_socket_close(dady); - gras_exit(); - return 0; -} /* end_of_child */ diff --git a/examples/gras/spawn/spawn_common.c b/examples/gras/spawn/spawn_common.c deleted file mode 100644 index c6c787d4bd..0000000000 --- a/examples/gras/spawn/spawn_common.c +++ /dev/null @@ -1,17 +0,0 @@ -/* spawn - demo of the gras_agent_spawn function */ - -/* Copyright (c) 2007, 2009, 2010. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "spawn.h" -XBT_LOG_NEW_DEFAULT_CATEGORY(Spawn, "Messages specific to this example"); - -/* register messages which may be sent (common to client and server) */ -void spawn_register_messages(void) -{ - gras_msgtype_declare("ping", gras_datadesc_by_name("int")); - gras_msgtype_declare("pong", gras_datadesc_by_name("int")); -} diff --git a/examples/gras/spawn/spawn_father.c b/examples/gras/spawn/spawn_father.c deleted file mode 100644 index 12cc6ae76a..0000000000 --- a/examples/gras/spawn/spawn_father.c +++ /dev/null @@ -1,106 +0,0 @@ -/* spawn - demo of the gras_agent_spawn function */ - -/* Copyright (c) 2007, 2009, 2010. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "spawn.h" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(Spawn); - -/* Global private data */ -typedef struct { - gras_socket_t sock; - int msg_got; -} father_data_t; - - -static int father_cb_ping_handler(gras_msg_cb_ctx_t ctx, void *payload) -{ - - xbt_ex_t e; - /* 1. Get the payload into the msg variable, and retrieve my caller */ - int msg = *(int *) payload; - gras_socket_t expeditor = gras_msg_cb_ctx_from(ctx); - - /* 2. Retrieve the father's state (globals) */ - father_data_t *globals = (father_data_t *) gras_userdata_get(); - globals->msg_got++; - - /* 3. Log which client connected */ - INFO3("Kid %s:%d pinged me with %d", - gras_socket_peer_name(expeditor), gras_socket_peer_port(expeditor), - msg); - - /* 4. Change the value of the msg variable */ - msg = 4321; - /* 5. Send it back as payload of a pong message to the expeditor */ - TRY { - gras_msg_send(expeditor, "pong", &msg); - - /* 6. Deal with errors: add some details to the exception */ - } CATCH(e) { - gras_socket_close(globals->sock); - RETHROW0("Unable to answer to my poor child: %s"); - } - INFO2("Answered to %s:%d's request", - gras_socket_peer_name(expeditor), - gras_socket_peer_port(expeditor)); - - /* 7. Tell GRAS that we consummed this message */ - return 0; -} /* end_of_father_cb_ping_handler */ - -int father(int argc, char *argv[]) -{ - father_data_t *globals; - - int port = 4000; - int child_amount = 5; - char **child_args; - int i; - - /* 1. Init the GRAS infrastructure and declare my globals */ - gras_init(&argc, argv); - globals = gras_userdata_new(father_data_t); - - /* 2. Get args from the command line, if specified */ - if (argc == 2) { - port = atoi(argv[1]); - child_amount = atoi(argv[2]); - } - - /* 3. Initialize my globals (mainly create my master socket) */ - globals->sock = gras_socket_server(port); - globals->msg_got = 0; - - /* 4. Register the known messages. */ - spawn_register_messages(); - - /* 5. Register my callback */ - gras_cb_register("ping", &father_cb_ping_handler); - - /* 6. Spawn the kids */ - INFO0("Spawn the kids"); - for (i = 0; i < child_amount; i++) { - child_args = xbt_new0(char *, 3); - child_args[0] = xbt_strdup("child"); - child_args[1] = bprintf("%d", port); - child_args[2] = NULL; - gras_agent_spawn("child", NULL, child, 2, child_args, NULL); - } - - /* 7. Wait to be contacted be the kids */ - while (globals->msg_got < child_amount) - gras_msg_handle(60.0); - INFO0("All kids gone. Leave now."); - - /* 8. Free the allocated resources, and shut GRAS down */ - gras_socket_close(globals->sock); - free(globals); - gras_exit(); - - return 0; -} /* end_of_father */ diff --git a/examples/gras/spawn/test_rl b/examples/gras/spawn/test_rl index 7fe56f8b95..d5a1a90e75 100755 --- a/examples/gras/spawn/test_rl +++ b/examples/gras/spawn/test_rl @@ -1,4 +1,3 @@ -! expect signal SIGABRT ! output ignore -$ $SG_TEST_ENV ./spawn_father$EXEEXT 4602 5 --log=root.fmt=%m%n +$ $SG_TEST_ENV ./spawn_server$EXEEXT --log=root.fmt=%m%n diff --git a/examples/gras/spawn/test_sg_32 b/examples/gras/spawn/test_sg_32 index 4467b1e2e1..adea07951c 100755 --- a/examples/gras/spawn/test_sg_32 +++ b/examples/gras/spawn/test_sg_32 @@ -1,31 +1,4 @@ p Runs the 'spawn' test within the simulator (simulation times valid for 32bits architectures) +! output ignore $ $SG_TEST_EXENV ./spawn_simulator${EXEEXT:=} ${srcdir:=.}/../../msg/small_platform.xml ${srcdir:=.}/spawn.xml -> [Tremblay:father:(1) 0.000156] [Spawn/INFO] Spawn the kids -> [Tremblay:child:(2) 0.000468] [Spawn/INFO] I (Tremblay:4001) have found my dady on Tremblay:4000. -> [Tremblay:child:(6) 0.000468] [Spawn/INFO] I (Tremblay:4002) have found my dady on Tremblay:4000. -> [Tremblay:child:(3) 0.000468] [Spawn/INFO] I (Tremblay:4003) have found my dady on Tremblay:4000. -> [Tremblay:child:(4) 0.000468] [Spawn/INFO] I (Tremblay:4004) have found my dady on Tremblay:4000. -> [Tremblay:child:(5) 0.000468] [Spawn/INFO] I (Tremblay:4005) have found my dady on Tremblay:4000. -> [Tremblay:father:(1) 0.000624] [Spawn/INFO] Kid Tremblay:4001 pinged me with 1234 -> [Tremblay:father:(1) 0.000780] [Spawn/INFO] Answered to Tremblay:4001's request -> [Tremblay:father:(1) 0.000780] [Spawn/INFO] Kid Tremblay:4002 pinged me with 1234 -> [Tremblay:child:(2) 0.000780] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(2) 0.000780] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.000936] [Spawn/INFO] Answered to Tremblay:4002's request -> [Tremblay:father:(1) 0.000936] [Spawn/INFO] Kid Tremblay:4003 pinged me with 1234 -> [Tremblay:child:(6) 0.000936] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(6) 0.000936] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001092] [Spawn/INFO] Answered to Tremblay:4003's request -> [Tremblay:father:(1) 0.001092] [Spawn/INFO] Kid Tremblay:4004 pinged me with 1234 -> [Tremblay:child:(3) 0.001092] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(3) 0.001092] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001248] [Spawn/INFO] Answered to Tremblay:4004's request -> [Tremblay:father:(1) 0.001248] [Spawn/INFO] Kid Tremblay:4005 pinged me with 1234 -> [Tremblay:child:(4) 0.001248] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(4) 0.001248] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001404] [Spawn/INFO] Answered to Tremblay:4005's request -> [Tremblay:father:(1) 0.001404] [Spawn/INFO] All kids gone. Leave now. -> [Tremblay:father:(1) 0.001404] [gras/INFO] Exiting GRAS -> [Tremblay:child:(5) 0.001404] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(5) 0.001404] [gras/INFO] Exiting GRAS diff --git a/examples/gras/spawn/test_sg_64 b/examples/gras/spawn/test_sg_64 index fd526f3d29..ae99f98648 100755 --- a/examples/gras/spawn/test_sg_64 +++ b/examples/gras/spawn/test_sg_64 @@ -1,33 +1,4 @@ p Runs the 'spawn' test within the simulator (simulation times valid for 64bits architectures) +! output ignore $ $SG_TEST_EXENV ./spawn_simulator${EXEEXT:=} ${srcdir:=.}/../../msg/small_platform.xml ${srcdir:=.}/spawn.xml -> [Tremblay:father:(1) 0.000156] [Spawn/INFO] Spawn the kids -> [Tremblay:child:(2) 0.000468] [Spawn/INFO] I (Tremblay:4001) have found my dady on Tremblay:4000. -> [Tremblay:child:(6) 0.000468] [Spawn/INFO] I (Tremblay:4002) have found my dady on Tremblay:4000. -> [Tremblay:child:(3) 0.000468] [Spawn/INFO] I (Tremblay:4003) have found my dady on Tremblay:4000. -> [Tremblay:child:(4) 0.000468] [Spawn/INFO] I (Tremblay:4004) have found my dady on Tremblay:4000. -> [Tremblay:child:(5) 0.000468] [Spawn/INFO] I (Tremblay:4005) have found my dady on Tremblay:4000. -> [Tremblay:father:(1) 0.000624] [Spawn/INFO] Kid Tremblay:4001 pinged me with 1234 -> [Tremblay:father:(1) 0.000780] [Spawn/INFO] Answered to Tremblay:4001's request -> [Tremblay:father:(1) 0.000780] [Spawn/INFO] Kid Tremblay:4002 pinged me with 1234 -> [Tremblay:child:(2) 0.000780] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(2) 0.000780] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.000936] [Spawn/INFO] Answered to Tremblay:4002's request -> [Tremblay:father:(1) 0.000936] [Spawn/INFO] Kid Tremblay:4003 pinged me with 1234 -> [Tremblay:child:(6) 0.000936] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(6) 0.000936] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001092] [Spawn/INFO] Answered to Tremblay:4003's request -> [Tremblay:father:(1) 0.001092] [Spawn/INFO] Kid Tremblay:4004 pinged me with 1234 -> [Tremblay:child:(3) 0.001092] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(3) 0.001092] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001248] [Spawn/INFO] Answered to Tremblay:4004's request -> [Tremblay:father:(1) 0.001248] [Spawn/INFO] Kid Tremblay:4005 pinged me with 1234 -> [Tremblay:child:(4) 0.001248] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(4) 0.001248] [gras/INFO] Exiting GRAS -> [Tremblay:father:(1) 0.001404] [Spawn/INFO] Answered to Tremblay:4005's request -> [Tremblay:father:(1) 0.001404] [Spawn/INFO] All kids gone. Leave now. -> [Tremblay:father:(1) 0.001404] [gras/INFO] Exiting GRAS -> [Tremblay:child:(5) 0.001404] [Spawn/INFO] Pinged dad with 1234, he answered with 4321; leaving now. -> [Tremblay:child:(5) 0.001404] [gras/INFO] Exiting GRAS - - -- 2.20.1