~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-4-3/tcgmsg/ipcv5.0/queues.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $$ */
 
2
#include "tcgmsgP.h"
 
3
 
 
4
static const long false = 0;
 
5
static const long true  = 1;
 
6
 
 
7
extern void USleep(long);
 
8
extern void Busy(int);
 
9
 
 
10
extern long async_send(SendQEntry *);
 
11
 
 
12
static long NextMsgID(long node)
 
13
/*
 
14
  Given a nodeid return a unqiue integer constructed by
 
15
  combining it with the value of a counter
 
16
*/
 
17
{
 
18
  static long id = 0;
 
19
  static long mask = (1<<20)-1;
 
20
 
 
21
  id = (id + 1) & mask;
 
22
  if (id == 0) id = 1;
 
23
  
 
24
  return (node << 20) + id;
 
25
}
 
26
 
 
27
static long NodeFromMsgID(long msgid)
 
28
/*
 
29
  Given an id from NextMsgID extract the node
 
30
*/
 
31
{
 
32
  long node = msgid >> 20;
 
33
 
 
34
  if (node < 0 || node > NNODES_())
 
35
    Error("NodeFromMsgID: invalid msgid", msgid);
 
36
 
 
37
  return node;
 
38
}
 
39
 
 
40
static void flush_send_q_node(long node)
 
41
/*
 
42
  Flush as many messages as possible without blocking from
 
43
  the send q to the specified node.
 
44
*/
 
45
{
 
46
  while (TCGMSG_proc_info[node].sendq) {
 
47
    
 
48
    if (!async_send(TCGMSG_proc_info[node].sendq)) {
 
49
      /* Send is incomplete ... stop processing this q*/
 
50
      break;
 
51
    }
 
52
    else {
 
53
      SendQEntry *tmp = TCGMSG_proc_info[node].sendq;
 
54
      
 
55
      TCGMSG_proc_info[node].sendq = (SendQEntry *) TCGMSG_proc_info[node].sendq->next;
 
56
      if (tmp->free_buf_on_completion)
 
57
        (void) free(tmp->buf);
 
58
      tmp->active = false;      /* Matches NewSendQEntry() */
 
59
    }
 
60
  }
 
61
}
 
62
 
 
63
void flush_send_q()
 
64
/*
 
65
  Flush as many messages as possible without blocking
 
66
  from all of the send q's.
 
67
*/
 
68
{
 
69
  long node;
 
70
  long nproc = NNODES_();
 
71
 
 
72
  for (node=0; node<nproc; node++)
 
73
    if (TCGMSG_proc_info[node].sendq)
 
74
      flush_send_q_node(node);
 
75
}    
 
76
 
 
77
long msg_status(msgid)
 
78
     long msgid;
 
79
/*
 
80
  Return 0 if the message operation is incomplete.
 
81
  Return 1 if the message operation is complete.
 
82
*/
 
83
{
 
84
  long node = NodeFromMsgID(msgid);
 
85
  SendQEntry *entry;
 
86
  long status = 1;
 
87
 
 
88
  flush_send_q();
 
89
 
 
90
  /* Attempt to find the msgid in the message q.  If it is not
 
91
     there then the send is complete */
 
92
 
 
93
  for (entry=TCGMSG_proc_info[node].sendq; entry; entry=(SendQEntry *) entry->next) {
 
94
    if (entry->msgid == msgid) {
 
95
      status = 0;
 
96
      break;
 
97
    }
 
98
  }
 
99
 
 
100
  return status;
 
101
}
 
102
 
 
103
void msg_wait(long msgid)
 
104
/*
 
105
  Wait for the operation referred to by msgid to complete.
 
106
*/
 
107
{
 
108
  long nspin = 0;
 
109
#ifdef NOSPIN
 
110
  long spinlim = 100;
 
111
# ifdef CRAY
 
112
  long waittim = 10000;
 
113
# endif
 
114
#else
 
115
  long spinlim = 1000000;
 
116
# ifdef CRAY
 
117
  long waittim = 100000;
 
118
# endif
 
119
#endif  
 
120
 
 
121
  while (!msg_status(msgid)) {
 
122
    nspin++;
 
123
    if (nspin < spinlim)
 
124
      Busy(100);
 
125
    else 
 
126
#ifdef CRAY
 
127
      USleep(waittim);
 
128
#else
 
129
      usleep(1);
 
130
#endif
 
131
  }
 
132
}
 
