Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Completely reimplement the spawn example: speaking with spawned agents cannot be...
[simgrid.git] / examples / gras / spawn / spawn.c
1 /* spawn - demo of the gras_agent_spawn function                            */
2
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. */
8
9 /* Copyright (c) 2010. The SimGrid Team.
10  * All rights reserved.                                                     */
11
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. */
14
15 #include "xbt/log.h"
16 #include "xbt/strbuff.h"
17 #include "gras.h"
18 XBT_LOG_NEW_DEFAULT_CATEGORY(Spawn, "Messages specific to this example");
19
20 /* defines an interval to be searched */
21 typedef struct {
22   int min, max;
23   xbt_dynar_t primes;
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; */
27
28 int worker(int argc, char *argv[]);
29 int worker(int argc, char *argv[]) {
30   work_chunk_t chunk;
31   int moretodo = 1;
32   while (moretodo) {
33     xbt_ex_t e;
34     TRY {
35       xbt_queue_shift_timed(todo,&chunk,0);
36     } CATCH(e) {
37       if (e.category != timeout_error) {
38         RETHROW;
39       }
40       moretodo = 0;
41     }
42     if (!moretodo)
43       break; // Do not break from within the CATCH, exceptions don't like it.
44
45     INFO2("Got [%d;%d] to do",chunk->min,chunk->max);
46     GRAS_BENCH_ALWAYS_BEGIN();
47     int i;
48     for (i=chunk->min;i<chunk->max;i++) {
49       int j;
50       for (j=2;j<i;j++) {
51         if (i%j == 0) // not prime: j divides i perfectly
52           break;
53       }
54       if (j==i) // no divisor found: that's prime
55         xbt_dynar_push(chunk->primes,&i);
56     }
57     GRAS_BENCH_ALWAYS_END();
58     xbt_queue_push(done,&chunk);
59   }
60   INFO0("No more work for me; bailing out");
61
62   return 0;
63 }
64
65 /* ********************************************************************** */
66 /*  The server */
67 /* ********************************************************************** */
68 int server(int argc, char *argv[]);
69 int server(int argc, char *argv[])
70 {
71   int maxint = 1000;
72   int perchunk = 50;
73   int child_amount = 5;
74   char **worker_args;
75   int i;
76   work_chunk_t chunk;
77
78   gras_init(&argc, argv);
79
80   todo = xbt_queue_new(-1,sizeof(work_chunk_t));
81   done = xbt_queue_new(-1,sizeof(work_chunk_t));
82
83
84   INFO0("Prepare some work");
85   for (i=0;i<maxint/perchunk;i++) {
86     chunk = xbt_new0(s_work_chunk_t,1);
87     chunk->min = i*perchunk;
88     chunk->max = (i+1)*perchunk;
89     chunk->primes = xbt_dynar_new(sizeof(int),NULL);
90     xbt_queue_push(todo,&chunk);
91   }
92
93   INFO0("Spawn the kids");
94   for (i = 0; i < child_amount; i++) {
95     worker_args = xbt_new0(char *, 1);
96     worker_args[0] = xbt_strdup("child");
97     worker_args[1] = NULL;
98     gras_agent_spawn(bprintf("child%d",i), NULL, worker, 1, worker_args, NULL);
99   }
100
101   INFO0("Fetch their answers");
102   for (i=0;i<maxint/perchunk;i++) {
103     work_chunk_t chunk;
104     xbt_strbuff_t buff = xbt_strbuff_new();
105     int first=1;
106     unsigned int cursor;
107     int data;
108     xbt_queue_pop(done,&chunk);
109     xbt_dynar_foreach(chunk->primes,cursor,data) {
110       char number[100];
111       sprintf(number,"%d",data);
112       if (first)
113         first = 0;
114       else
115         xbt_strbuff_append(buff,",");
116       xbt_strbuff_append(buff,number);
117     }
118     INFO3("Primes in [%d,%d]: %s",chunk->min,chunk->max,buff->data);
119     xbt_strbuff_free(buff);
120   }
121   xbt_queue_free(&todo);
122   xbt_queue_free(&done);
123
124   gras_exit();
125
126   return 0;
127 }