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