[BACK]Return to ox.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2018 / io

Annotation of OpenXM_contrib2/asir2018/io/ox.c, Revision 1.6

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>