133
 
 
134
static SendQEntry *NewSendQEntry(void)
 
135
{
 
136
  SendQEntry *new = TCGMSG_sendq_ring;
 
137
 
 
138
  if (new->active)
 
139
    Error("NewSendQEntry: too many outstanding sends\n", 0L);
 
140
 
 
141
  TCGMSG_sendq_ring = (SendQEntry *) TCGMSG_sendq_ring->next_in_ring;
 
142
 
 
143
  new->active = true;
 
144
 
 
145
  return new;
 
146
}
 
147
 
 
148
long msg_async_snd(type, buf, lenbuf, node)
 
149
     long type;
 
150
     char *buf;
 
151
     long lenbuf;
 
152
     long node;
 
153
{
 
154
  long msgid;
 
155
  SendQEntry *entry;
 
156
 
 
157
  if (node<0 || node>=TCGMSG_nnodes)
 
158
    Error("msg_async_send: node is out of range", node);
 
159
 
 
160
  if (node == TCGMSG_nodeid)
 
161
    Error("msg_async_send: cannot send to self", node);
 
162
 
 
163
  msgid = NextMsgID(node);
 
164
  entry = NewSendQEntry();
 
165
 
 
166
  /* Insert a new entry into the q */
 
167
 
 
168
  entry->tag   = TCGMSG_proc_info[node].n_snd++; /* Increment tag */
 
169
  entry->msgid = msgid;
 
170
  entry->type  = type;
 
171
#ifdef CRAY_T3D
 
172
  /* allignment is critical on T3D (shmem library) */
 
173
  if (((unsigned long) buf) & 7) {
 
174
    printf("%2ld: mallocing unalinged buffer len=%ld\n",
 
175
           TCGMSG_nodeid, lenbuf);
 
176
    fflush(stdout);
 
177
    if (!(entry->buf = malloc((size_t) lenbuf)))
 
178
       Error("msg_sync_send: malloc failed", lenbuf);
 
179
    (void) memcpy(entry->buf, buf, lenbuf);
 
180
    entry->free_buf_on_completion = 1;
 
181
  }
 
182
  else 
 
183
#endif
 
184
  {
 
185
    entry->buf   = buf;
 
186
    entry->free_buf_on_completion = 0;
 
187
  }
 
188
  entry->lenbuf= lenbuf;
 
189
  entry->node  = node;
 
190
  entry->next  = (SendQEntry *) 0;
 
191
  entry->written = 0;
 
192
  entry->buffer_number = 0;
 
193
 
 
194
  /* Attach to the send q */
 
195
 
 
196
  if (!TCGMSG_proc_info[node].sendq)
 
197
    TCGMSG_proc_info[node].sendq = entry;
 
198
  else {
 
199
    SendQEntry *cur = TCGMSG_proc_info[node].sendq;
 
200
    
 
201
    while (cur->next)
 
202
      cur = cur->next;
 
203
    cur->next = entry;
 
204
  }
 
205
 
 
206
  /* Attempt to flush the send q */
 
207
 
 
208
  flush_send_q();
 
209
 
 
210
  return msgid;
 
211
}
 
212
 
 
213
void msg_snd(long type, char *buf, long lenbuf, long node)
 
214
/*
 
215
  synchronous send of message to a process
 
216
 
 
217
  long *type     = user defined integer message type (input)
 
218
  char *buf      = data buffer (input)
 
219
  long *lenbuf   = length of buffer in bytes (input)
 
220
  long *node     = node to send to (input)
 
221
 
 
222
  for zero length messages only the header is sent
 
223
*/
 
224
{
 
225
  msg_wait(msg_async_snd(type, buf, lenbuf, node));
 
226
}