Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
use a user level mallocator on the task content
[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     }
37     CATCH(e) {
38       if (e.category != timeout_error) {
39         RETHROW;
40       }
41       moretodo = 0;
42     }
43     if (!moretodo)
44       break; // Do not break from within the CATCH, exceptions don't like it.
45
46     XBT_INFO("Got [%d;%d] to do",chunk->min,chunk->max);
47     GRAS_BENCH_ALWAYS_BEGIN();
48     int i;
49     for (i=chunk->min;i<chunk->max;i++) {
50       int j;
51       for (j=2;j<i;j++) {
52         if (i%j == 0) // not prime: j divides i perfectly
53           break;
54       }
55       if (j==i) // no divisor found: that's prime
56         xbt_dynar_push(chunk->primes,&i);
57     }
58     GRAS_BENCH_ALWAYS_END();
59     xbt_queue_push(done,&chunk);
60   }
61   XBT_INFO("No more work for me; bailing out");
62
63   return 0;
64 }
65
66 /* ********************************************************************** */
67 /*  The server */
68 /* ********************************************************************** */
69 int server(int argc, char *argv[]);
70 int server(int argc, char *argv[])
71 {
72   int maxint = 1000;
73   int perchunk = 50;
74   int child_amount = 5;
75   char **worker_args;
76   int i;
77   work_chunk_t chunk;
78
79   gras_init(&argc, argv);
80
81   todo = xbt_queue_new(-1,sizeof(work_chunk_t));
82   done = xbt_queue_new(-1,sizeof(work_chunk_t));
83
84
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);
92   }
93
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);
101     free(name);
102   }
103
104   XBT_INFO("Fetch their answers");
105   for (i=0;i<maxint/perchunk;i++) {
106     work_chunk_t chunk;
107     xbt_strbuff_t buff = xbt_strbuff_new();
108     int first=1;
109     unsigned int cursor;
110     int data;
111     xbt_queue_pop(done,&chunk);
112     xbt_dynar_foreach(chunk->primes,cursor,data) {
113       char number[100];
114       sprintf(number,"%d",data);
115       if (first)
116         first = 0;
117       else
118         xbt_strbuff_append(buff,",");
119       xbt_strbuff_append(buff,number);
120     }
121     XBT_INFO("Primes in [%d,%d]: %s",chunk->min,chunk->max,buff->data);
122     xbt_strbuff_free(buff);
123   }
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);
127
128   gras_exit();
129
130   return 0;
131 }