Annotation of OpenXM_contrib2/asir2000/io/ox.c, Revision 1.23
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.23 ! noro 47: * $OpenXM: OpenXM_contrib2/asir2000/io/ox.c,v 1.22 2003/12/10 05:39:58 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;
1.23 ! noro 538: int r,mask,id,src,dst;
1.22 noro 539:
540: data = *rp;
1.23 ! noro 541: r = myrank_102-root;
! 542: if ( r < 0 ) r += nserver_102;
! 543: for ( mask = 1; mask < nserver_102; mask <<= 1 )
1.22 noro 544: if ( r&mask ) {
1.23 ! noro 545: src = myrank_102-mask;
! 546: if ( src < 0 ) src += nserver_102;
1.22 noro 547: ox_recv_102(src,&id,&data);
548: break;
549: }
550: for ( mask >>= 1; mask > 0; mask >>= 1 )
1.23 ! noro 551: if ( (r+mask) < nserver_102 ) {
! 552: dst = myrank_102+mask;
! 553: if ( dst >= nserver_102 ) dst -= nserver_102;
1.22 noro 554: ox_send_data_102(dst,data);
555: }
556: *rp = data;
1.23 ! noro 557: }
! 558:
! 559: /* func : an arithmetic funcion func(vl,a,b,*c) */
! 560:
! 561: void ox_reduce_102(int root,void (*func)(),Obj data,Obj *rp)
! 562: {
! 563: Obj data0,t;
! 564: int r,mask,id,src,dst;
! 565:
! 566: r = myrank_102-root;
! 567: if ( r < 0 ) r += nserver_102;
! 568: for ( mask = 1; mask < nserver_102; mask <<= 1 )
! 569: if ( r&mask ) {
! 570: dst = (r-mask)+root;
! 571: if ( dst >= nserver_102 ) dst -= nserver_102;
! 572: ox_send_data_102(dst,data);
! 573: break;
! 574: } else {
! 575: src = r+mask;
! 576: if ( src < nserver_102 ) {
! 577: src += root;
! 578: if ( src >= nserver_102 ) src -= nserver_102;
! 579: ox_recv_102(src,&id,&data0);
! 580: (*func)(CO,data,data0,&t); data = t;
! 581: }
! 582: }
! 583: if ( !r )
! 584: *rp = data;
! 585: else
! 586: *rp = 0;
1.21 noro 587: }
588:
1.1 noro 589: void ox_send_cmd(int s,int id)
590: {
591: if ( ox_check && !check_sm_by_mc(s,id) )
592: error("ox_send_cmd : Mathcap violation");
593: begin_critical();
594: ox_write_int(s,OX_COMMAND);
595: ox_write_int(s,ox_serial++);
596: ox_write_int(s,id);
597: ox_flush_stream(s);
598: end_critical();
599: }
600:
601: void ox_send_sync(int s)
602: {
603: begin_critical();
604: ox_write_int(s,OX_SYNC_BALL);
605: ox_write_int(s,ox_serial++);
606: ox_flush_stream(s);
607: end_critical();
608: }
609:
1.21 noro 610: void ox_send_sync_102(int rank)
611: {
612: begin_critical();
613: ox_write_int_102(rank,OX_SYNC_BALL);
614: ox_write_int_102(rank,ox_serial++);
615: ox_flush_stream_102(rank);
616: end_critical();
617: }
618:
1.1 noro 619: void ox_send_local_data(int s,Obj p)
620: {
621: begin_critical();
622: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
623: ox_write_int(s,ox_serial++);
624: ox_write_int(s,ASIR_OBJ);
1.12 noro 625: saveobj((FILE *)iofp[s].out,p);
1.1 noro 626: ox_flush_stream(s);
627: end_critical();
628: }
629:
1.21 noro 630: void ox_send_local_data_102(int rank,Obj p)
631: {
632: begin_critical();
633: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
634: ox_write_int_102(rank,ox_serial++);
635: ox_write_int_102(rank,ASIR_OBJ);
636: saveobj((FILE *)iofp_102[rank].out,p);
637: ox_flush_stream_102(rank);
638: end_critical();
639: }
640:
1.1 noro 641: void ox_send_local_ring(int s,VL vl)
642: {
643: begin_critical();
644: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
645: ox_write_int(s,ox_serial++);
646: ox_write_int(s,ASIR_VL);
1.12 noro 647: savevl((FILE *)iofp[s].out,vl);
1.1 noro 648: ox_flush_stream(s);
649: end_critical();
650: }
651:
1.21 noro 652: void ox_send_local_ring_102(int rank,VL vl)
653: {
654: begin_critical();
655: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
656: ox_write_int_102(rank,ox_serial++);
657: ox_write_int_102(rank,ASIR_VL);
658: savevl((FILE *)iofp_102[rank].out,vl);
659: ox_flush_stream_102(rank);
660: end_critical();
661: }
662:
1.12 noro 663: unsigned int ox_recv(int s, int *id, Obj *p)
1.1 noro 664: {
665: unsigned int cmd,serial;
666: USINT ui;
667:
668: wait_for_data(s);
669: begin_critical();
670: ox_read_int(s,id);
671: ox_read_int(s,&serial);
672: switch ( *id ) {
673: case OX_COMMAND:
674: ox_read_int(s,&cmd);
675: MKUSINT(ui,cmd);
1.12 noro 676: *p = (Obj)ui;
1.1 noro 677: break;
678: case OX_DATA:
679: ox_read_cmo(s,p);
680: break;
681: case OX_LOCAL_OBJECT_ASIR:
682: ox_read_local(s,p);
683: break;
684: default:
685: *p = 0;
686: break;
687: }
688: end_critical();
689: return serial;
690: }
691:
1.21 noro 692: unsigned int ox_recv_102(int rank, int *id, Obj *p)
693: {
694: unsigned int cmd,serial;
695: USINT ui;
696:
697: wait_for_data_102(rank);
698: begin_critical();
699: ox_read_int_102(rank,id);
700: ox_read_int_102(rank,&serial);
701: switch ( *id ) {
702: case OX_COMMAND:
703: ox_read_int_102(rank,&cmd);
704: MKUSINT(ui,cmd);
705: *p = (Obj)ui;
706: break;
707: case OX_DATA:
708: ox_read_cmo_102(rank,p);
709: break;
710: case OX_LOCAL_OBJECT_ASIR:
711: ox_read_local_102(rank,p);
712: break;
713: default:
714: *p = 0;
715: break;
716: }
717: end_critical();
718: return serial;
719: }
720:
1.12 noro 721: void ox_get_result(int s,Obj *rp)
1.1 noro 722: {
723: int id;
724: Obj obj,r;
725: int level;
726:
727: level = 0;
728: r = 0;
729: do {
1.12 noro 730: ox_recv(s,&id,&obj);
1.1 noro 731: if ( id == OX_COMMAND ) {
732: switch ( ((USINT)obj)->body ) {
733: case SM_beginBlock:
734: level++;
735: break;
736: case SM_endBlock:
737: level--;
738: }
739: } else
740: r = obj;
741: } while ( level );
742: *rp = r;
743: }
744:
745: void ox_read_int(int s, int *n)
746: {
747: ox_need_conv = iofp[s].conv;
1.12 noro 748: read_int((FILE *)iofp[s].in,n);
1.1 noro 749: }
750:
1.21 noro 751: void ox_read_int_102(int rank, int *n)
752: {
753: ox_need_conv = iofp_102[rank].conv;
754: read_int((FILE *)iofp_102[rank].in,n);
755: }
756:
1.1 noro 757: void ox_read_cmo(int s, Obj *rp)
758: {
759: ox_need_conv = iofp[s].conv;
1.12 noro 760: read_cmo((FILE *)iofp[s].in,rp);
1.1 noro 761: }
762:
1.21 noro 763: void ox_read_cmo_102(int rank, Obj *rp)
764: {
765: ox_need_conv = iofp_102[rank].conv;
766: read_cmo((FILE *)iofp_102[rank].in,rp);
767: }
768:
769:
1.1 noro 770: void ox_read_local(int s, Obj *rp)
771: {
772: int id;
773:
774: ox_need_conv = iofp[s].conv;
1.12 noro 775: read_int((FILE *)iofp[s].in,&id);
1.1 noro 776: switch ( id ) {
777: case ASIR_VL:
1.12 noro 778: loadvl((FILE *)iofp[s].in);
1.1 noro 779: *rp = VOIDobj;
780: break;
781: case ASIR_OBJ:
1.12 noro 782: loadobj((FILE *)iofp[s].in,rp);
1.1 noro 783: break;
784: default:
785: error("ox_read_local : unsupported id");
786: break;
787: }
788: }
789:
1.21 noro 790: void ox_read_local_102(int rank, Obj *rp)
791: {
792: int id;
793:
794: ox_need_conv = iofp_102[rank].conv;
795: read_int((FILE *)iofp_102[rank].in,&id);
796: switch ( id ) {
797: case ASIR_VL:
798: loadvl((FILE *)iofp_102[rank].in);
799: *rp = VOIDobj;
800: break;
801: case ASIR_OBJ:
802: loadobj((FILE *)iofp_102[rank].in,rp);
803: break;
804: default:
805: error("ox_read_local_102 : unsupported id");
806: break;
807: }
808: }
809:
1.1 noro 810: void ox_write_int(int s, int n)
811: {
812: ox_need_conv = iofp[s].conv;
1.12 noro 813: write_int((FILE *)iofp[s].out,&n);
1.1 noro 814: }
815:
1.21 noro 816: void ox_write_int_102(int rank, int n)
817: {
818: ox_need_conv = iofp_102[rank].conv;
819: write_int((FILE *)iofp_102[rank].out,&n);
820: }
821:
1.1 noro 822: void ox_write_cmo(int s, Obj obj)
823: {
824: ox_need_conv = iofp[s].conv;
1.12 noro 825: write_cmo((FILE *)iofp[s].out,obj);
1.1 noro 826: }
827:
1.21 noro 828: void ox_write_cmo_102(int rank, Obj obj)
829: {
830: ox_need_conv = iofp_102[rank].conv;
831: write_cmo((FILE *)iofp_102[rank].out,obj);
832: }
833:
1.1 noro 834: int ox_check_cmo(int s, Obj obj)
835: {
836: NODE m;
837:
838: if ( !obj )
839: return 1;
840: switch ( OID(obj) ) {
841: case O_MATHCAP: case O_STR: case O_ERR: case O_USINT: case O_VOID:
1.10 noro 842: case O_BYTEARRAY:
1.1 noro 843: return 1;
844: case O_P:
845: if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
846: return 0;
847: else
848: return ox_check_cmo_p(s,(P)obj);
849: case O_R:
850: if ( !check_by_mc(s,OX_DATA,CMO_RATIONAL) )
851: return 0;
852: else if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
853: return 0;
854: else
855: return ox_check_cmo_p(s,NM((R)obj)) && ox_check_cmo_p(s,DN((R)obj));
856: case O_DP:
857: return ox_check_cmo_dp(s,(DP)obj);
858: case O_N:
1.4 noro 859: switch ( NID((Num)obj) ) {
860: case N_Q:
861: if ( INT((Q)obj) )
862: return check_by_mc(s,OX_DATA,CMO_ZZ);
863: else
864: return check_by_mc(s,OX_DATA,CMO_QQ);
865: case N_R:
866: return 1;
867: default:
868: return 0;
869: }
870: break;
1.1 noro 871: case O_LIST:
872: for ( m = BDY((LIST)obj); m; m = NEXT(m) )
873: if ( !ox_check_cmo(s,(BDY(m))) )
874: return 0;
1.11 noro 875: return 1;
876: case O_QUOTE: /* XXX */
1.1 noro 877: return 1;
878: default:
879: return 0;
880: }
881: }
882:
883: void ox_get_serverinfo(int s, LIST *rp)
884: {
885: if ( remote_mc )
886: *rp = remote_mc[s].mc;
887: else {
888: MKLIST(*rp,0);
889: }
890: }
1.15 noro 891:
892: char *ox_get_servername(int s)
893: {
894: return (remote_mc && remote_mc[s].servername)?remote_mc[s].servername:0;
895: }
896:
1.1 noro 897:
898: int ox_check_cmo_p(int s, P p)
899: {
900: DCP dc;
901:
902: if ( NUM(p) )
903: return ox_check_cmo(s,(Obj)p);
904: else {
905: for ( dc = DC(p); dc; dc = NEXT(dc) )
906: if ( !ox_check_cmo_p(s,COEF(dc)) )
907: return 0;
908: return 1;
909: }
910: }
911:
912: int ox_check_cmo_dp(int s, DP p)
913: {
914: MP m;
915:
916: for ( m = BDY(p); m; m = NEXT(m) )
917: if ( !ox_check_cmo(s,(Obj)m->c) )
918: return 0;
919: return 1;
920: }
921:
1.12 noro 922: void ox_flush_stream(int s)
1.1 noro 923: {
924: if ( ox_batch )
925: return;
926: #if defined(VISUAL)
927: if ( _fileno(&iofp[s].out->fp) < 0 )
928: cflush(iofp[s].out);
929: else
1.20 noro 930: #elif MPI
1.1 noro 931: if ( (char)fileno(&iofp[s].out->fp) < 0 )
932: cflush(iofp[s].out);
933: else
934: #endif
1.12 noro 935: fflush((FILE *)iofp[s].out);
1.1 noro 936: }
937:
1.12 noro 938: void ox_flush_stream_force(int s)
1.1 noro 939: {
940: #if defined(VISUAL)
941: if ( _fileno(&iofp[s].out->fp) < 0 )
942: cflush(iofp[s].out);
943: else
1.20 noro 944: #elif MPI
1.1 noro 945: if ( (char)fileno(&iofp[s].out->fp) < 0 )
946: cflush(iofp[s].out);
947: else
948: #endif
1.12 noro 949: fflush((FILE *)iofp[s].out);
1.21 noro 950: }
951:
952: void ox_flush_stream_102(int rank)
953: {
954: if ( !ox_batch )
955: ox_flush_stream_force_102(rank);
956: }
957:
958: void ox_flush_stream_force_102(int rank)
959: {
960: if ( iofp_102[rank].out )
961: #if defined(VISUAL)
962: cflush(iofp_102[rank].out);
963: #elif MPI
964: cflush(iofp_102[rank].out);
965: #else
966: fflush(iofp_102[rank].out);
967: #endif
1.1 noro 968: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>