charj: get rid of extra malloc in jacobi implementation
[charm.git] / src / langs / pvmc / pvmc_groups.c
1 #include <stddef.h>
2 #include <converse.h>
3 #include "pvmc.h"
4
5 CpvDeclare(int,pvmc_at_barrier_num);
6 CpvDeclare(int,pvmc_barrier_num);
7 CpvStaticDeclare(int,pvmc_last_at_barrier_num);
8 CpvStaticDeclare(int,pvmc_last_barrier_num);
9
10 CpvExtern(int,pvmc_control_handler);
11
12 void pvmc_init_groups()
13 {
14   CpvInitialize(int,pvmc_barrier_num);
15   CpvAccess(pvmc_barrier_num)=0;
16   CpvInitialize(int,pvmc_at_barrier_num);
17   CpvAccess(pvmc_at_barrier_num)=0;
18   CpvInitialize(int,pvmc_last_barrier_num);
19   CpvAccess(pvmc_last_barrier_num)=0;
20   CpvInitialize(int,pvmc_last_at_barrier_num);
21   CpvAccess(pvmc_last_at_barrier_num)=0;
22 }
23
24 int pvm_joingroup(const char *group)
25 {
26   PRINTF("TID %d joining group %s -- group support is limited\n",pvm_mytid(),group);
27
28   return pvm_mytid();
29 }
30
31 int pvm_lvgroup(const char *group)
32 {
33   PRINTF("TID %d leaving group %s -- group support is limited\n",pvm_mytid(),group);
34
35   return 0;
36 }
37
38 int pvm_bcast(const char *group, int msgtag)
39 {
40   int i;
41   int return_val=0;
42
43   for(i=0; i<NUMPES(); i++)
44     if(i!=MYPE())
45       return_val+=pvm_send(PE2TID(i),msgtag);
46
47   return return_val;
48
49 }
50
51 int pvm_barrier(const char *group, int count)
52 {
53   int i;
54   
55 #ifdef PVM_DEBUG
56   PRINTF("Pe(%d) tid=%d:pvm_barrier(%s,%d) waiting for barrier %d\n",
57         MYPE(),pvm_mytid(),group,count,CpvAccess(pvmc_last_barrier_num)+1);
58 #endif
59
60   /*
61    * First, everyone except Node 0 sends a message to node 0
62    */
63   if (MYPE() != 0)
64     pvmc_send_control_msg(PVMC_CTRL_AT_BARRIER,0);
65
66   /* 
67    * Node 0 will wait for NUMPES-1 messages, then send the response back
68    */
69   if (MYPE() == 0)
70   {
71     while(CpvAccess(pvmc_at_barrier_num) < 
72           CpvAccess(pvmc_last_at_barrier_num) + NUMPES()-1)
73     {
74       /* Empty network buffer */
75       while(CmiDeliverMsgs(1)==0)
76         ;
77     }
78     /*
79      * Now, node 0 has received the proper number of messages, so it must
80      * tell the other nodes to continue
81      */
82     for (i=1; i < NUMPES(); i++)
83       pvmc_send_control_msg(PVMC_CTRL_THROUGH_BARRIER,i);
84     /*
85      * Now node 0 must set itself up for the next call
86      */
87     CpvAccess(pvmc_last_at_barrier_num) += NUMPES() - 1;
88     /*
89      * And finally, node 0 tells itself that it has passed the barrier
90      */
91     CpvAccess(pvmc_barrier_num)++;
92   }
93
94   /*
95    * Now, all processors wait for barrier passage, by looking 
96    * at pvmc_barrier_num counter
97    */
98   while(CpvAccess(pvmc_barrier_num) ==  CpvAccess(pvmc_last_barrier_num))
99   {
100     /* Empty network buffer */
101     while(CmiDeliverMsgs(1)==0)
102       ;
103   }
104   /*
105    *  Barrier reached. Set up for next barrier
106    */
107   CpvAccess(pvmc_last_barrier_num)++;
108   
109 }
110