Charj: Construct Range when a range is given.
[charm.git] / src / langs / pvmc / pvmc_buf.c
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <converse.h>
4 #include "pvmc.h"
5
6 #define MAX_BUFFERS 1000
7
8 typedef struct pvmc_item_s {
9   int type;
10   int size;
11   int free_data;
12   char *data;
13   struct pvmc_item_s *nxt;
14 } pvmc_item;
15
16 typedef struct pvmc_buffer_s {
17   int bufid;
18   int bytes;
19   int tag;
20   int tid;
21   int num_items;
22   int refcount;
23   pvmc_item *first_item;
24   pvmc_item *cur_item;
25   pvmc_item *last_item;
26   struct pvmc_buffer_s *nxt_free;
27   char *data_buf;
28 } pvmc_buffer;
29
30 CpvStaticDeclare(pvmc_buffer*,pvmc_bufarray);
31 CpvStaticDeclare(pvmc_buffer*,pvmc_freebufs);
32 CpvStaticDeclare(int,pvmc_sbufid);
33 CpvStaticDeclare(int,pvmc_rbufid);
34
35 void pvmc_init_bufs(void)
36 {
37   int i;
38
39 #ifdef PVM_DEBUG
40   PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_bufs() initializing buffer array\n",
41         MYPE(),pvm_mytid(),__FILE__,__LINE__);
42 #endif
43
44   CpvInitialize(pvmc_buffer*,pvmc_bufarray);
45   CpvAccess(pvmc_bufarray)=MALLOC(sizeof(pvmc_buffer)*MAX_BUFFERS);
46   if (CpvAccess(pvmc_bufarray)==NULL) {
47     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_bufs() can't alloc buffer array\n",
48            MYPE(),pvm_mytid(),__FILE__,__LINE__);
49     exit(1);
50   }
51     
52   CpvInitialize(pvmc_buffer*,pvmc_freebufs);
53   CpvAccess(pvmc_freebufs)=&(CpvAccess(pvmc_bufarray)[1]);  /* throw away first bufid */
54   
55   for(i=0;i<MAX_BUFFERS;i++) {
56     CpvAccess(pvmc_bufarray)[i].bufid=i;
57     CpvAccess(pvmc_bufarray)[i].bytes=0;
58     CpvAccess(pvmc_bufarray)[i].tag=0;
59     CpvAccess(pvmc_bufarray)[i].tid=-1;
60     CpvAccess(pvmc_bufarray)[i].num_items=-1;
61     CpvAccess(pvmc_bufarray)[i].refcount=0;
62     CpvAccess(pvmc_bufarray)[i].first_item=(pvmc_item *)NULL;
63     CpvAccess(pvmc_bufarray)[i].cur_item=(pvmc_item *)NULL;
64     CpvAccess(pvmc_bufarray)[i].last_item=(pvmc_item *)NULL;
65     if (i==MAX_BUFFERS-1)
66       CpvAccess(pvmc_bufarray)[i].nxt_free=(pvmc_buffer *)NULL;
67     else
68       CpvAccess(pvmc_bufarray)[i].nxt_free=&(CpvAccess(pvmc_bufarray)[i+1]);
69
70     CpvAccess(pvmc_bufarray)[i].data_buf=(char *)NULL;
71   }
72
73   CpvInitialize(int,pvmc_sbufid);
74   CpvAccess(pvmc_sbufid) = 0;
75
76   CpvInitialize(int,pvmc_rbufid);
77   CpvAccess(pvmc_rbufid) = 0;
78 }
79
80 int pvm_mkbuf(int encoding)
81 {
82   pvmc_buffer *new_buf;
83
84 #ifdef PVM_DEBUG
85   PRINTF("Pe(%d) tid=%d:pvm_mkbuf(%d)\n",
86         MYPE(),pvm_mytid(),encoding);
87
88   if (encoding != PvmDataRaw)
89     PRINTF("Pe(%d) tid=%d:%s:%d Warning: only encoding=PvmDataRaw supported\n",
90            MYPE(),pvm_mytid(),__FILE__,__LINE__);
91 #endif
92
93   new_buf = CpvAccess(pvmc_freebufs);
94   if (new_buf == NULL) {
95     PRINTF("Pe(%d) tid=%d:%s:%d pvm_mkbuf() no more buffers\n",
96            MYPE(),pvm_mytid(),__FILE__,__LINE__);
97     return -1;
98   }
99
100   CpvAccess(pvmc_freebufs)=CpvAccess(pvmc_freebufs)->nxt_free;
101   new_buf->bytes=0;
102   new_buf->tag=0;
103   new_buf->tid=pvm_mytid();
104   new_buf->num_items = 0;
105   if ((new_buf->first_item=
106        (pvmc_item *)MALLOC(sizeof(pvmc_item))) == NULL) {
107     PRINTF("Pe(%d) tid=%d:%s:%d pvm_mkbuf() MALLOC failed\n",
108            MYPE(),pvm_mytid(),__FILE__,__LINE__);
109     return -1;
110   }
111   new_buf->first_item->type=0;
112   new_buf->first_item->size=0;
113   new_buf->first_item->free_data=FALSE;
114   new_buf->first_item->data=(char *)NULL;
115   new_buf->first_item->nxt=(pvmc_item *)NULL;
116
117   new_buf->cur_item=new_buf->first_item;
118   new_buf->last_item=new_buf->first_item;
119   new_buf->refcount=1;
120   return new_buf->bufid;
121 }
122   
123 static void pvmc_emptybuf(pvmc_buffer *cur_buf)
124 {
125   pvmc_item *nxt_item, *prv_item; 
126
127   if (cur_buf->data_buf) {
128     FREE(cur_buf->data_buf);
129     cur_buf->data_buf=(char *)NULL;
130   }
131
132   nxt_item=cur_buf->first_item;
133   while (nxt_item) {
134     prv_item=nxt_item;
135     nxt_item=nxt_item->nxt;
136     if (prv_item->free_data)
137       FREE(prv_item->data);
138     FREE(prv_item);
139   }
140   cur_buf->bytes=0;
141   cur_buf->tag=0;
142   cur_buf->tid=-1;
143   cur_buf->num_items=0;
144   cur_buf->first_item=(pvmc_item *)NULL;
145   cur_buf->cur_item=(pvmc_item *)NULL;
146   cur_buf->last_item=(pvmc_item *)NULL;
147 }
148
149 int pvm_freebuf(int bufid)
150 {
151   pvmc_buffer *cur_buf;
152   int result=0;
153
154 #ifdef PVM_DEBUG
155   PRINTF("Pe(%d) tid=%d:pvm_freebuf(%d)\n",MYPE(),pvm_mytid(),bufid);
156 #endif
157
158   if ((bufid<=0) || (bufid>=MAX_BUFFERS)) {
159     PRINTF("Pe(%d) tid=%d:%s:%d pvm_freebuf() attempted to free out of range bufid\n",
160            MYPE(),pvm_mytid(),__FILE__,__LINE__);
161     return -1;
162   }
163     
164   cur_buf = &(CpvAccess(pvmc_bufarray)[bufid]);
165
166   if (cur_buf->refcount < 1) {
167     PRINTF("Pe(%d) tid=%d:%s:%d pvm_freebuf(%d) refcount=%d, i'm confused\n",
168            MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid,cur_buf->refcount);
169     result=-2;
170   }
171   cur_buf->refcount--;
172
173   if (cur_buf->refcount==0) {
174     pvmc_emptybuf(cur_buf);
175     cur_buf->nxt_free=CpvAccess(pvmc_freebufs);
176     CpvAccess(pvmc_freebufs)=cur_buf;
177   }
178
179 #ifdef PVM_DEBUG
180   {
181     int x;
182     int Counter=0;
183     int FreeCounter=0;
184     struct pvmc_buffer_s *FreeList;
185     /* find the number that we think are free */
186     for(x=0; x<MAX_BUFFERS; x++)
187     {
188       if (CpvAccess(pvmc_bufarray)[x].refcount == 0) Counter++;
189     }
190     /* find the number that are linked as free */
191     FreeList = CpvAccess(pvmc_freebufs);
192     while(FreeList != NULL)
193     {
194       FreeCounter++;
195       FreeList = FreeList->nxt_free;
196     }
197     /* show the results */
198     PRINTF("Pe(%d) tid=%d:%s:%d unused=(%d) sizeof(freelist)=%d\n",
199            MYPE(),pvm_mytid(),__FILE__,__LINE__,Counter,FreeCounter);
200   }
201 #endif
202
203   return result;
204 }  
205
206 static int pvmc_getbuf(int bufid)
207 {
208   pvmc_buffer *cur_buf;
209
210   if ((bufid<=0) || (bufid>=MAX_BUFFERS)) {
211     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getbuf(%d) attempted to get out of range bufid\n",
212            MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid);
213     return -1;
214   }
215     
216   cur_buf = &(CpvAccess(pvmc_bufarray)[bufid]);
217
218   if (cur_buf->refcount<1) {
219     PRINTF("Pe(%d) tid=%d:%s:%d pvm_getbuf() trying with refcount=%d, i'm confused\n",
220            MYPE(),pvm_mytid(),__FILE__,__LINE__,cur_buf->refcount);
221     return -1;
222   }
223
224   cur_buf->refcount++;
225   return bufid;
226 }
227
228 int pvm_getsbuf(void)
229 {
230 #ifdef PVM_DEBUG
231   PRINTF("Pe(%d) tid=%d:pvm_getsbuf()\n",MYPE(),pvm_mytid());
232 #endif
233   return CpvAccess(pvmc_sbufid);
234 }
235
236 int pvm_setsbuf(int bufid)
237 {
238   int prv_sbufid;
239
240 #ifdef PVM_DEBUG
241   PRINTF("Pe(%d) tid=%d:pvm_setsbuf(%d)\n",MYPE(),pvm_mytid(),bufid);
242 #endif
243
244   prv_sbufid=CpvAccess(pvmc_sbufid);
245
246   /*
247   if (prv_sbufid>0) {
248     pvmc_getbuf(prv_sbufid);
249     pvm_freebuf(prv_sbufid);
250   }
251   */
252
253   CpvAccess(pvmc_sbufid)=bufid;
254
255   return prv_sbufid;
256 }
257
258 int pvm_getrbuf(void)
259 {
260 #ifdef PVM_DEBUG
261   PRINTF("Pe(%d) tid=%d:pvm_getrbuf()\n",MYPE(),pvm_mytid());
262 #endif
263   return CpvAccess(pvmc_rbufid);
264 }
265
266 int pvm_setrbuf(int bufid)
267 {
268   int prv_rbufid;
269
270 #ifdef PVM_DEBUG
271   PRINTF("Pe(%d) tid=%d:pvm_setrbuf(%d)\n",MYPE(),pvm_mytid(),bufid);
272 #endif
273   prv_rbufid=CpvAccess(pvmc_rbufid);
274
275   /*
276   if (prv_rbufid>0) {
277     pvmc_getbuf(prv_rbufid);
278     pvm_freebuf(prv_rbufid);
279   }
280   */
281     
282
283   CpvAccess(pvmc_rbufid)=bufid;
284
285   return prv_rbufid;
286 }
287
288 int pvm_initsend(int encoding)
289 {
290   int newbufid;
291
292 #ifdef PVM_DEBUG
293   PRINTF("Pe(%d) tid=%d:pvm_initsend(%d)\n",MYPE(),pvm_mytid(),encoding);
294 #endif
295   if (CpvAccess(pvmc_sbufid) > 0)
296     pvm_freebuf(CpvAccess(pvmc_sbufid));
297
298   newbufid=pvm_mkbuf(encoding);
299
300   if (newbufid<=0) {
301     PRINTF("Pe(%d) tid=%d:%s:%d pvm_initsend() couldn't alloc new buffer\n",
302            MYPE(),pvm_mytid(),__FILE__,__LINE__);
303   }
304   CpvAccess(pvmc_sbufid)=newbufid;
305   return CpvAccess(pvmc_sbufid);
306 }
307
308 int pvm_bufinfo(int bufid, int *bytes, int *msgtag, int *tid)
309 {
310 #ifdef PVM_DEBUG
311   PRINTF("Pe(%d) tid=%d:pvm_bufinfo(%d,0x%x,0x%x,0x%x)\n",
312          pvm_mytid(),bufid,bytes,msgtag,tid);
313 #endif
314
315   if ((bufid<=0) || (bufid >= MAX_BUFFERS) ||
316       (CpvAccess(pvmc_bufarray)[bufid].refcount <= 0)) {
317     PRINTF("Pe(%d) tid=%d:%s:%d pvm_bufinfo(%d) info requested about unused buffer\n",
318            MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid);
319     return -1;
320   }
321   if (bytes)
322     *bytes=CpvAccess(pvmc_bufarray)[bufid].bytes;
323   if (msgtag)
324     *msgtag=CpvAccess(pvmc_bufarray)[bufid].tag;
325   if (tid)
326     *tid=CpvAccess(pvmc_bufarray)[bufid].tid;
327   return 0;
328 }
329
330 int pvmc_sendmsgsz(void)
331 {
332   int msgsz;
333   pvmc_buffer *cur_buf;
334   pvmc_item *cur_item;
335
336   if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
337       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
338     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_sendmsgsz() size requested for unused send buffer\n",
339            MYPE(),pvm_mytid(),__FILE__,__LINE__);
340     return -1;
341   }
342
343   cur_buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
344
345   msgsz=sizeof(cur_buf->bytes)+sizeof(cur_buf->tag)+
346     sizeof(cur_buf->tid)+sizeof(cur_buf->num_items);
347
348   cur_item=cur_buf->first_item;
349   while (cur_item != cur_buf->last_item) {
350     msgsz += cur_item->size+sizeof(cur_item->type)+sizeof(cur_item->size);
351     cur_item = cur_item->nxt;
352   }
353
354   return msgsz;
355 }
356
357 int pvmc_settidtag(int pvm_tid, int tag)
358 {
359   pvmc_buffer *cur_buf;
360
361   if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
362       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
363     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_setidtag() unused send buffer\n",
364            MYPE(),pvm_mytid(),__FILE__,__LINE__);
365     return -1;
366   }
367   cur_buf=&(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
368   cur_buf->tag = tag;
369   cur_buf->tid = pvm_tid;
370 }
371
372
373 int pvmc_packmsg(void *msgbuf)
374 {
375   pvmc_buffer *cur_buf;
376   pvmc_item *cur_item;
377   int bytes_packed=0;
378
379   if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
380       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
381     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_packmsg() unused send buffer\n",
382            MYPE(),pvm_mytid(),__FILE__,__LINE__);
383     return -1;
384   }
385   cur_buf=&(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
386   *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->bytes;
387   bytes_packed+=sizeof(int);
388   *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->tag;
389   bytes_packed+=sizeof(int);
390   *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->tid;
391   bytes_packed+=sizeof(int);
392   *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->num_items;
393   bytes_packed+=sizeof(int);
394
395 #ifdef PVM_DEBUG
396   PRINTF("Pe(%d) pvmc_packmsg: %d items packed for tag %d\n",
397          MYPE(),cur_buf->num_items,cur_buf->tag);
398 #endif
399   cur_item=cur_buf->first_item;
400   while(cur_item!=cur_buf->last_item) {
401     *((int *)((char *)msgbuf+bytes_packed)) = cur_item->type;
402     bytes_packed+=sizeof(int);
403     *((int *)((char *)msgbuf+bytes_packed)) = cur_item->size;
404     bytes_packed+=sizeof(int);
405     cur_item=cur_item->nxt;
406   }
407     
408   cur_item=cur_buf->first_item;
409   while(cur_item!=cur_buf->last_item) {
410     if (cur_item->size > 0) {
411       memcpy((void *)((char *)msgbuf+bytes_packed),cur_item->data,
412              cur_item->size);
413       bytes_packed+=cur_item->size;
414     }
415     cur_item=cur_item->nxt;
416   }
417   return bytes_packed;
418 }
419
420 int pvmc_unpackmsg(void *msgbuf, void *start_of_msg)
421 {
422   pvmc_buffer *cur_buf;
423   pvmc_item *cur_item, *nxt_item;
424   int bytes_unpacked=0;
425   int i;
426
427   if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
428       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
429     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() uninitialized recv buffer\n",
430            MYPE(),__FILE__,__LINE__);
431     return -1;
432   }
433   cur_buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
434   pvmc_emptybuf(cur_buf);
435
436   cur_buf->bytes = *((int *)((char *)start_of_msg+bytes_unpacked));
437   bytes_unpacked += sizeof(int);
438   cur_buf->tag = *((int *)((char *)start_of_msg+bytes_unpacked));
439   bytes_unpacked += sizeof(int);
440   cur_buf->tid = *((int *)((char *)start_of_msg+bytes_unpacked));
441   bytes_unpacked += sizeof(int);
442   cur_buf->num_items = *((int *)((char *)start_of_msg+bytes_unpacked));
443   bytes_unpacked += sizeof(int);
444
445 #ifdef PVM_DEBUG
446   PRINTF("Pe(%d) pvmc_unpackmsg: %d items unpacked for tag %d\n",
447          MYPE(),cur_buf->num_items,cur_buf->tag);
448 #endif
449   if (msgbuf)
450     cur_buf->data_buf = msgbuf;
451   else cur_buf->data_buf = (void *)NULL;
452
453   cur_item=(pvmc_item *)MALLOC(sizeof(pvmc_item));
454   cur_buf->first_item=cur_item;
455   cur_buf->cur_item=cur_item;
456
457   if (cur_item==(pvmc_item *)NULL) {
458     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() can't allocate memory\n",
459            MYPE(),pvm_mytid(),__FILE__,__LINE__);
460     return -1;
461   }
462
463 #if PVM_DEBUG
464   PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() unpacking %d messages.\n",
465         MYPE(),pvm_mytid(),__FILE__,__LINE__,cur_buf->num_items);
466 #endif
467
468   for(i=0;i<cur_buf->num_items;i++) {
469     cur_item->type = *((int *)((char *)start_of_msg+bytes_unpacked));
470     bytes_unpacked+=sizeof(int);
471     cur_item->size = *((int *)((char *)start_of_msg+bytes_unpacked));
472     bytes_unpacked+=sizeof(int);
473     
474     nxt_item=(pvmc_item *)MALLOC(sizeof(pvmc_item));
475
476     if (!nxt_item) {
477       PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() can't allocate memory\n",
478              MYPE(),pvm_mytid(),__FILE__,__LINE__);
479       return -1;
480     }
481     cur_item->nxt = nxt_item;
482     cur_item = nxt_item;
483   }
484   
485   cur_item->type = 0;
486   cur_item->size = 0;
487   cur_item->free_data = FALSE;
488   cur_item->data = (char *) NULL;
489   cur_item->nxt = (pvmc_item *) NULL;
490
491   cur_buf->last_item = cur_item;
492     
493   cur_item = cur_buf->first_item;
494   while(cur_item!=cur_buf->last_item) {
495     if (cur_item->size > 0) {
496       cur_item->free_data=FALSE;
497       cur_item->data = (void *)((char *)start_of_msg+bytes_unpacked);
498       bytes_unpacked+=cur_item->size;
499     }
500     else cur_item->data=NULL;
501     cur_item = cur_item->nxt;
502   }
503
504   return bytes_unpacked;
505 }
506
507 int pvmc_gettag(void *msgbuf)
508 {
509   return *((int *)msgbuf+1);
510 }
511
512 void *pvmc_mkitem(int nbytes, int type)
513 {
514   pvmc_buffer *buf;
515   void *databuf;
516
517   if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
518       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
519     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() unused send buffer\n",
520            MYPE(),pvm_mytid(),__FILE__,__LINE__);
521     return NULL;
522   }
523   buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
524
525   buf->last_item->type=type;
526   buf->last_item->size=nbytes;
527   databuf=MALLOC(nbytes);
528   if (!databuf) {
529     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() can't allocate data space\n",
530            MYPE(),pvm_mytid(),__FILE__,__LINE__);
531     return databuf;
532   }
533   buf->last_item->free_data=TRUE;
534   buf->last_item->data=databuf;
535   buf->last_item->nxt=(pvmc_item *)MALLOC(sizeof(pvmc_item));
536   if (buf->last_item->nxt==NULL) {
537     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() can't allocate new item\n",
538            MYPE(),pvm_mytid(),__FILE__,__LINE__);
539     return NULL;
540   }
541
542   buf->last_item=buf->last_item->nxt;
543   buf->last_item->type=0;
544   buf->last_item->size=0;
545   buf->last_item->free_data=FALSE;
546   buf->last_item->data=(char *)NULL;
547   buf->last_item->nxt=(pvmc_item *)NULL;
548   buf->num_items++;
549
550   return databuf;
551 }
552
553 void *pvmc_getitem(int n_bytes, int type)
554 {
555   pvmc_buffer *buf;
556   pvmc_item *item;
557   void *data;
558
559   if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
560       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
561     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() uninitialized recv buffer\n",
562            MYPE(),pvm_mytid(),__FILE__,__LINE__);
563     return NULL;
564   }
565   buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
566
567   item = buf->cur_item;
568
569   if (item==buf->last_item) {
570     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() no more items\n",
571           MYPE(),pvm_mytid(), __FILE__,__LINE__);
572     data=NULL;
573   } else if (item->data==(void *)NULL) {
574     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() uninitialized data\n",
575           MYPE(),pvm_mytid(), __FILE__,__LINE__);
576     data=NULL;
577   } else if (item->size < n_bytes) {
578     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() data size mismatch\n",
579           MYPE(),pvm_mytid(), __FILE__,__LINE__);
580     data=NULL;
581   } else if (item->type != type) {
582     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() type mismatch\n",
583           MYPE(),pvm_mytid(), __FILE__,__LINE__);
584     data=NULL;
585   } else {
586     data=item->data;
587   }
588
589   buf->cur_item = buf->cur_item->nxt;
590   return data;
591 }
592
593 void *pvmc_getstritem(int *n_bytes)
594 {
595   pvmc_buffer *buf;
596   pvmc_item *item;
597   void *data;
598
599   if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
600       (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
601     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() uninitialized recv buffer\n",
602            MYPE(),pvm_mytid(),__FILE__,__LINE__);
603     return NULL;
604   }
605   buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
606
607   item = buf->cur_item;
608   *n_bytes = item->size;
609
610   if (item==buf->last_item) {
611     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() no more items\n",
612            MYPE(),pvm_mytid(),__FILE__,__LINE__);
613     data=NULL;
614   } else if (item->data==(void *)NULL) {
615     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() uninitialized data\n",
616            MYPE(),pvm_mytid(),__FILE__,__LINE__);
617     data=NULL;
618   } else if (item->type != PVM_STR) {
619     PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() type mismatch\n",
620            MYPE(),pvm_mytid(),__FILE__,__LINE__);
621     data=NULL;
622   } else {
623     data=item->data;
624   }
625
626   buf->cur_item = buf->cur_item->nxt;
627   return data;
628 }
629