Annotation of OpenXM_contrib2/asir2000/io/ox.c, Revision 1.37
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.37 ! ohara 47: * $OpenXM: OpenXM_contrib2/asir2000/io/ox.c,v 1.36 2015/08/18 02:26:05 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);
1.30 ohara 94: Obj asir_pop_one();
95: void asir_push_one(Obj);
1.12 noro 96:
1.35 fujimoto 97: #if defined(VISUAL) || defined(__MINGW32__)
1.9 noro 98: /* XXX : mainly used in engine2000/io.c, but declared here */
1.33 fujimoto 99: typedef void *HANDLE;
1.9 noro 100: HANDLE hStreamNotify,hStreamNotify_Ack;
101:
102: void cleanup_events()
103: {
104: /* ox_watch_stream may be waiting for hStreamNotify_Ack to be set */
105:
106: ResetEvent(hStreamNotify);
107: SetEvent(hStreamNotify_Ack);
108: }
109: #endif
110:
1.12 noro 111: void ox_resetenv(char *s)
1.1 noro 112: {
1.35 fujimoto 113: #if defined(VISUAL) || defined(__MINGW32__)
1.9 noro 114: cleanup_events();
115: #endif
1.1 noro 116: fprintf(stderr,"%s\n",s);
1.13 noro 117: LONGJMP(ox_env,1);
1.1 noro 118: }
119:
120: static int available_cmo[] = {
121: CMO_NULL, CMO_INT32, CMO_DATUM, CMO_STRING, CMO_MATHCAP,
122: CMO_ERROR, CMO_ERROR2, CMO_LIST, CMO_MONOMIAL32,
123: CMO_ZZ, CMO_QQ, CMO_ZERO,
124: CMO_DMS_GENERIC, CMO_DMS_OF_N_VARIABLES,
125: CMO_RING_BY_NAME, CMO_DISTRIBUTED_POLYNOMIAL,
1.25 takayama 126: CMO_RATIONAL,
1.1 noro 127: CMO_RECURSIVE_POLYNOMIAL, CMO_UNIVARIATE_POLYNOMIAL,
128: CMO_INDETERMINATE,
1.37 ! ohara 129: CMO_TREE, CMO_BIGFLOAT32, CMO_COMPLEX,
1.1 noro 130: 0
131: };
132:
1.17 noro 133: static int asir_available_sm[] = {
134: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
135: SM_popCMO, SM_popString, SM_pushCMOtag, SM_setName,
136: SM_evalName, SM_executeStringByLocalParser,
137: SM_executeStringByLocalParserInBatchMode,
138: SM_executeFunction, SM_shutdown, SM_pops,
139: SM_mathcap, SM_setMathcap, SM_nop,
140: SM_beginBlock, SM_endBlock,
141: 0
142: };
143:
1.15 noro 144: static int ox_asir_available_sm[] = {
1.1 noro 145: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
1.7 noro 146: SM_popCMO, SM_popString, SM_pushCMOtag, SM_setName,
1.1 noro 147: SM_evalName, SM_executeStringByLocalParser,
148: SM_executeStringByLocalParserInBatchMode,
149: SM_executeFunction, SM_shutdown, SM_pops,
150: SM_mathcap, SM_setMathcap, SM_nop,
1.29 noro 151: SM_beginBlock, SM_endBlock, SM_executeFunctionSync,
1.21 noro 152: SM_set_rank_102, SM_tcp_accept_102, SM_tcp_connect_102, SM_reset_102,
1.24 noro 153: SM_bcast_102, SM_reduce_102,
1.1 noro 154: 0
155: };
156:
1.15 noro 157: static int ox_plot_available_sm[] = {
158: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
159: SM_popCMO, SM_popString, SM_setName,
160: SM_evalName, SM_executeStringByLocalParser,
161: SM_executeFunction, SM_shutdown, SM_pops,
1.16 noro 162: SM_mathcap, SM_setMathcap, SM_nop,
1.15 noro 163: 0
164: };
165:
1.1 noro 166: /*
167: mathcap =
168: [
169: version list,
170: SMlist,
171: [
172: [OX tag,CMO tag list],
173: [OX tag,CMO tag list],
174: ...
175: ]
176: ]
177: */
178:
179: void create_my_mathcap(char *system)
180: {
181: NODE n,n0;
182: int i,k;
183: STRING str;
1.12 noro 184: LIST sname,smlist,oxlist,cmolist,asirlist,oxasir,r;
1.1 noro 185: USINT tag,t,t1;
186:
187: if ( my_mathcap )
188: return;
189: /* version */
190: MKSTR(str,system);
191: MKUSINT(t,OX_VERSION);
192: n0 = mknode(2,t,str); MKLIST(sname,n0);
193:
1.15 noro 194: /* sm tag */
195: n0 = 0;
1.17 noro 196: if ( !strcmp(system,"asir") ) {
197: for ( i = 0; k = asir_available_sm[i]; i++ ) {
198: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
199: }
200: } else if ( !strcmp(system,"ox_asir") ) {
1.15 noro 201: for ( i = 0; k = ox_asir_available_sm[i]; i++ ) {
202: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
203: }
204: NEXT(n) = 0;
205: } else if ( !strcmp(system,"ox_plot") ) {
206: for ( i = 0; k = ox_plot_available_sm[i]; i++ ) {
207: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
208: }
209: NEXT(n) = 0;
1.1 noro 210: }
1.15 noro 211: MKLIST(smlist,n0);
1.1 noro 212:
213: /* creation of [OX_DATA,CMO list] */
214: /* ox tag */
215: MKUSINT(tag,OX_DATA);
216: /* cmo tag */
217: for ( n0 = 0, i = 0; k = available_cmo[i]; i++ ) {
218: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
219: }
220: NEXT(n) = 0; MKLIST(cmolist,n0);
221: /* [ox tag, cmo list] */
222: n0 = mknode(2,tag,cmolist);
223: MKLIST(oxlist,n0);
224:
225: /* creation of [OX_LOCAL_OBJECT_ASIR,ASIR tag] */
226: /* ox tag */
227: MKUSINT(tag,OX_LOCAL_OBJECT_ASIR);
228: /* local tag */
229: MKUSINT(t,ASIR_VL);
230: MKUSINT(t1,ASIR_OBJ);
231: n0 = mknode(2,t,t1); MKLIST(cmolist,n0);
232: /* [ox tag, local list] */
233: n0 = mknode(2,tag,cmolist);
234: MKLIST(asirlist,n0);
235:
236: /* [oxlist,asirlist] */
237: n0 = mknode(2,oxlist,asirlist); MKLIST(oxasir,n0);
238:
239: /* [version,sm,oxasir] */
240: n0 = mknode(3,sname,smlist,oxasir); MKLIST(r,n0);
241:
242: MKMATHCAP(my_mathcap,r);
243: mclist_to_mc(r,&my_mc);
244: my_oxcap = my_mc.oxcap;
245: }
246:
247: void store_remote_mathcap(int s,MATHCAP mc)
248: {
249: if ( !remote_mc ) {
250: remote_mc_len = 16;
251: remote_mc = (struct mathcap *)
252: CALLOC(remote_mc_len,sizeof(struct mathcap));
253: }
254: if ( s >= remote_mc_len ) {
255: remote_mc_len *= 2;
256: remote_mc = (struct mathcap *)REALLOC(remote_mc,
257: remote_mc_len*sizeof(struct mathcap));
258: }
259: mclist_to_mc(BDY(mc),&remote_mc[s]);
260: }
261:
262: /*
263: mathcap =
264: [
265: version list,
266: SMlist,
267: [
268: [OX tag,CMO tag list],
269: [OX tag,CMO tag list],
270: ...
271: ]
272: ]
273:
274: ===>
275:
276: mathcap
277: | version | &servername | nsmcap | &smcap | noxcap | &oxcap |
278: smcap
279: | SM_xxx | SM_yyy | ... |
280: oxcap
281: | oxcap[0] | oxcap[1] | ... |
282: oxcap[i]
283: | ox | ncap | &cap |
284: cap
285: | CMO_xxx | CMO_yyy | ... |
286: */
287:
288: void mclist_to_mc(LIST mclist,struct mathcap *mc)
289: {
1.12 noro 290: int l,i,j;
291: NODE n,t,oxcmo,cap;
1.1 noro 292: int *ptr;
293:
294: /*
295: [
296: [ version,servername ]
297: [sm1,sm2,...],
298: [
299: [o1,[n11,n12,...]],
300: [o2,[n21,n22,...]],
301: ...
302: ]
303: ]
304: */
305: n = BDY(mclist);
306: mc->mc = mclist;
307: mc->version = BDY((USINT)BDY(BDY((LIST)BDY(n))));
308: mc->servername = BDY((STRING)BDY(NEXT(BDY((LIST)BDY(n)))));
309:
310: /* smcap */
311: n = NEXT(n);
312: t = BDY((LIST)BDY(n));
313: mc->nsmcap = length(t);
314: mc->smcap = (int *)MALLOC_ATOMIC(mc->nsmcap*sizeof(int));
315: for ( j = 0, ptr = mc->smcap; j < mc->nsmcap; j++, t = NEXT(t) )
316: ptr[j] = BDY((USINT)BDY(t));
317:
318: n = NEXT(n);
319: n = BDY((LIST)BDY(n));
320: /* n -> BDY([[OX1,CMOlist1], [OX2,CMOlist2], ...]) */
321: mc->noxcap = length(n);
322: mc->oxcap = (struct oxcap *)MALLOC(mc->noxcap*sizeof(struct oxcap));
323: for ( j = 0; j < mc->noxcap; j++, n = NEXT(n) ) {
324: oxcmo = BDY((LIST)BDY(n));
325: /* oxcmo = BDY([OXj,CMOlistj]) */
326: mc->oxcap[j].ox = BDY((USINT)BDY(oxcmo));
327: cap = BDY((LIST)BDY(NEXT(oxcmo)));
328: /* cap ->BDY(CMOlistj) */
329: l = length(cap);
330: mc->oxcap[j].ncap = l;
331: mc->oxcap[j].cap = (unsigned int *)CALLOC(l+1,sizeof(unsigned int));
332: for ( t = cap, ptr = mc->oxcap[j].cap, i = 0; i < l; t = NEXT(t), i++ )
333: ptr[i] = BDY((USINT)BDY(t));
334: }
335: }
336:
1.12 noro 337: int check_sm_by_mc(int s,unsigned int smtag)
1.1 noro 338: {
339: struct mathcap *rmc;
340: int nsmcap,i;
341: unsigned int *smcap;
342:
343: /* XXX : return 1 if remote_mc is not available. */
344: if ( !remote_mc )
345: return 1;
346: rmc = &remote_mc[s];
347: nsmcap = rmc->nsmcap;
348: smcap = rmc->smcap;
349: if ( !smcap )
350: return 1;
351: for ( i = 0; i < nsmcap; i++ )
352: if ( smcap[i] == smtag )
353: break;
354: if ( i == nsmcap )
355: return 0;
356: else
357: return 1;
358: }
359:
1.12 noro 360: int check_by_mc(int s,unsigned int oxtag,unsigned int cmotag)
1.1 noro 361: {
362: struct mathcap *rmc;
363: int noxcap,ncap,i,j;
364: struct oxcap *oxcap;
365: unsigned int *cap;
366:
367: /* XXX : return 1 if remote_mc is not available. */
368: if ( !remote_mc )
369: return 1;
370: rmc = &remote_mc[s];
371: noxcap = rmc->noxcap;
372: oxcap = rmc->oxcap;
373: if ( !oxcap )
374: return 1;
375: for ( i = 0; i < noxcap; i++ )
376: if ( oxcap[i].ox == oxtag )
377: break;
378: if ( i == noxcap )
379: return 0;
380: ncap = oxcap[i].ncap;
381: cap = oxcap[i].cap;
382: for ( j = 0; j < ncap; j++ )
383: if ( cap[j] == cmotag )
384: break;
385: if ( j == ncap )
386: return 0;
387: else
388: return 1;
389: }
390:
391: void begin_critical() {
392: critical_when_signal = 1;
393: }
394:
395: void end_critical() {
396: critical_when_signal = 0;
397: if ( ox_usr1_sent ) {
1.12 noro 398: ox_usr1_sent = 0;
1.35 fujimoto 399: #if !defined(VISUAL) && !defined(__MINGW32__)
1.12 noro 400: ox_usr1_handler(SIGUSR1);
401: #else
402: ox_usr1_handler(0);
403: #endif
1.1 noro 404: }
405: if ( ox_int_received ) {
406: ox_int_received = 0; int_handler(SIGINT);
407: }
408: }
409:
1.26 noro 410: extern NODE user_int_handler;
1.18 noro 411:
1.12 noro 412: void ox_usr1_handler(int sig)
1.1 noro 413: {
1.26 noro 414: NODE t;
415:
1.35 fujimoto 416: #if !defined(VISUAL) && !defined(__MINGW32__)
1.1 noro 417: signal(SIGUSR1,ox_usr1_handler);
418: #endif
419: if ( critical_when_signal ) {
420: fprintf(stderr,"usr1 : critical\n");
421: ox_usr1_sent = 1;
422: } else {
423: ox_flushing = 1;
1.26 noro 424: if ( user_int_handler ) {
1.18 noro 425: fprintf(stderr,
1.26 noro 426: "usr1 : calling the registered exception handlers...");
427: for ( t = user_int_handler; t; t = NEXT(t) )
428: bevalf((FUNC)BDY(t),0);
1.18 noro 429: fprintf(stderr, "done.\n");
430: }
1.1 noro 431: ox_resetenv("usr1 : return to toplevel by SIGUSR1");
432: }
433: }
434:
435: void clear_readbuffer()
436: {
437: #if defined(linux)
438: iofp[0].in->_IO_read_ptr = iofp[0].in->_IO_read_end;
439: #elif defined(__FreeBSD__)
440: fpurge(iofp[0].in);
441: #endif
442: /*
443: sock = fileno(iofp[0].in);
444: interval.tv_sec = (int)0;
445: interval.tv_usec = (int)0;
446:
447: FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
448: FD_SET(sock,&r);
449: while ( 1 ) {
450: n = select(FD_SETSIZE,&r,&w,&e,&interval);
451: if ( !n )
452: break;
453: read(sock,&c,1);
454: }
455: */
456: }
457:
1.20 noro 458: #if MPI
1.1 noro 459: int ox_data_is_available(int s)
460: {
461: return 1;
462: }
463:
464: void wait_for_data(int s)
465: {
466: return;
467: }
1.28 ohara 468:
469: void wait_for_data_102(int rank)
470: {
471: return;
472: }
1.1 noro 473: #else
474: int ox_data_is_available(int s)
475: {
476: return FP_DATA_IS_AVAILABLE(iofp[s].in);
477: }
478:
479: void wait_for_data(int s)
480: {
481: fd_set r;
482: int sock;
483:
484: if ( !FP_DATA_IS_AVAILABLE(iofp[s].in) ) {
1.35 fujimoto 485: #if defined(VISUAL) || defined(__MINGW32__)
1.1 noro 486: sock = iofp[s].in->fildes;
487: FD_ZERO(&r);
1.12 noro 488: FD_SET((unsigned int)sock,&r);
1.1 noro 489: select(0,&r,NULL,NULL,NULL);
490: #else
491: sock = fileno(iofp[s].in);
492: FD_ZERO(&r);
493: FD_SET(sock,&r);
494: select(FD_SETSIZE,&r,NULL,NULL,NULL);
495: #endif
496: }
497: }
1.21 noro 498:
499: void wait_for_data_102(int rank)
500: {
501: fd_set r;
502: int sock;
503:
504: if ( !FP_DATA_IS_AVAILABLE(iofp_102[rank].in) ) {
1.35 fujimoto 505: #if defined(VISUAL) || defined(__MINGW32__)
1.21 noro 506: sock = iofp_102[rank].in->fildes;
507: FD_ZERO(&r);
508: FD_SET((unsigned int)sock,&r);
509: select(0,&r,NULL,NULL,NULL);
510: #else
511: sock = fileno(iofp_102[rank].in);
512: FD_ZERO(&r);
513: FD_SET(sock,&r);
514: select(FD_SETSIZE,&r,NULL,NULL,NULL);
515: #endif
516: }
517: }
1.1 noro 518: #endif
519:
520: void ox_send_data(int s,pointer p)
521: {
1.8 noro 522: ERR err;
523:
524: if ( ox_check && !ox_check_cmo(s,(Obj)p) ) {
1.27 noro 525: create_error(&err,ox_serial,"ox_send_data : Mathcap violation",0);
1.8 noro 526: p = (pointer)err;
527: }
1.1 noro 528: begin_critical();
529: ox_write_int(s,OX_DATA);
530: ox_write_int(s,ox_serial++);
531: ox_write_cmo(s,p);
532: ox_flush_stream(s);
533: end_critical();
534: }
535:
1.21 noro 536: void ox_send_data_102(int rank,pointer p)
537: {
538: ERR err;
539:
540: begin_critical();
541: ox_write_int_102(rank,OX_DATA);
542: ox_write_int_102(rank,ox_serial++);
543: ox_write_cmo_102(rank,p);
544: ox_flush_stream_102(rank);
545: end_critical();
1.22 noro 546: }
547:
1.24 noro 548: void ox_bcast_102(int root)
1.22 noro 549: {
550: Obj data;
1.23 noro 551: int r,mask,id,src,dst;
1.22 noro 552:
1.23 noro 553: r = myrank_102-root;
1.24 noro 554: if ( r == 0 )
555: data = (Obj)asir_pop_one();
556:
1.23 noro 557: if ( r < 0 ) r += nserver_102;
558: for ( mask = 1; mask < nserver_102; mask <<= 1 )
1.22 noro 559: if ( r&mask ) {
1.23 noro 560: src = myrank_102-mask;
561: if ( src < 0 ) src += nserver_102;
1.22 noro 562: ox_recv_102(src,&id,&data);
563: break;
564: }
565: for ( mask >>= 1; mask > 0; mask >>= 1 )
1.23 noro 566: if ( (r+mask) < nserver_102 ) {
567: dst = myrank_102+mask;
568: if ( dst >= nserver_102 ) dst -= nserver_102;
1.22 noro 569: ox_send_data_102(dst,data);
570: }
1.24 noro 571: asir_push_one(data);
1.23 noro 572: }
573:
574: /* func : an arithmetic funcion func(vl,a,b,*c) */
575:
1.24 noro 576: void ox_reduce_102(int root,void (*func)())
1.23 noro 577: {
1.24 noro 578: Obj data,data0,t;
1.23 noro 579: int r,mask,id,src,dst;
580:
581: r = myrank_102-root;
582: if ( r < 0 ) r += nserver_102;
1.24 noro 583: data = (Obj)asir_pop_one();
1.23 noro 584: for ( mask = 1; mask < nserver_102; mask <<= 1 )
585: if ( r&mask ) {
586: dst = (r-mask)+root;
587: if ( dst >= nserver_102 ) dst -= nserver_102;
588: ox_send_data_102(dst,data);
589: break;
590: } else {
591: src = r+mask;
592: if ( src < nserver_102 ) {
593: src += root;
594: if ( src >= nserver_102 ) src -= nserver_102;
595: ox_recv_102(src,&id,&data0);
596: (*func)(CO,data,data0,&t); data = t;
597: }
598: }
1.24 noro 599: asir_push_one(r?0:data);
1.21 noro 600: }
601:
1.1 noro 602: void ox_send_cmd(int s,int id)
603: {
604: if ( ox_check && !check_sm_by_mc(s,id) )
605: error("ox_send_cmd : Mathcap violation");
606: begin_critical();
607: ox_write_int(s,OX_COMMAND);
608: ox_write_int(s,ox_serial++);
609: ox_write_int(s,id);
610: ox_flush_stream(s);
611: end_critical();
612: }
613:
614: void ox_send_sync(int s)
615: {
616: begin_critical();
617: ox_write_int(s,OX_SYNC_BALL);
618: ox_write_int(s,ox_serial++);
619: ox_flush_stream(s);
620: end_critical();
621: }
622:
1.21 noro 623: void ox_send_sync_102(int rank)
624: {
625: begin_critical();
626: ox_write_int_102(rank,OX_SYNC_BALL);
627: ox_write_int_102(rank,ox_serial++);
628: ox_flush_stream_102(rank);
629: end_critical();
630: }
631:
1.1 noro 632: void ox_send_local_data(int s,Obj p)
633: {
634: begin_critical();
635: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
636: ox_write_int(s,ox_serial++);
637: ox_write_int(s,ASIR_OBJ);
1.12 noro 638: saveobj((FILE *)iofp[s].out,p);
1.1 noro 639: ox_flush_stream(s);
640: end_critical();
641: }
642:
1.21 noro 643: void ox_send_local_data_102(int rank,Obj p)
644: {
645: begin_critical();
646: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
647: ox_write_int_102(rank,ox_serial++);
648: ox_write_int_102(rank,ASIR_OBJ);
649: saveobj((FILE *)iofp_102[rank].out,p);
650: ox_flush_stream_102(rank);
651: end_critical();
652: }
653:
1.1 noro 654: void ox_send_local_ring(int s,VL vl)
655: {
656: begin_critical();
657: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
658: ox_write_int(s,ox_serial++);
659: ox_write_int(s,ASIR_VL);
1.12 noro 660: savevl((FILE *)iofp[s].out,vl);
1.1 noro 661: ox_flush_stream(s);
662: end_critical();
663: }
664:
1.21 noro 665: void ox_send_local_ring_102(int rank,VL vl)
666: {
667: begin_critical();
668: ox_write_int_102(rank,OX_LOCAL_OBJECT_ASIR);
669: ox_write_int_102(rank,ox_serial++);
670: ox_write_int_102(rank,ASIR_VL);
671: savevl((FILE *)iofp_102[rank].out,vl);
672: ox_flush_stream_102(rank);
673: end_critical();
674: }
675:
1.12 noro 676: unsigned int ox_recv(int s, int *id, Obj *p)
1.1 noro 677: {
678: unsigned int cmd,serial;
679: USINT ui;
680:
681: wait_for_data(s);
682: begin_critical();
683: ox_read_int(s,id);
684: ox_read_int(s,&serial);
685: switch ( *id ) {
686: case OX_COMMAND:
687: ox_read_int(s,&cmd);
688: MKUSINT(ui,cmd);
1.12 noro 689: *p = (Obj)ui;
1.1 noro 690: break;
691: case OX_DATA:
692: ox_read_cmo(s,p);
693: break;
694: case OX_LOCAL_OBJECT_ASIR:
695: ox_read_local(s,p);
696: break;
697: default:
698: *p = 0;
699: break;
700: }
701: end_critical();
702: return serial;
703: }
704:
1.21 noro 705: unsigned int ox_recv_102(int rank, int *id, Obj *p)
706: {
707: unsigned int cmd,serial;
708: USINT ui;
709:
710: wait_for_data_102(rank);
711: begin_critical();
712: ox_read_int_102(rank,id);
713: ox_read_int_102(rank,&serial);
714: switch ( *id ) {
715: case OX_COMMAND:
716: ox_read_int_102(rank,&cmd);
717: MKUSINT(ui,cmd);
718: *p = (Obj)ui;
719: break;
720: case OX_DATA:
721: ox_read_cmo_102(rank,p);
722: break;
723: case OX_LOCAL_OBJECT_ASIR:
724: ox_read_local_102(rank,p);
725: break;
726: default:
727: *p = 0;
728: break;
729: }
730: end_critical();
731: return serial;
732: }
733:
1.12 noro 734: void ox_get_result(int s,Obj *rp)
1.1 noro 735: {
736: int id;
737: Obj obj,r;
738: int level;
739:
740: level = 0;
741: r = 0;
742: do {
1.12 noro 743: ox_recv(s,&id,&obj);
1.1 noro 744: if ( id == OX_COMMAND ) {
745: switch ( ((USINT)obj)->body ) {
746: case SM_beginBlock:
747: level++;
748: break;
749: case SM_endBlock:
750: level--;
751: }
752: } else
753: r = obj;
754: } while ( level );
755: *rp = r;
756: }
757:
758: void ox_read_int(int s, int *n)
759: {
760: ox_need_conv = iofp[s].conv;
1.12 noro 761: read_int((FILE *)iofp[s].in,n);
1.1 noro 762: }
763:
1.21 noro 764: void ox_read_int_102(int rank, int *n)
765: {
766: ox_need_conv = iofp_102[rank].conv;
767: read_int((FILE *)iofp_102[rank].in,n);
768: }
769:
1.1 noro 770: void ox_read_cmo(int s, Obj *rp)
771: {
772: ox_need_conv = iofp[s].conv;
1.12 noro 773: read_cmo((FILE *)iofp[s].in,rp);
1.1 noro 774: }
775:
1.21 noro 776: void ox_read_cmo_102(int rank, Obj *rp)
777: {
778: ox_need_conv = iofp_102[rank].conv;
779: read_cmo((FILE *)iofp_102[rank].in,rp);
780: }
781:
782:
1.1 noro 783: void ox_read_local(int s, Obj *rp)
784: {
785: int id;
786:
787: ox_need_conv = iofp[s].conv;
1.12 noro 788: read_int((FILE *)iofp[s].in,&id);
1.1 noro 789: switch ( id ) {
790: case ASIR_VL:
1.12 noro 791: loadvl((FILE *)iofp[s].in);
1.1 noro 792: *rp = VOIDobj;
793: break;
794: case ASIR_OBJ:
1.12 noro 795: loadobj((FILE *)iofp[s].in,rp);
1.1 noro 796: break;
797: default:
798: error("ox_read_local : unsupported id");
799: break;
800: }
801: }
802:
1.21 noro 803: void ox_read_local_102(int rank, Obj *rp)
804: {
805: int id;
806:
807: ox_need_conv = iofp_102[rank].conv;
808: read_int((FILE *)iofp_102[rank].in,&id);
809: switch ( id ) {
810: case ASIR_VL:
811: loadvl((FILE *)iofp_102[rank].in);
812: *rp = VOIDobj;
813: break;
814: case ASIR_OBJ:
815: loadobj((FILE *)iofp_102[rank].in,rp);
816: break;
817: default:
818: error("ox_read_local_102 : unsupported id");
819: break;
820: }
821: }
822:
1.1 noro 823: void ox_write_int(int s, int n)
824: {
825: ox_need_conv = iofp[s].conv;
1.12 noro 826: write_int((FILE *)iofp[s].out,&n);
1.1 noro 827: }
828:
1.21 noro 829: void ox_write_int_102(int rank, int n)
830: {
831: ox_need_conv = iofp_102[rank].conv;
832: write_int((FILE *)iofp_102[rank].out,&n);
833: }
834:
1.1 noro 835: void ox_write_cmo(int s, Obj obj)
836: {
837: ox_need_conv = iofp[s].conv;
1.12 noro 838: write_cmo((FILE *)iofp[s].out,obj);
1.1 noro 839: }
840:
1.21 noro 841: void ox_write_cmo_102(int rank, Obj obj)
842: {
843: ox_need_conv = iofp_102[rank].conv;
844: write_cmo((FILE *)iofp_102[rank].out,obj);
845: }
846:
1.1 noro 847: int ox_check_cmo(int s, Obj obj)
848: {
849: NODE m;
850:
851: if ( !obj )
852: return 1;
853: switch ( OID(obj) ) {
854: case O_MATHCAP: case O_STR: case O_ERR: case O_USINT: case O_VOID:
1.10 noro 855: case O_BYTEARRAY:
1.1 noro 856: return 1;
857: case O_P:
858: if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
859: return 0;
860: else
861: return ox_check_cmo_p(s,(P)obj);
862: case O_R:
863: if ( !check_by_mc(s,OX_DATA,CMO_RATIONAL) )
864: return 0;
865: else if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
866: return 0;
867: else
868: return ox_check_cmo_p(s,NM((R)obj)) && ox_check_cmo_p(s,DN((R)obj));
869: case O_DP:
870: return ox_check_cmo_dp(s,(DP)obj);
871: case O_N:
1.4 noro 872: switch ( NID((Num)obj) ) {
873: case N_Q:
874: if ( INT((Q)obj) )
875: return check_by_mc(s,OX_DATA,CMO_ZZ);
876: else
877: return check_by_mc(s,OX_DATA,CMO_QQ);
1.36 noro 878: case N_R: case N_B: case N_C:
1.4 noro 879: return 1;
880: default:
881: return 0;
882: }
883: break;
1.1 noro 884: case O_LIST:
885: for ( m = BDY((LIST)obj); m; m = NEXT(m) )
886: if ( !ox_check_cmo(s,(BDY(m))) )
887: return 0;
1.11 noro 888: return 1;
889: case O_QUOTE: /* XXX */
1.1 noro 890: return 1;
1.32 noro 891: case O_MAT: /* MAT is sent as a list */
892: return 1;
1.1 noro 893: default:
894: return 0;
895: }
896: }
897:
898: void ox_get_serverinfo(int s, LIST *rp)
899: {
900: if ( remote_mc )
901: *rp = remote_mc[s].mc;
902: else {
903: MKLIST(*rp,0);
904: }
905: }
1.15 noro 906:
907: char *ox_get_servername(int s)
908: {
909: return (remote_mc && remote_mc[s].servername)?remote_mc[s].servername:0;
910: }
911:
1.1 noro 912:
913: int ox_check_cmo_p(int s, P p)
914: {
915: DCP dc;
916:
917: if ( NUM(p) )
918: return ox_check_cmo(s,(Obj)p);
919: else {
920: for ( dc = DC(p); dc; dc = NEXT(dc) )
921: if ( !ox_check_cmo_p(s,COEF(dc)) )
922: return 0;
923: return 1;
924: }
925: }
926:
927: int ox_check_cmo_dp(int s, DP p)
928: {
929: MP m;
930:
931: for ( m = BDY(p); m; m = NEXT(m) )
932: if ( !ox_check_cmo(s,(Obj)m->c) )
933: return 0;
934: return 1;
935: }
936:
1.12 noro 937: void ox_flush_stream(int s)
1.1 noro 938: {
939: if ( ox_batch )
940: return;
1.35 fujimoto 941: #if defined(VISUAL) || defined(__MINGW32__)
1.1 noro 942: if ( _fileno(&iofp[s].out->fp) < 0 )
943: cflush(iofp[s].out);
944: else
1.20 noro 945: #elif MPI
1.1 noro 946: if ( (char)fileno(&iofp[s].out->fp) < 0 )
947: cflush(iofp[s].out);
948: else
949: #endif
1.12 noro 950: fflush((FILE *)iofp[s].out);
1.1 noro 951: }
952:
1.12 noro 953: void ox_flush_stream_force(int s)
1.1 noro 954: {
1.35 fujimoto 955: #if defined(VISUAL) || defined(__MINGW32__)
1.1 noro 956: if ( _fileno(&iofp[s].out->fp) < 0 )
957: cflush(iofp[s].out);
958: else
1.20 noro 959: #elif MPI
1.1 noro 960: if ( (char)fileno(&iofp[s].out->fp) < 0 )
961: cflush(iofp[s].out);
962: else
963: #endif
1.12 noro 964: fflush((FILE *)iofp[s].out);
1.21 noro 965: }
966:
967: void ox_flush_stream_102(int rank)
968: {
969: if ( !ox_batch )
970: ox_flush_stream_force_102(rank);
971: }
972:
973: void ox_flush_stream_force_102(int rank)
974: {
975: if ( iofp_102[rank].out )
1.35 fujimoto 976: #if defined(VISUAL) || defined(__MINGW32__)
1.21 noro 977: cflush(iofp_102[rank].out);
978: #elif MPI
979: cflush(iofp_102[rank].out);
980: #else
981: fflush(iofp_102[rank].out);
982: #endif
1.1 noro 983: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>