1 /* spawn - demo of the gras_agent_spawn function */
3 /* The server process wants to compute all prime numbers between 0 and maxint.
4 For that, it spawns amount of child processes and communicate with them
5 through 2 queues (one for the things to do, and another for the things done).
6 Beware, using sockets to speak between main thread and spawned agent
7 is unreliable because they share the same incoming listener thread. */
9 /* Copyright (c) 2010. The SimGrid Team.
10 * All rights reserved. */
12 /* This program is free software; you can redistribute it and/or modify it
13 * under the terms of the license (GNU LGPL) which comes with this package. */
16 #include "xbt/strbuff.h"
18 XBT_LOG_NEW_DEFAULT_CATEGORY(Spawn, "Messages specific to this example");
20 /* defines an interval to be searched */
24 } s_work_chunk_t,*work_chunk_t;
25 xbt_queue_t todo; /* The queue in which the server puts the work to do */
26 xbt_queue_t done; /* the queue in which the workers puts the result of their work; */
28 int worker(int argc, char *argv[]);
29 int worker(int argc, char *argv[]) {
35 xbt_queue_shift_timed(todo,&chunk,0);
38 if (e.category != timeout_error) {
44 break; // Do not break from within the CATCH, exceptions don't like it.
46 XBT_INFO("Got [%d;%d] to do",chunk->min,chunk->max);
47 GRAS_BENCH_ALWAYS_BEGIN();
49 for (i=chunk->min;i<chunk->max;i++) {
52 if (i%j == 0) // not prime: j divides i perfectly
55 if (j==i) // no divisor found: that's prime
56 xbt_dynar_push(chunk->primes,&i);
58 GRAS_BENCH_ALWAYS_END();
59 xbt_queue_push(done,&chunk);
61 XBT_INFO("No more work for me; bailing out");
66 /* ********************************************************************** */
68 /* ********************************************************************** */
69 int server(int argc, char *argv[]);
70 int server(int argc, char *argv[])
79 gras_init(&argc, argv);
81 todo = xbt_queue_new(-1,sizeof(work_chunk_t));
82 done = xbt_queue_new(-1,sizeof(work_chunk_t));
85 XBT_INFO("Prepare some work");
86 for (i=0;i<maxint/perchunk;i++) {
87 chunk = xbt_new0(s_work_chunk_t,1);
88 chunk->min = i*perchunk;
89 chunk->max = (i+1)*perchunk;
90 chunk->primes = xbt_dynar_new(sizeof(int),NULL);
91 xbt_queue_push(todo,&chunk);
94 XBT_INFO("Spawn the kids");
95 for (i = 0; i < child_amount; i++) {
96 char *name = bprintf("child%d",i);
97 worker_args = xbt_new0(char *, 2);
98 worker_args[0] = xbt_strdup("child");
99 worker_args[1] = NULL;
100 gras_agent_spawn(name, worker, 1, worker_args, NULL);
104 XBT_INFO("Fetch their answers");
105 for (i=0;i<maxint/perchunk;i++) {
107 xbt_strbuff_t buff = xbt_strbuff_new();
111 xbt_queue_pop(done,&chunk);
112 xbt_dynar_foreach(chunk->primes,cursor,data) {
114 sprintf(number,"%d",data);
118 xbt_strbuff_append(buff,",");
119 xbt_strbuff_append(buff,number);
121 XBT_INFO("Primes in [%d,%d]: %s",chunk->min,chunk->max,buff->data);
122 xbt_strbuff_free(buff);
124 gras_os_sleep(.1);/* Let the childs detect that there is nothing more to do */
125 xbt_queue_free(&todo);
126 xbt_queue_free(&done);