/* -*- Mode: C -*- * $Basename$ * $Revision$ * Author : Edward Walker / Denis Leconte * Last Modified By: Ulrich Pfeifer * Last Modified On: Thu Sep 20 20:23:12 2001 */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif /* MY EXTENSION */ #include #include #include #include #include "pvm3.h" #define MAXPROCS 100 #define MAXHOSTS 100 #define MAXSTR 100000 #define MAXARGS 50 #define STRING 1 #define INTEGER 2 #define DOUBLE 3 static SV *recvf_callback = (SV *)NULL; static int (*olmatch)(); static int recvf_foo( int bufid, int tid, int tag ) { dSP ; int count; int compare_val; ENTER ; SAVETMPS ; PUSHMARK(sp) ; XPUSHs(sv_2mortal(newSViv(bufid))); XPUSHs(sv_2mortal(newSViv(tid))); XPUSHs(sv_2mortal(newSViv(tag))); PUTBACK ; count = perl_call_sv(recvf_callback,G_SCALAR); SPAGAIN ; if ( count != 1 ) croak("pvm_recvf: comparison function must return only one scalar\n"); compare_val = POPi; PUTBACK ; FREETMPS ; LEAVE ; return compare_val; } static HV * derefHV( SV *node ) { HV *hv_tmp; if ( SvROK(node) ) { if ( SvTYPE(SvRV(node)) == SVt_PVHV ) { hv_tmp = (HV *)SvRV(node); return hv_tmp; } } return 0; } static int not_here(char *s) { croak("%s not implemented on this architecture", s); return -1; } static double constant(char *name, int arg) { /* This function is used for autoloading, no need to optimeze for speed. The ifdef stuff also makes not too much sense, because nobody will handle different name sets anyway. */ errno = 0; if (strEQ(name, "PVM_BYTE")) return PVM_BYTE; if (strEQ(name, "PVM_CPLX")) return PVM_CPLX; if (strEQ(name, "PVM_DCPLX")) return PVM_DCPLX; if (strEQ(name, "PVM_DOUBLE")) return PVM_DOUBLE; if (strEQ(name, "PVM_FLOAT")) return PVM_FLOAT; if (strEQ(name, "PVM_INT")) return PVM_INT; if (strEQ(name, "PVM_LONG")) return PVM_LONG; if (strEQ(name, "PVM_SHORT")) return PVM_SHORT; if (strEQ(name, "PVM_STR")) return PVM_STR; if (strEQ(name, "PVM_UINT")) return PVM_UINT; if (strEQ(name, "PVM_ULONG")) return PVM_ULONG; if (strEQ(name, "PVM_USHORT")) return PVM_USHORT; if (strEQ(name, "PvmAllowDirect")) return PvmAllowDirect; if (strEQ(name, "PvmAlready")) return PvmAlready; if (strEQ(name, "PvmAutoErr")) return PvmAutoErr; if (strEQ(name, "PvmBadMsg")) return PvmBadMsg; if (strEQ(name, "PvmBadParam")) return PvmBadParam; if (strEQ(name, "PvmBadVersion")) return PvmBadVersion; if (strEQ(name, "PvmCantStart")) return PvmCantStart; if (strEQ(name, "PvmDSysErr")) return PvmDSysErr; if (strEQ(name, "PvmDataDefault")) return PvmDataDefault; if (strEQ(name, "PvmDataFoo")) return PvmDataFoo; if (strEQ(name, "PvmDataInPlace")) return PvmDataInPlace; if (strEQ(name, "PvmDataRaw")) return PvmDataRaw; if (strEQ(name, "PvmDebugMask")) return PvmDebugMask; if (strEQ(name, "PvmDontRoute")) return PvmDontRoute; if (strEQ(name, "PvmDupEntry")) return PvmDupEntry; if (strEQ(name, "PvmDupGroup")) return PvmDupGroup; if (strEQ(name, "PvmDupHost")) return PvmDupHost; if (strEQ(name, "PvmFragSize")) return PvmFragSize; if (strEQ(name, "PvmHostAdd")) return PvmHostAdd; if (strEQ(name, "PvmHostCompl")) return PvmHostCompl; if (strEQ(name, "PvmHostDelete")) return PvmHostDelete; if (strEQ(name, "PvmHostFail")) return PvmHostFail; if (strEQ(name, "PvmMismatch")) return PvmMismatch; if (strEQ(name, "PvmMppFront")) return PvmMppFront; if (strEQ(name, "PvmNoBuf")) return PvmNoBuf; if (strEQ(name, "PvmNoData")) return PvmNoData; if (strEQ(name, "PvmNoEntry")) return PvmNoEntry; if (strEQ(name, "PvmNoFile")) return PvmNoFile; if (strEQ(name, "PvmNoGroup")) return PvmNoGroup; if (strEQ(name, "PvmNoHost")) return PvmNoHost; if (strEQ(name, "PvmNoInst")) return PvmNoInst; if (strEQ(name, "PvmNoMem")) return PvmNoMem; if (strEQ(name, "PvmNoParent")) return PvmNoParent; if (strEQ(name, "PvmNoSuchBuf")) return PvmNoSuchBuf; if (strEQ(name, "PvmNoTask")) return PvmNoTask; if (strEQ(name, "PvmNotImpl")) return PvmNotImpl; if (strEQ(name, "PvmNotInGroup")) return PvmNotInGroup; if (strEQ(name, "PvmNullGroup")) return PvmNullGroup; if (strEQ(name, "PvmOk")) return PvmOk; if (strEQ(name, "PvmOutOfRes")) return PvmOutOfRes; if (strEQ(name, "PvmOutputCode")) return PvmOutputCode; if (strEQ(name, "PvmOutputTid")) return PvmOutputTid; if (strEQ(name, "PvmOverflow")) return PvmOverflow; if (strEQ(name, "PvmPollConstant")) return PvmPollConstant; if (strEQ(name, "PvmPollSleep")) return PvmPollSleep; if (strEQ(name, "PvmPollTime")) return PvmPollTime; if (strEQ(name, "PvmPollType")) return PvmPollType; if (strEQ(name, "PvmResvTids")) return PvmResvTids; if (strEQ(name, "PvmRoute")) return PvmRoute; if (strEQ(name, "PvmRouteDirect")) return PvmRouteDirect; if (strEQ(name, "PvmSelfOutputCode")) return PvmSelfOutputCode; if (strEQ(name, "PvmSelfOutputTid")) return PvmSelfOutputTid; if (strEQ(name, "PvmSelfTraceCode")) return PvmSelfTraceCode; if (strEQ(name, "PvmSelfTraceTid")) return PvmSelfTraceTid; if (strEQ(name, "PvmShowTids")) return PvmShowTids; if (strEQ(name, "PvmSysErr")) return PvmSysErr; if (strEQ(name, "PvmTaskArch")) return PvmTaskArch; if (strEQ(name, "PvmTaskChild")) return PvmTaskChild; if (strEQ(name, "PvmTaskDebug")) return PvmTaskDebug; if (strEQ(name, "PvmTaskDefault")) return PvmTaskDefault; if (strEQ(name, "PvmTaskExit")) return PvmTaskExit; if (strEQ(name, "PvmTaskHost")) return PvmTaskHost; if (strEQ(name, "PvmTaskSelf")) return PvmTaskSelf; if (strEQ(name, "PvmTaskTrace")) return PvmTaskTrace; if (strEQ(name, "PvmTraceCode")) return PvmTraceCode; if (strEQ(name, "PvmTraceTid")) return PvmTraceTid; if (strEQ(name, "PvmMboxDefault")) return PvmMboxDefault; if (strEQ(name, "PvmMboxPersistent")) return PvmMboxPersistent; if (strEQ(name, "PvmMboxMultiInstance")) return PvmMboxMultiInstance; if (strEQ(name, "PvmMboxOverWritable")) return PvmMboxOverWritable; if (strEQ(name, "PvmMboxFirstAvail")) return PvmMboxFirstAvail; if (strEQ(name, "PvmMboxReadAndDelete")) return PvmMboxReadAndDelete; errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; } MODULE = Parallel::Pvm PACKAGE = Parallel::Pvm double constant(name,arg) char * name int arg PROTOTYPES: ENABLE void spawn(task,ntask,flag=PvmTaskDefault,where="",argvRef=0) char * task int ntask int flag char * where SV * argvRef PREINIT: int tids[MAXPROCS]; int info; int i; char ** argv = (char **)0; PPCODE: if (argvRef) { int argc; AV * av; SV ** a; if (!SvROK(argvRef)) croak("Parallel::Pvm::spawn - non-reference passed for argv"); av = (AV *) SvRV( argvRef ); argc = av_len( av ) + 1; /* number of elts in vector */ Newz( 0, argv, argc+1, char *); /* last one will be NULL */ for (i = 0; i < argc; i++) { if ( a = av_fetch( av, i, 0) ) argv[i] = (char *) SvPV( *a, PL_na ); } } info = pvm_spawn(task,argv,flag,where,ntask,tids); Safefree( argv ); /* no harm done if argv is NULL */ XPUSHs(sv_2mortal(newSViv(info))); for (i=0;i 1 ) { if ( items > MAXARGS ) croak("Warning: too many arguments. Try increasing MAXARGS"); for(i=1;i 2 and therefore in > buf */ RETVAL = pvm_psend(tid,tag,buf,buflen,PVM_BYTE); Safefree(buf); OUTPUT: RETVAL int mcast(...) PREINIT: int i; int tag_num; int proc_num; int tids[MAXPROCS]; int tag; CODE: if ( items < 2 ) croak("Usage: Parallel::Pvm::pvm_mcast(tids_list,tag)"); for (i=0;i 0 and therefore in > buf */ RETVAL = pvm_pkstr(buf); Safefree(buf); OUTPUT: RETVAL void unpack(buflen=MAXSTR) int buflen PREINIT: char *buf, *po; int type; PPCODE: New(2401, buf, buflen, char); if (pvm_upkstr(buf) != 0) { if (PL_dowarn) { warn("pvm_upkstr failed"); Safefree(buf); XSRETURN_UNDEF; } } po = strtok(buf,"\v"); while ( po != NULL ) { /* Change: Everything is a string * sn@neopoly.com Fri Feb 9 13:41:46 CET 2001 */ XPUSHs(sv_2mortal(newSVpv(po,0))); po = strtok(NULL,"\v"); } Safefree(buf); int pvm_exit() int pvm_halt() int pvm_catchout(io=stdout) FILE * io void tasks(where=0) int where PREINIT: int ntask,i,info; struct pvmtaskinfo *taskp; int ti_tid,ti_ptid,ti_host,ti_flag,ti_pid; char ti_a_out[256]; HV *hv_tmp; PPCODE: info = pvm_tasks(where,&ntask,&taskp); XPUSHs(sv_2mortal(newSViv(info))); if (info >= 0) /* ntask may be undefined if there was an error */ for(i=0;i