dnl (c)INRIA 1999 Christophe.Lavarenne@inria.fr dnl $Id: TCP.m4x,v 1.1 2000/04/17 13:02:26 lavarenn Exp $ divert(-1) # SynDEx v5 generic executive kernel, customization for TCP communications ifdef(`syndex.m4x_already_included',,`errprint( __file__:__line__: m4: syndex.m4x must be included before __file__! )m4exit(1)') ifelse(lang_,`C',,`error_(`lang_=C expected, not lang_='lang_)m4exit(1)') ifdef( __file__`_already_included',`error_(`already included')m4exit(1)', `define(__file__`_already_included')') # ----------------------------------------------------------------------------- # This file defines all TARGET MEDIA DEPENDENT macros (prefixed by ) # which customize the generic executive macros defined in the syndex.m4x file. # SynDEx generates for each processor one macro-executive file starting with a # `processor_' macro taking as argument the processor type, which is stored in # the `processorType_' macro, and used to include the processorType_.m4x file. # Moreover each communication sequence starts with a `thread_' macro taking as # argument the communication media type, which is stored in the `mediaType_' # macro, and used to include the mediaType_.m4x file. # Test have been successfully done with gcc on the following architectures: # PC hosttype=i386 under Linux(2.0.36 POSIX) # SUN hosttype=sun4 under Solaris(5.6) # DEC hosttype=alpha under OSF1(V4.0) # ?SGI hosttype=iris4d under IRIX(6.2) # ?HP hosttype=hp9000s700 under HP-UX(B.10.20 9000/780) # WARNING: # This Unix implementation uses "rsh" for the booting process, which requires # that each host accepts rsh from the booting host (SynDEx "root"); this is # usually done by adding a "rootHostName userLoginName" line in the # $HOME/.rhost file of each remote host. # WARNING: # This TCP implementation of interprocessor communications limits the number # of processor to the number of sockets that may be created for a process, # which is 64 on SUN, -3 for stdin, stdout and stderr, minus those needed # for i/o operations. # -------------------------------------------------------------------------- ######################## # COMMUNICATION SEQUENCE # ----------- # TCP_shared_(mediaName,procrNames) define(`TCP_shared_', `ifdef(`TCP_shared_done_',,`define(`TCP_shared_done_')dnl dnl `typedef struct {' opened by `semaphores_' indent_(-) } shmemory; /* end of shared data */ shmemory* sp; /* the mapped base address of the shared memory area */ /* support for workstations with different byte orders */ void brev4(int *data, int items) { /* b1b2b3b4 -> b4b3b2b1 */ do { *data = *data<<24 | *data<<8&0xff0000 | *data>>8&0xff00 | *data>>24&0xff; data++; } while(--items); } void brev8(int *data, int items) { /* 12345678 -> 78563412 */ do { int t = *data<<24 | *data<<8&0xff0000 | *data>>8&0xff00 | *data>>24&0xff; data++; data[-1] = *data<<24 | *data<<8&0xff0000 | *data>>8&0xff00 | *data>>24&0xff; *data++ = t; } while(--items); } #ifdef DEBUG #define INFO(x) printf x #else #define INFO(x) #endif #include /* for popen, pclose, sprintf */ #include /* for system */ #include /* for strcpy */ #include /* for everybody */ #include /* for gethostname and setsockopt */ #include /* for TCP_NODELAY */ #include /* for internet sockets */ #include /* for inet_addr and inet_ntoa */ #include /* for read and write */ ')') # procrIndex_(procrName) define(`procrIndex_', `lindex($1,shift(shift(threadArgs_)))') # -------- # TCP_ini_(mediaName,procrNames) define(`TCP_ini_', ` `#define' MYID procrIndex_(processorName_) /* my index on $1 bus */ `#define' NHOSTS eval($#-1) /* number of procrs connected on $1 bus */ int sd[NHOSTS]; /* socket descriptors */ struct sockaddr_in saddr; /* socket address */ /* support for workstations with different byte orders */ `#define' BREVKEY 0x01234567 int brev[NHOSTS]; /* byte-reverse when different byte orders */ int len, n; char *pp; /* packet pointer */ int i, j; struct hostpnx { u_short port; /* TCP socket address */ char name[42]; /* internet hostname */ char exec[20]; /* executable filename */ };') define(`TCP_openListeningSocket_',` /* open a TCP socket for accepting connections */ sd[MYID] = socket(PF_INET, SOCK_STREAM, 0); saddr.sin_family = AF_INET; saddr.sin_port = 0; /* let the system allocate a TCP port */ saddr.sin_addr.s_addr = INADDR_ANY; /* accept connexions from anywhere */ bind(sd[MYID], (struct sockaddr*)&saddr, sizeof(saddr)); listen(sd[MYID], 1); brev[MYID] = BREVKEY;') define(`TCP_closeListeningSocket_', ` for(i=0; ip_proto, n=1; i&2"); exit(-1); }dnl changequote]]changequote` } TCP_openListeningSocket_ /* retrieve the address of the listening TCP socket */ len = sizeof(saddr); getsockname(sd[MYID], (struct sockaddr*)&saddr, &len); host[MYID].port = saddr.sin_port; gethostname(host[MYID].name, sizeof(host[MYID].name)); for(i=0; i>> %s %d\n", host[i].name, ntohs(host[i].port))); } /* broadcast byte-orders */ for(i=0; ih_addr, (char*)&saddr.sin_addr.s_addr, sizeof(struct in_addr)); saddr.sin_port = htons(atoi(argv[2])); /* get root listening port */ saddr.sin_family = AF_INET; /* create a TCP socket and connect it to root */ sd[BOOTID] = socket(PF_INET, SOCK_STREAM, 0); connect(sd[BOOTID], (struct sockaddr*)&saddr, sizeof(saddr)); write(sd[BOOTID], (char*)(brev+MYID), 4); /* send my byte order */ for(i=0; ih_addr, (char*)&saddr.sin_addr.s_addr, sizeof(struct in_addr)); /* create a TCP socket and connect it to the server */ sd[i] = socket(PF_INET, SOCK_STREAM, 0); connect(sd[i], (struct sockaddr*)&saddr, sizeof(saddr)); } /* send to root my listening port address */ len = sizeof(saddr); getsockname(sd[MYID], (struct sockaddr*)&saddr, &len); write(sd[BOOTID], (char*)&saddr.sin_port, 2); /* accept connexions from my clients */ for(i=MYID+1; i