Annotation of OpenXM_contrib2/asir2000/io/ox.c, Revision 1.22
1.5 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.6 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.5 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
1.22 ! noro 47: * $OpenXM: OpenXM_contrib2/asir2000/io/ox.c,v 1.21 2003/12/09 03:07:45 noro Exp $
1.5 noro 48: */
1.1 noro 49: #include "ca.h"
50: #include "parse.h"
1.3 noro 51: #include "signal.h"
1.1 noro 52: #include "wsio.h"
53: #include "ox.h"
54:
55: #define ISIZ sizeof(int)
56:
57: extern Obj VOIDobj;
58:
1.22 ! noro 59: extern int nserver_102, myrank_102;
1.1 noro 60: extern int ox_need_conv;
1.14 noro 61: int ox_usr1_sent, ox_int_received, critical_when_signal;
1.1 noro 62: unsigned int ox_serial;
63: int ox_flushing;
64: int ox_batch;
65: int ox_check=1;
1.2 noro 66: int ox_exchange_mathcap=1;
1.13 noro 67: JMP_BUF ox_env;
1.1 noro 68:
69: MATHCAP my_mathcap;
70:
71: struct oxcap {
72: unsigned int ox;
73: int ncap;
74: int *cap;
75: };
76:
77: struct mathcap {
78: LIST mc;
79: unsigned int version;
80: char *servername;
81: int nsmcap;
82: unsigned int *smcap;
83: int noxcap;
84: struct oxcap *oxcap;
85: };
86:
87: struct oxcap *my_oxcap;
88:
89: static struct mathcap my_mc;
90: static struct mathcap *remote_mc;
91: static int remote_mc_len;
92:
1.12 noro 93: void mclist_to_mc(LIST mclist,struct mathcap *mc);
94:
1.9 noro 95: #if defined(VISUAL)
96: /* XXX : mainly used in engine2000/io.c, but declared here */
97: HANDLE hStreamNotify,hStreamNotify_Ack;
98:
99: void cleanup_events()
100: {
101: /* ox_watch_stream may be waiting for hStreamNotify_Ack to be set */
102:
103: ResetEvent(hStreamNotify);
104: SetEvent(hStreamNotify_Ack);
105: }
106: #endif
107:
1.12 noro 108: void ox_resetenv(char *s)
1.1 noro 109: {
1.9 noro 110: #if defined(VISUAL)
111: cleanup_events();
112: #endif
1.1 noro 113: fprintf(stderr,"%s\n",s);
1.13 noro 114: LONGJMP(ox_env,1);
1.1 noro 115: }
116:
117: static int available_cmo[] = {
118: CMO_NULL, CMO_INT32, CMO_DATUM, CMO_STRING, CMO_MATHCAP,
119: CMO_ERROR, CMO_ERROR2, CMO_LIST, CMO_MONOMIAL32,
120: CMO_ZZ, CMO_QQ, CMO_ZERO,
121: CMO_DMS_GENERIC, CMO_DMS_OF_N_VARIABLES,
122: CMO_RING_BY_NAME, CMO_DISTRIBUTED_POLYNOMIAL,
123: CMO_RECURSIVE_POLYNOMIAL, CMO_UNIVARIATE_POLYNOMIAL,
124: CMO_INDETERMINATE,
1.11 noro 125: CMO_TREE,
1.1 noro 126: 0
127: };
128:
1.17 noro 129: static int asir_available_sm[] = {
130: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
131: SM_popCMO, SM_popString, SM_pushCMOtag, SM_setName,
132: SM_evalName, SM_executeStringByLocalParser,
133: SM_executeStringByLocalParserInBatchMode,
134: SM_executeFunction, SM_shutdown, SM_pops,
135: SM_mathcap, SM_setMathcap, SM_nop,
136: SM_beginBlock, SM_endBlock,
137: 0
138: };
139:
1.15 noro 140: static int ox_asir_available_sm[] = {
1.1 noro 141: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
1.7 noro 142: SM_popCMO, SM_popString, SM_pushCMOtag, SM_setName,
1.1 noro 143: SM_evalName, SM_executeStringByLocalParser,
144: SM_executeStringByLocalParserInBatchMode,
145: SM_executeFunction, SM_shutdown, SM_pops,
146: SM_mathcap, SM_setMathcap, SM_nop,
147: SM_beginBlock, SM_endBlock,
1.21 noro 148: SM_set_rank_102, SM_tcp_accept_102, SM_tcp_connect_102, SM_reset_102,
1.1 noro 149: 0
150: };
151:
1.15 noro 152: static int ox_plot_available_sm[] = {
153: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
154: SM_popCMO, SM_popString, SM_setName,
155: SM_evalName, SM_executeStringByLocalParser,
156: SM_executeFunction, SM_shutdown, SM_pops,
1.16 noro 157: SM_mathcap, SM_setMathcap, SM_nop,
1.15 noro 158: 0
159: };
160:
1.1 noro 161: /*
162: mathcap =
163: [
164: version list,
165: SMlist,
166: [
167: [OX tag,CMO tag list],
168: [OX tag,CMO tag list],
169: ...
170: ]
171: ]
172: */
173:
174: void create_my_mathcap(char *system)
175: {
176: NODE n,n0;
177: int i,k;
178: STRING str;
1.12 noro 179: LIST sname,smlist,oxlist,cmolist,asirlist,oxasir,r;
1.1 noro 180: USINT tag,t,t1;
181:
182: if ( my_mathcap )
183: return;
184: /* version */
185: MKSTR(str,system);
186: MKUSINT(t,OX_VERSION);
187: n0 = mknode(2,t,str); MKLIST(sname,n0);
188:
1.15 noro 189: /* sm tag */
190: n0 = 0;
1.17 noro 191: if ( !strcmp(system,"asir") ) {
192: for ( i = 0; k = asir_available_sm[i]; i++ ) {
193: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
194: }
195: } else if ( !strcmp(system,"ox_asir") ) {
1.15 noro 196: for ( i = 0; k = ox_asir_available_sm[i]; i++ ) {
197: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
198: }
199: NEXT(n) = 0;
200: } else if ( !strcmp(system,"ox_plot") ) {
201: for ( i = 0; k = ox_plot_available_sm[i]; i++ ) {
202: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
203: }
204: NEXT(n) = 0;
1.1 noro 205: }
1.15 noro 206: MKLIST(smlist,n0);
1.1 noro 207:
208: /* creation of [OX_DATA,CMO list] */
209: /* ox tag */
210: MKUSINT(tag,OX_DATA);
211: /* cmo tag */
212: for ( n0 = 0, i = 0; k = available_cmo[i]; i++ ) {
213: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
214: }
215: NEXT(n) = 0; MKLIST(cmolist,n0);
216: /* [ox tag, cmo list] */
217: n0 = mknode(2,tag,cmolist);
218: MKLIST(oxlist,n0);
219:
220: /* creation of [OX_LOCAL_OBJECT_ASIR,ASIR tag] */
221: /* ox tag */
222: MKUSINT(tag,OX_LOCAL_OBJECT_ASIR);
223: /* local tag */
224: MKUSINT(t,ASIR_VL);
225: MKUSINT(t1,ASIR_OBJ);
226: n0 = mknode(2,t,t1); MKLIST(cmolist,n0);
227: /* [ox tag, local list] */
228: n0 = mknode(2,tag,cmolist);
229: MKLIST(asirlist,n0);
230:
231: /* [oxlist,asirlist] */
232: n0 = mknode(2,oxlist,asirlist); MKLIST(oxasir,n0);
233:
234: /* [version,sm,oxasir] */
235: n0 = mknode(3,sname,smlist,oxasir); MKLIST(r,n0);
236:
237: MKMATHCAP(my_mathcap,r);
238: mclist_to_mc(r,&my_mc);
239: my_oxcap = my_mc.oxcap;
240: }
241:
242: void store_remote_mathcap(int s,MATHCAP mc)
243: {
244: if ( !remote_mc ) {
245: remote_mc_len = 16;
246: remote_mc = (struct mathcap *)
247: CALLOC(remote_mc_len,sizeof(struct mathcap));
248: }
249: if ( s >= remote_mc_len ) {
250: remote_mc_len *= 2;
251: remote_mc = (struct mathcap *)REALLOC(remote_mc,
252: remote_mc_len*sizeof(struct mathcap));
253: }
254: mclist_to_mc(BDY(mc),&remote_mc[s]);
255: }
256:
257: /*
258: mathcap =
259: [
260: version list,
261: SMlist,
262: [
263: [OX tag,CMO tag list],
264: [OX tag,CMO tag list],
265: ...
266: ]
267: ]
268:
269: ===>
270:
271: mathcap
272: | version | &servername | nsmcap | &smcap | noxcap | &oxcap |
273: smcap
274: | SM_xxx | SM_yyy | ... |
275: oxcap
276: | oxcap[0] | oxcap[1] | ... |
277: oxcap[i]
278: | ox | ncap | &cap |
279: cap
280: | CMO_xxx | CMO_yyy | ... |
281: */
282:
283: void mclist_to_mc(LIST mclist,struct mathcap *mc)
284: {
1.12 noro 285: int l,i,j;
286: NODE n,t,oxcmo,cap;
1.1 noro 287: int *ptr;
288:
289: /*
290: [
291: [ version,servername ]
292: [sm1,sm2,...],
293: [
294: [o1,[n11,n12,...]],
295: [o2,[n21,n22,...]],
296: ...
297: ]
298: ]
299: */
300: n = BDY(mclist);
301: mc->mc = mclist;
302: mc->version = BDY((USINT)BDY(BDY((LIST)BDY(n))));
303: mc->servername = BDY((STRING)BDY(NEXT(BDY((LIST)BDY(n)))));
304:
305: /* smcap */
306: n = NEXT(n);
307: t = BDY((LIST)BDY(n));
308: mc->nsmcap = length(t);
309: mc->smcap = (int *)MALLOC_ATOMIC(mc->nsmcap*sizeof(int));
310: for ( j = 0, ptr = mc->smcap; j < mc->nsmcap; j++, t = NEXT(t) )
311: ptr[j] = BDY((USINT)BDY(t));
312:
313: n = NEXT(n);
314: n = BDY((LIST)BDY(n));
315: /* n -> BDY([[OX1,CMOlist1], [OX2,CMOlist2], ...]) */
316: mc->noxcap = length(n);
317: mc->oxcap = (struct oxcap *)MALLOC(mc->noxcap*sizeof(struct oxcap));
318: for ( j = 0; j < mc->noxcap; j++, n = NEXT(n) ) {
319: oxcmo = BDY((LIST)BDY(n));
320: /* oxcmo = BDY([OXj,CMOlistj]) */
321: mc->oxcap[j].ox = BDY((USINT)BDY(oxcmo));
322: cap = BDY((LIST)BDY(NEXT(oxcmo)));
323: /* cap ->BDY(CMOlistj) */
324: l = length(cap);
325: mc->oxcap[j].ncap = l;
326: mc->oxcap[j].cap = (unsigned int *)CALLOC(l+1,sizeof(unsigned int));
327: for ( t = cap, ptr = mc->oxcap[j].cap, i = 0; i < l; t = NEXT(t), i++ )
328: ptr[i] = BDY((USINT)BDY(t));
329: }
330: }
331:
1.12 noro 332: int check_sm_by_mc(int s,unsigned int smtag)
1.1 noro 333: {
334: struct mathcap *rmc;
335: int nsmcap,i;
336: unsigned int *smcap;
337:
338: /* XXX : return 1 if remote_mc is not available. */
339: if ( !remote_mc )
340: return 1;
341: rmc = &remote_mc[s];
342: nsmcap = rmc->nsmcap;
343: smcap = rmc->smcap;
344: if ( !smcap )
345: return 1;
346: for ( i = 0; i < nsmcap; i++ )
347: if ( smcap[i] == smtag )
348: break;
349: if ( i == nsmcap )
350: return 0;
351: else
352: return 1;
353: }
354:
1.12 noro 355: int check_by_mc(int s,unsigned int oxtag,unsigned int cmotag)
1.1 noro 356: {
357: struct mathcap *rmc;
358: int noxcap,ncap,i,j;
359: struct oxcap *oxcap;
360: unsigned int *cap;
361:
362: /* XXX : return 1 if remote_mc is not available. */
363: if ( !remote_mc )
364: return 1;
365: rmc = &remote_mc[s];
366: noxcap = rmc->noxcap;
367: oxcap = rmc->oxcap;
368: if ( !oxcap )
369: return 1;
370: for ( i = 0; i < noxcap; i++ )
371: if ( oxcap[i].ox == oxtag )
372: break;
373: if ( i == noxcap )
374: return 0;
375: ncap = oxcap[i].ncap;
376: cap = oxcap[i].cap;
377: for ( j = 0; j < ncap; j++ )
378: if ( cap[j] == cmotag )
379: break;
380: if ( j == ncap )
381: return 0;
382: else
383: return 1;
384: }
385:
386: void begin_critical() {
387: critical_when_signal = 1;
388: }
389:
390: void end_critical() {
391: critical_when_signal = 0;
392: if ( ox_usr1_sent ) {
1.12 noro 393: ox_usr1_sent = 0;
394: #if !defined(VISUAL)
395: ox_usr1_handler(SIGUSR1);
396: #else
397: ox_usr1_handler(0);
398: #endif
1.1 noro 399: }
400: if ( ox_int_received ) {
401: ox_int_received = 0; int_handler(SIGINT);
402: }
403: }
404:
1.18 noro 405: extern FUNC registered_handler;
406:
1.12 noro 407: void ox_usr1_handler(int sig)
1.1 noro 408: {
409: #if !defined(VISUAL)
410: signal(SIGUSR1,ox_usr1_handler);
411: #endif
412: if ( critical_when_signal ) {
413: fprintf(stderr,"usr1 : critical\n");
414: ox_usr1_sent = 1;
415: } else {
416: ox_flushing = 1;
1.18 noro 417: if ( registered_handler ) {
418: fprintf(stderr,
419: "usr1 : calling the registered exception handler...");
420: bevalf(registered_handler,0);
421: fprintf(stderr, "done.\n");
422: }
1.1 noro 423: ox_resetenv("usr1 : return to toplevel by SIGUSR1");
424: }
425: }
426:
427: void clear_readbuffer()
428: {
429: #if defined(linux)
430: iofp[0].in->_IO_read_ptr = iofp[0].in->_IO_read_end;
431: #elif defined(__FreeBSD__)
432: fpurge(iofp[0].in);
433: #endif
434: /*
435: sock = fileno(iofp[0].in);
436: interval.tv_sec = (int)0;
437: interval.tv_usec = (int)0;
438:
439: FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
440: FD_SET(sock,&r);
441: while ( 1 ) {
442: n = select(FD_SETSIZE,&r,&w,&e,&interval);
443: if ( !n )
444: break;
445: read(sock,&c,1);
446: }
447: */
448: }
449:
1.20 noro 450: #if MPI
1.1 noro 451: int ox_data_is_available(int s)
452: {
453: return 1;
454: }
455:
456: void wait_for_data(int s)
457: {
458: return;
459: }
460: #else
461: int ox_data_is_available(int s)
462: {
463: return FP_DATA_IS_AVAILABLE(iofp[s].in);
464: }
465:
466: void wait_for_data(int s)
467: {
468: fd_set r;
469: int sock;
470:
471: if ( !FP_DATA_IS_AVAILABLE(iofp[s].in) ) {
472: #if defined(VISUAL)
473: sock = iofp[s].in->fildes;
474: FD_ZERO(&r);
1.12 noro 475: FD_SET((unsigned int)sock,&r);
1.1 noro 476: select(0,&r,NULL,NULL,NULL);
477: #else
478: sock = fileno(iofp[s].in);
479: FD_ZERO(&r);
480: FD_SET(sock,&r);
481: select(FD_SETSIZE,&r,NULL,NULL,NULL);
482: #endif
483: }
484: }
1.21 noro 485:
486: void wait_for_data_102(int rank)
487: {
488: fd_set r;
489: int sock;
490:
491: if ( !FP_DATA_IS_AVAILABLE(iofp_102[rank].in) ) {
492: #if defined(VISUAL)
493: sock = iofp_102[rank].in->fildes;
494: FD_ZERO(&r);
495: FD_SET((unsigned int)sock,&r);
496: select(0,&r,NULL,NULL,NULL);
497: #else
498: sock = fileno(iofp_102[rank].in);
499: FD_ZERO(&r);
500: FD_SET(sock,&r);
501: select(FD_SETSIZE,&r,NULL,NULL,NULL);
502: #endif
503: }
504: }
1.1 noro 505: #endif
506:
507: void ox_send_data(int s,pointer p)
508: {
1.8 noro 509: ERR err;
510:
511: if ( ox_check && !ox_check_cmo(s,(Obj)p) ) {
512: create_error(&err,ox_serial,"ox_send_data : Mathcap violation");
513: p = (pointer)err;
514: }
1.1 noro 515: begin_critical();
516: ox_write_int(s,OX_DATA);
517: ox_write_int(s,ox_serial++);
518: ox_write_cmo(s,p);
519: ox_flush_stream(s);
520: end_critical();
521: }
522:
1.21 noro 523: void ox_send_data_102(int rank,pointer p)
524: {
525: ERR err;
526:
527: begin_critical();
528: ox_write_int_102(rank,OX_DATA);
529: ox_write_int_102(rank,ox_serial++);
530: ox_write_cmo_102(rank,p);
531: ox_flush_stream_102(rank);
532: end_critical();
1.22 ! noro 533: }
! 534:
! 535: void ox_bcast_102(int root,Obj *rp)
! 536: {
! 537: Obj data;
! 538: int n,myr,r,mask,src,dst,id;
! 539:
! 540: data = *rp;
! 541: n = nserver_102;
! 542: myr = myrank_102;
! 543: r = myr-root;
! 544: if ( r < 0 ) r += n;
! 545: for ( mask = 1; mask < n; mask <<= 1 )
! 546: if ( r&mask ) {
! 547: src = myr-mask;
! 548: if ( src < 0 ) src += n;
! 549: ox_recv_102(src,&id,&data);
! 550: break;
! 551: }
! 552: for ( mask >>= 1; mask > 0; mask >>= 1 )
! 553: if ( (r+mask) < n ) {
! 554: dst = myr+mask;
! 555: if ( dst >= n ) dst -= n;
! 556: ox_send_data_102(dst,data);
! 557: }
! 558: *rp = data;
1.21 noro 559: }
560:
1.1 noro 561: void ox_send_cmd(int s,int id)
562: {
563: if ( ox_check && !check_sm_by_mc(s,id) )
564: error("ox_send_cmd : Mathcap violation");
565: begin_critical();
566: ox_write_int(s,OX_COMMAND);
567: ox_write_int(s,ox_serial++);
568: ox_write_int(s,id);
569: ox_flush_stream(s);
570: end_critical();
571: }
572:
573: void ox_send_sync(int s)
574: {
575: begin_critical();
576: ox_write_int(s,OX_SYNC_BALL);
577: ox_write_int(s,ox_serial++);
578: ox_flush_stream(s);
579: end_critical();
580: }
581:
1.21 noro 582: void ox_send_sync_102(int rank)
583: {
584: begin_critical();
585: ox_write_int_102(rank,OX_SYNC_BALL);
586: ox_write_int_102(rank,ox_serial++);
587: ox_flush_stream_102(rank);
588: end_critical();
589: }
590:
1.1 noro 591: void ox_send_local_data(int s,Obj p)
592: {
593: begin_critical();
594: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
595: ox_write_int(s,ox_serial++);
596: ox_write_int(s,ASIR_OBJ);
1.12 noro 597: saveobj((FILE *)iofp[s].out,p);
1.1 noro 598: ox_flush_stream(s);
599: end_critical();
600: }
601:
1.21 noro 602: void ox_send_local_data_102(int rank,Obj p)
603: {
604: begin_critical();
605: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
606: ox_write_int_102(rank,ox_serial++);
607: ox_write_int_102(rank,ASIR_OBJ);
608: saveobj((FILE *)iofp_102[rank].out,p);
609: ox_flush_stream_102(rank);
610: end_critical();
611: }
612:
1.1 noro 613: void ox_send_local_ring(int s,VL vl)
614: {
615: begin_critical();
616: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
617: ox_write_int(s,ox_serial++);
618: ox_write_int(s,ASIR_VL);
1.12 noro 619: savevl((FILE *)iofp[s].out,vl);
1.1 noro 620: ox_flush_stream(s);
621: end_critical();
622: }
623:
1.21 noro 624: void ox_send_local_ring_102(int rank,VL vl)
625: {
626: begin_critical();
627: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
628: ox_write_int_102(rank,ox_serial++);
629: ox_write_int_102(rank,ASIR_VL);
630: savevl((FILE *)iofp_102[rank].out,vl);
631: ox_flush_stream_102(rank);
632: end_critical();
633: }
634:
1.12 noro 635: unsigned int ox_recv(int s, int *id, Obj *p)
1.1 noro 636: {
637: unsigned int cmd,serial;
638: USINT ui;
639:
640: wait_for_data(s);
641: begin_critical();
642: ox_read_int(s,id);
643: ox_read_int(s,&serial);
644: switch ( *id ) {
645: case OX_COMMAND:
646: ox_read_int(s,&cmd);
647: MKUSINT(ui,cmd);
1.12 noro 648: *p = (Obj)ui;
1.1 noro 649: break;
650: case OX_DATA:
651: ox_read_cmo(s,p);
652: break;
653: case OX_LOCAL_OBJECT_ASIR:
654: ox_read_local(s,p);
655: break;
656: default:
657: *p = 0;
658: break;
659: }
660: end_critical();
661: return serial;
662: }
663:
1.21 noro 664: unsigned int ox_recv_102(int rank, int *id, Obj *p)
665: {
666: unsigned int cmd,serial;
667: USINT ui;
668:
669: wait_for_data_102(rank);
670: begin_critical();
671: ox_read_int_102(rank,id);
672: ox_read_int_102(rank,&serial);
673: switch ( *id ) {
674: case OX_COMMAND:
675: ox_read_int_102(rank,&cmd);
676: MKUSINT(ui,cmd);
677: *p = (Obj)ui;
678: break;
679: case OX_DATA:
680: ox_read_cmo_102(rank,p);
681: break;
682: case OX_LOCAL_OBJECT_ASIR:
683: ox_read_local_102(rank,p);
684: break;
685: default:
686: *p = 0;
687: break;
688: }
689: end_critical();
690: return serial;
691: }
692:
1.12 noro 693: void ox_get_result(int s,Obj *rp)
1.1 noro 694: {
695: int id;
696: Obj obj,r;
697: int level;
698:
699: level = 0;
700: r = 0;
701: do {
1.12 noro 702: ox_recv(s,&id,&obj);
1.1 noro 703: if ( id == OX_COMMAND ) {
704: switch ( ((USINT)obj)->body ) {
705: case SM_beginBlock:
706: level++;
707: break;
708: case SM_endBlock:
709: level--;
710: }
711: } else
712: r = obj;
713: } while ( level );
714: *rp = r;
715: }
716:
717: void ox_read_int(int s, int *n)
718: {
719: ox_need_conv = iofp[s].conv;
1.12 noro 720: read_int((FILE *)iofp[s].in,n);
1.1 noro 721: }
722:
1.21 noro 723: void ox_read_int_102(int rank, int *n)
724: {
725: ox_need_conv = iofp_102[rank].conv;
726: read_int((FILE *)iofp_102[rank].in,n);
727: }
728:
1.1 noro 729: void ox_read_cmo(int s, Obj *rp)
730: {
731: ox_need_conv = iofp[s].conv;
1.12 noro 732: read_cmo((FILE *)iofp[s].in,rp);
1.1 noro 733: }
734:
1.21 noro 735: void ox_read_cmo_102(int rank, Obj *rp)
736: {
737: ox_need_conv = iofp_102[rank].conv;
738: read_cmo((FILE *)iofp_102[rank].in,rp);
739: }
740:
741:
1.1 noro 742: void ox_read_local(int s, Obj *rp)
743: {
744: int id;
745:
746: ox_need_conv = iofp[s].conv;
1.12 noro 747: read_int((FILE *)iofp[s].in,&id);
1.1 noro 748: switch ( id ) {
749: case ASIR_VL:
1.12 noro 750: loadvl((FILE *)iofp[s].in);
1.1 noro 751: *rp = VOIDobj;
752: break;
753: case ASIR_OBJ:
1.12 noro 754: loadobj((FILE *)iofp[s].in,rp);
1.1 noro 755: break;
756: default:
757: error("ox_read_local : unsupported id");
758: break;
759: }
760: }
761:
1.21 noro 762: void ox_read_local_102(int rank, Obj *rp)
763: {
764: int id;
765:
766: ox_need_conv = iofp_102[rank].conv;
767: read_int((FILE *)iofp_102[rank].in,&id);
768: switch ( id ) {
769: case ASIR_VL:
770: loadvl((FILE *)iofp_102[rank].in);
771: *rp = VOIDobj;
772: break;
773: case ASIR_OBJ:
774: loadobj((FILE *)iofp_102[rank].in,rp);
775: break;
776: default:
777: error("ox_read_local_102 : unsupported id");
778: break;
779: }
780: }
781:
1.1 noro 782: void ox_write_int(int s, int n)
783: {
784: ox_need_conv = iofp[s].conv;
1.12 noro 785: write_int((FILE *)iofp[s].out,&n);
1.1 noro 786: }
787:
1.21 noro 788: void ox_write_int_102(int rank, int n)
789: {
790: ox_need_conv = iofp_102[rank].conv;
791: write_int((FILE *)iofp_102[rank].out,&n);
792: }
793:
1.1 noro 794: void ox_write_cmo(int s, Obj obj)
795: {
796: ox_need_conv = iofp[s].conv;
1.12 noro 797: write_cmo((FILE *)iofp[s].out,obj);
1.1 noro 798: }
799:
1.21 noro 800: void ox_write_cmo_102(int rank, Obj obj)
801: {
802: ox_need_conv = iofp_102[rank].conv;
803: write_cmo((FILE *)iofp_102[rank].out,obj);
804: }
805:
1.1 noro 806: int ox_check_cmo(int s, Obj obj)
807: {
808: NODE m;
809:
810: if ( !obj )
811: return 1;
812: switch ( OID(obj) ) {
813: case O_MATHCAP: case O_STR: case O_ERR: case O_USINT: case O_VOID:
1.10 noro 814: case O_BYTEARRAY:
1.1 noro 815: return 1;
816: case O_P:
817: if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
818: return 0;
819: else
820: return ox_check_cmo_p(s,(P)obj);
821: case O_R:
822: if ( !check_by_mc(s,OX_DATA,CMO_RATIONAL) )
823: return 0;
824: else if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
825: return 0;
826: else
827: return ox_check_cmo_p(s,NM((R)obj)) && ox_check_cmo_p(s,DN((R)obj));
828: case O_DP:
829: return ox_check_cmo_dp(s,(DP)obj);
830: case O_N:
1.4 noro 831: switch ( NID((Num)obj) ) {
832: case N_Q:
833: if ( INT((Q)obj) )
834: return check_by_mc(s,OX_DATA,CMO_ZZ);
835: else
836: return check_by_mc(s,OX_DATA,CMO_QQ);
837: case N_R:
838: return 1;
839: default:
840: return 0;
841: }
842: break;
1.1 noro 843: case O_LIST:
844: for ( m = BDY((LIST)obj); m; m = NEXT(m) )
845: if ( !ox_check_cmo(s,(BDY(m))) )
846: return 0;
1.11 noro 847: return 1;
848: case O_QUOTE: /* XXX */
1.1 noro 849: return 1;
850: default:
851: return 0;
852: }
853: }
854:
855: void ox_get_serverinfo(int s, LIST *rp)
856: {
857: if ( remote_mc )
858: *rp = remote_mc[s].mc;
859: else {
860: MKLIST(*rp,0);
861: }
862: }
1.15 noro 863:
864: char *ox_get_servername(int s)
865: {
866: return (remote_mc && remote_mc[s].servername)?remote_mc[s].servername:0;
867: }
868:
1.1 noro 869:
870: int ox_check_cmo_p(int s, P p)
871: {
872: DCP dc;
873:
874: if ( NUM(p) )
875: return ox_check_cmo(s,(Obj)p);
876: else {
877: for ( dc = DC(p); dc; dc = NEXT(dc) )
878: if ( !ox_check_cmo_p(s,COEF(dc)) )
879: return 0;
880: return 1;
881: }
882: }
883:
884: int ox_check_cmo_dp(int s, DP p)
885: {
886: MP m;
887:
888: for ( m = BDY(p); m; m = NEXT(m) )
889: if ( !ox_check_cmo(s,(Obj)m->c) )
890: return 0;
891: return 1;
892: }
893:
1.12 noro 894: void ox_flush_stream(int s)
1.1 noro 895: {
896: if ( ox_batch )
897: return;
898: #if defined(VISUAL)
899: if ( _fileno(&iofp[s].out->fp) < 0 )
900: cflush(iofp[s].out);
901: else
1.20 noro 902: #elif MPI
1.1 noro 903: if ( (char)fileno(&iofp[s].out->fp) < 0 )
904: cflush(iofp[s].out);
905: else
906: #endif
1.12 noro 907: fflush((FILE *)iofp[s].out);
1.1 noro 908: }
909:
1.12 noro 910: void ox_flush_stream_force(int s)
1.1 noro 911: {
912: #if defined(VISUAL)
913: if ( _fileno(&iofp[s].out->fp) < 0 )
914: cflush(iofp[s].out);
915: else
1.20 noro 916: #elif MPI
1.1 noro 917: if ( (char)fileno(&iofp[s].out->fp) < 0 )
918: cflush(iofp[s].out);
919: else
920: #endif
1.12 noro 921: fflush((FILE *)iofp[s].out);
1.21 noro 922: }
923:
924: void ox_flush_stream_102(int rank)
925: {
926: if ( !ox_batch )
927: ox_flush_stream_force_102(rank);
928: }
929:
930: void ox_flush_stream_force_102(int rank)
931: {
932: if ( iofp_102[rank].out )
933: #if defined(VISUAL)
934: cflush(iofp_102[rank].out);
935: #elif MPI
936: cflush(iofp_102[rank].out);
937: #else
938: fflush(iofp_102[rank].out);
939: #endif
1.1 noro 940: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>