Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
adapt to lastest prototype change, and kill a race condition at the end of the execut...
[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     char *name = bprintf("child%d",i);
96     worker_args = xbt_new0(char *, 2);
97     worker_args[0] = xbt_strdup("child");
98     worker_args[1] = NULL;
99     gras_agent_spawn(name, worker, 1, worker_args, NULL);
100     free(name);
101   }
102
103   INFO0("Fetch their answers");
104   for (i=0;i<maxint/perchunk;i++) {
105     work_chunk_t chunk;
106     xbt_strbuff_t buff = xbt_strbuff_new();
107     int first=1;
108     unsigned int cursor;
109     int data;
110     xbt_queue_pop(done,&chunk);
111     xbt_dynar_foreach(chunk->primes,cursor,data) {
112       char number[100];
113       sprintf(number,"%d",data);
114       if (first)
115         first = 0;
116       else
117         xbt_strbuff_append(buff,",");
118       xbt_strbuff_append(buff,number);
119     }
120     INFO3("Primes in [%d,%d]: %s",chunk->min,chunk->max,buff->data);
121     xbt_strbuff_free(buff);
122   }
123   gras_os_sleep(.1);/* Let the childs detect that there is nothing more to do */
124   xbt_queue_free(&todo);
125   xbt_queue_free(&done);
126
127   gras_exit();
128
129   return 0;
130 }