moved ulnds/socklnd.
+++ /dev/null
-This library implements two NAL interfaces, both running over IP.
-The first, tcpnal, creates TCP connections between participating
-processes in order to transport the portals requests. The second,
-ernal, provides a simple transport protocol which runs over
-UDP datagrams.
-
-The interface functions return both of these values in host order for
-convenience and readability. However this means that addresses
-exchanged in messages between hosts of different orderings will not
-function properly.
-
-Both NALs use the same support functions in order to schedule events
-and communicate with the generic portals implementation.
-
- -------------------------
- | api |
- |_______________________|
- | lib |
- |_______________________|
- | ernal | |tcpnal |
- |--------| |----------|
- | udpsock| |connection|
- |-----------------------|
- | timer/select |
- -------------------------
-
-
- These NALs uses the framework from fdnal of a pipe between the api
-and library sides. This is wrapped up in the select on the library
-side, and blocks on the api side. Performance could be severely
-enhanced by collapsing this aritificial barrier, by using shared
-memory queues, or by wiring the api layer directly to the library.
-
-
-nid is defined as the low order 24-bits of the IP address of the
-physical node left shifted by 8 plus a virtual node number of 0
-through 255 (really only 239). The virtual node number of a tcpnal
-application should be specified using the environment variable
-PTL_VIRTNODE. pid is now a completely arbitrary number in the
-range of 0 to 255. The IP interface used can be overridden by
-specifying the appropriate hostid by setting the PTL_HOSTID
-environment variable. The value can be either dotted decimal
-(n.n.n.n) or hex starting with "0x".
-TCPNAL:
- As the NAL needs to try to send to a particular nid/pid pair, it
- will open up connections on demand. Because the port associated with
- the connecting socket is different from the bound port, two
- connections will normally be established between a pair of peers, with
- data flowing from the anonymous connect (active) port to the advertised
- or well-known bound (passive) port of each peer.
-
- Should the connection fail to open, an error is reported to the
- library component, which causes the api request to fail.
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-#ifndef TCPNAL_PROCBRIDGE_H
-#define TCPNAL_PROCBRIDGE_H
-
-#include <lnet/lib-lnet.h>
-
-typedef struct bridge {
- int alive;
- ptl_ni_t *b_ni;
- void *lower;
- void *local;
- /* this doesn't really belong here */
- unsigned char iptop8;
-} *bridge;
-
-#endif
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* connection.c:
- This file provides a simple stateful connection manager which
- builds tcp connections on demand and leaves them open for
- future use.
-*/
-
-#include <stdlib.h>
-#include <pqtimer.h>
-#include <dispatch.h>
-#include <table.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <lnet/types.h>
-#include <lnet/lib-types.h>
-#include <lnet/socklnd.h>
-#include <libcfs/kp30.h>
-#include <connection.h>
-#include <pthread.h>
-#include <errno.h>
-#ifndef __CYGWIN__
-#include <syscall.h>
-#endif
-
-/* tunables (via environment) */
-int tcpnal_acceptor_port = 988;
-int tcpnal_buffer_size = 2 * (PTL_MTU + sizeof(ptl_hdr_t));
-int tcpnal_nagle = 0;
-
-int
-tcpnal_env_param (char *name, int *val)
-{
- char *env = getenv(name);
- int n;
-
- if (env == NULL)
- return 1;
-
- n = strlen(env); /* scanf may not assign on EOS */
- if (sscanf(env, "%i%n", val, &n) >= 1 &&
- n == strlen(env))
- return 1;
-
- CERROR("Can't parse environment variable '%s=%s'\n",
- name, env);
- return 0;
-}
-
-int
-tcpnal_set_global_params (void)
-{
- return tcpnal_env_param("TCPNAL_ACCEPTOR_PORT",
- &tcpnal_acceptor_port) &&
- tcpnal_env_param("TCPNAL_BUFFER_SIZE",
- &tcpnal_buffer_size) &&
- tcpnal_env_param("TCPNAL_NAGLE",
- &tcpnal_nagle);
-}
-
-/* Function: compare_connection
- * Arguments: connection c: a connection in the hash table
- * lnet_process_id_t: an id to verify agains
- * Returns: 1 if the connection is the one requested, 0 otherwise
- *
- * compare_connection() tests for collisions in the hash table
- */
-static int compare_connection(void *arg1, void *arg2)
-{
- connection c = arg1;
- lnet_nid_t *nid = arg2;
-
- return (c->peer_nid == *nid);
-}
-
-/* Function: connection_key
- * Arguments: lnet_process_id_t id: an id to hash
- * Returns: a not-particularily-well-distributed hash
- * of the id
- */
-static unsigned int connection_key(void *arg)
-{
- lnet_nid_t *nid = arg;
-
- return (unsigned int)(*nid);
-}
-
-void
-close_connection(void *arg)
-{
- connection c = arg;
-
- close(c->fd);
- free(c);
-}
-
-/* Function: remove_connection
- * Arguments: c: the connection to remove
- */
-void remove_connection(void *arg)
-{
- connection c = arg;
-
- hash_table_remove(c->m->connections,&c->peer_nid);
- close_connection(c);
-}
-
-
-/* Function: read_connection:
- * Arguments: c: the connection to read from
- * dest: the buffer to read into
- * len: the number of bytes to read
- * Returns: success as 1, or failure as 0
- *
- * read_connection() reads data from the connection, continuing
- * to read partial results until the request is satisfied or
- * it errors. TODO: this read should be covered by signal protection.
- */
-int read_connection(connection c,
- unsigned char *dest,
- int len)
-{
- int offset = 0,rc;
-
- if (len) {
- do {
-#ifndef __CYGWIN__
- rc = syscall(SYS_read, c->fd, dest+offset, len-offset);
-#else
- rc = recv(c->fd, dest+offset, len-offset, 0);
-#endif
- if (rc <= 0) {
- if (errno == EINTR) {
- rc = 0;
- } else {
- remove_connection(c);
- return (0);
- }
- }
- offset += rc;
- } while (offset < len);
- }
- return (1);
-}
-
-static int connection_input(void *d)
-{
- connection c = d;
- return((*c->m->handler)(c->m->handler_arg,c));
-}
-
-
-static connection
-allocate_connection(manager m,
- lnet_nid_t nid,
- int fd)
-{
- connection c=malloc(sizeof(struct connection));
-
- c->m=m;
- c->fd=fd;
- c->peer_nid = nid;
-
- register_io_handler(fd,READ_HANDLER,connection_input,c);
- hash_table_insert(m->connections,c,&nid);
- return(c);
-}
-
-int
-tcpnal_write(lnet_nid_t nid, int sockfd, void *buffer, int nob)
-{
- int rc = syscall(SYS_write, sockfd, buffer, nob);
-
- /* NB called on an 'empty' socket with huge buffering! */
- if (rc == nob)
- return 0;
-
- if (rc < 0) {
- CERROR("Failed to send to %s: %s\n",
- libcfs_nid2str(nid), strerror(errno));
- return -1;
- }
-
- CERROR("Short send to %s: %d/%d\n",
- libcfs_nid2str(nid), rc, nob);
- return -1;
-}
-
-int
-tcpnal_read(lnet_nid_t nid, int sockfd, void *buffer, int nob)
-{
- int rc;
-
- while (nob > 0) {
- rc = syscall(SYS_read, sockfd, buffer, nob);
-
- if (rc == 0) {
- CERROR("Unexpected EOF from %s\n",
- libcfs_nid2str(nid));
- return -1;
- }
-
- if (rc < 0) {
- CERROR("Failed to receive from %s: %s\n",
- libcfs_nid2str(nid), strerror(errno));
- return -1;
- }
-
- nob -= rc;
- }
- return 0;
-}
-
-int
-tcpnal_hello (int sockfd, lnet_nid_t nid)
-{
- struct timeval tv;
- __u64 incarnation;
- int rc;
- int nob;
- lnet_acceptor_connreq_t cr;
- ptl_hdr_t hdr;
- ptl_magicversion_t hmv;
-
- gettimeofday(&tv, NULL);
- incarnation = (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
-
- memset(&cr, 0, sizeof(cr));
- cr.acr_magic = PTL_PROTO_ACCEPTOR_MAGIC;
- cr.acr_version = PTL_PROTO_ACCEPTOR_VERSION;
- cr.acr_nid = nid;
-
- /* hmv initialised and copied separately into hdr; compiler "optimize"
- * likely due to confusion about pointer alias of hmv and hdr when this
- * was done in-place. */
- hmv.magic = cpu_to_le32(PTL_PROTO_TCP_MAGIC);
- hmv.version_major = cpu_to_le32(PTL_PROTO_TCP_VERSION_MAJOR);
- hmv.version_minor = cpu_to_le32(PTL_PROTO_TCP_VERSION_MINOR);
-
- memset (&hdr, 0, sizeof (hdr));
-
- CLASSERT (sizeof (hmv) == sizeof (hdr.dest_nid));
- memcpy(&hdr.dest_nid, &hmv, sizeof(hmv));
-
- /* hdr.src_nid/src_pid are ignored at dest */
-
- hdr.type = cpu_to_le32(PTL_MSG_HELLO);
- hdr.msg.hello.type = cpu_to_le32(SOCKNAL_CONN_ANY);
- hdr.msg.hello.incarnation = cpu_to_le64(incarnation);
-
- /* I don't send any interface info */
-
- /* Assume sufficient socket buffering for these messages... */
- rc = tcpnal_write(nid, sockfd, &cr, sizeof(cr));
- if (rc != 0)
- return -1;
-
- rc = tcpnal_write(nid, sockfd, &hdr, sizeof(hdr));
- if (rc != 0)
- return -1;
-
- rc = tcpnal_read(nid, sockfd, &hmv, sizeof(hmv));
- if (rc != 0)
- return -1;
-
- if (hmv.magic != le32_to_cpu(PTL_PROTO_TCP_MAGIC)) {
- CERROR ("Bad magic %#08x (%#08x expected) from %s\n",
- cpu_to_le32(hmv.magic), PTL_PROTO_TCP_MAGIC,
- libcfs_nid2str(nid));
- return -1;
- }
-
- if (hmv.version_major != cpu_to_le16 (PTL_PROTO_TCP_VERSION_MAJOR) ||
- hmv.version_minor != cpu_to_le16 (PTL_PROTO_TCP_VERSION_MINOR)) {
- CERROR ("Incompatible protocol version %d.%d (%d.%d expected)"
- " from %s\n",
- le16_to_cpu (hmv.version_major),
- le16_to_cpu (hmv.version_minor),
- PTL_PROTO_TCP_VERSION_MAJOR,
- PTL_PROTO_TCP_VERSION_MINOR,
- libcfs_nid2str(nid));
- return -1;
- }
-
-#if (PTL_PROTO_TCP_VERSION_MAJOR != 1)
-# error "This code only understands protocol version 1.x"
-#endif
- /* version 1 sends magic/version as the dest_nid of a 'hello' header,
- * so read the rest of it in now... */
-
- rc = tcpnal_read(nid, sockfd, ((char *)&hdr) + sizeof (hmv),
- sizeof(hdr) - sizeof(hmv));
- if (rc != 0)
- return -1;
-
- /* ...and check we got what we expected */
- if (hdr.type != cpu_to_le32 (PTL_MSG_HELLO)) {
- CERROR ("Expecting a HELLO hdr "
- " but got type %d with %d payload from %s\n",
- le32_to_cpu (hdr.type),
- le32_to_cpu (hdr.payload_length), libcfs_nid2str(nid));
- return -1;
- }
-
- if (le64_to_cpu(hdr.src_nid) == LNET_NID_ANY) {
- CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY\n");
- return -1;
- }
-
- if (nid != le64_to_cpu (hdr.src_nid)) {
- CERROR ("Connected to %s, but expecting %s\n",
- libcfs_nid2str(le64_to_cpu (hdr.src_nid)),
- libcfs_nid2str(nid));
- return -1;
- }
-
- /* Ignore any interface info in the payload */
- nob = le32_to_cpu(hdr.payload_length);
- if (nob != 0) {
- CERROR("Unexpected HELLO payload %d from %s\n",
- nob, libcfs_nid2str(nid));
- return -1;
- }
-
- return 0;
-}
-
-/* Function: force_tcp_connection
- * Arguments: t: tcpnal
- * dest: portals endpoint for the connection
- * Returns: an allocated connection structure, either
- * a pre-existing one, or a new connection
- */
-connection force_tcp_connection(manager m,
- lnet_nid_t nid,
- procbridge pb)
-{
- unsigned int ip = PTL_NIDADDR(nid);
- connection conn;
- struct sockaddr_in addr;
- struct sockaddr_in locaddr;
- int fd;
- int option;
- int rc;
-
- pthread_mutex_lock(&m->conn_lock);
-
- conn = hash_table_find(m->connections, &nid);
- if (conn)
- goto out;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(ip);
- addr.sin_port = htons(tcpnal_acceptor_port);
-
- memset(&locaddr, 0, sizeof(locaddr));
- locaddr.sin_family = AF_INET;
- locaddr.sin_addr.s_addr = INADDR_ANY;
-
-#if 1 /* tcpnal connects from a non-privileged port */
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("tcpnal socket failed");
- goto out;
- }
-
- option = 1;
- rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- &option, sizeof(option));
- if (rc != 0) {
- perror ("Can't set SO_REUSEADDR for socket");
- close(fd);
- goto out;
- }
-
- rc = connect(fd, (struct sockaddr *)&addr,
- sizeof(struct sockaddr_in));
- if (rc != 0) {
- perror("Error connecting to remote host");
- close(fd);
- goto out;
- }
-#else
- for (rport = IPPORT_RESERVED - 1; rport > IPPORT_RESERVED / 2; --rport) {
- fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("tcpnal socket failed");
- goto out;
- }
-
- option = 1;
- rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- &option, sizeof(option));
- if (rc != 0) {
- perror ("Can't set SO_REUSEADDR for socket");
- close(fd);
- goto out;
- }
-
- locaddr.sin_port = htons(rport);
- rc = bind(fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
- if (rc == 0 || errno == EACCES) {
- rc = connect(fd, (struct sockaddr *)&addr,
- sizeof(struct sockaddr_in));
- if (rc == 0) {
- break;
- } else if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
- perror("Error connecting to remote host");
- close(fd);
- goto out;
- }
- } else if (errno != EADDRINUSE) {
- perror("Error binding to privileged port");
- close(fd);
- goto out;
- }
- close(fd);
- }
-
- if (rport == IPPORT_RESERVED / 2) {
- fprintf(stderr, "Out of ports trying to bind to a reserved port\n");
- goto out;
- }
-#endif
-
- option = tcpnal_nagle ? 0 : 1;
- setsockopt(fd, SOL_TCP, TCP_NODELAY, &option, sizeof(option));
- option = tcpnal_buffer_size;
- setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
- option = tcpnal_buffer_size;
- setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
-
- /* say hello */
- if (tcpnal_hello(fd, nid))
- goto out;
-
- conn = allocate_connection(m, nid, fd);
-
- /* let nal thread know this event right away */
- if (conn)
- procbridge_wakeup_nal(pb);
-
-out:
- pthread_mutex_unlock(&m->conn_lock);
- return (conn);
-}
-
-
-#if 0 /* we don't accept connections */
-/* Function: new_connection
- * Arguments: t: opaque argument holding the tcpname
- * Returns: 1 in order to reregister for new connection requests
- *
- * called when the bound service socket recieves
- * a new connection request, it always accepts and
- * installs a new connection
- */
-static int new_connection(void *z)
-{
- manager m=z;
- struct sockaddr_in s;
- int len=sizeof(struct sockaddr_in);
- int fd=accept(m->bound,(struct sockaddr *)&s,&len);
- unsigned int nid=*((unsigned int *)&s.sin_addr);
- /* cfs specific hack */
- //unsigned short pid=s.sin_port;
- pthread_mutex_lock(&m->conn_lock);
- allocate_connection(m,htonl(nid),0/*pid*/,fd);
- pthread_mutex_unlock(&m->conn_lock);
- return(1);
-}
-
-/* Function: bind_socket
- * Arguments: t: the nal state for this interface
- * port: the port to attempt to bind to
- * Returns: 1 on success, or 0 on error
- *
- * bind_socket() attempts to allocate and bind a socket to the requested
- * port, or dynamically assign one from the kernel should the port be
- * zero. Sets the bound and bound_handler elements of m.
- *
- * TODO: The port should be an explicitly sized type.
- */
-static int bind_socket(manager m,unsigned short port)
-{
- struct sockaddr_in addr;
- int alen=sizeof(struct sockaddr_in);
-
- if ((m->bound = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return(0);
-
- bzero((char *) &addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = 0;
- addr.sin_port = htons(port);
-
- if (bind(m->bound,(struct sockaddr *)&addr,alen)<0){
- perror ("tcpnal bind");
- return(0);
- }
-
- getsockname(m->bound,(struct sockaddr *)&addr, &alen);
-
- m->bound_handler=register_io_handler(m->bound,READ_HANDLER,
- new_connection,m);
- listen(m->bound,5);
- m->port=addr.sin_port;
- return(1);
-}
-#endif
-
-
-/* Function: shutdown_connections
- * Arguments: m: the manager structure
- *
- * close all connections and reclaim resources
- */
-void shutdown_connections(manager m)
-{
-#if 0
- /* we don't accept connections */
- close(m->bound);
- remove_io_handler(m->bound_handler);
-#endif
- hash_destroy_table(m->connections,close_connection);
- free(m);
-}
-
-
-/* Function: init_connections
- * Arguments: t: the nal state for this interface
- * Returns: a newly allocated manager structure, or
- * zero if the fixed port could not be bound
- */
-manager init_connections(int (*input)(void *, void *), void *a)
-{
- manager m = (manager)malloc(sizeof(struct manager));
-
- m->connections = hash_create_table(compare_connection,connection_key);
- m->handler = input;
- m->handler_arg = a;
- pthread_mutex_init(&m->conn_lock, 0);
-
- return m;
-#if 0
- if (bind_socket(m,pid))
- return(m);
-
- free(m);
- return(0);
-#endif
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-#include <table.h>
-#include <procbridge.h>
-
-typedef struct manager {
- table connections;
- pthread_mutex_t conn_lock; /* protect connections table */
-#if 0 /* we don't accept connections */
- int bound;
- io_handler bound_handler;
-#endif
- int (*handler)(void *, void *);
- void *handler_arg;
- unsigned short port;
-} *manager;
-
-
-typedef struct connection {
- lnet_nid_t peer_nid;
- int fd;
- manager m;
-} *connection;
-
-connection force_tcp_connection(manager m, lnet_nid_t nid, procbridge pb);
-manager init_connections(int (*f)(void *, void *), void *);
-void remove_connection(void *arg);
-void shutdown_connections(manager m);
-int read_connection(connection c, unsigned char *dest, int len);
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- * Author: Phil Schwan <phil@clusterfs.com>
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/time.h>
-#include <libcfs/libcfs.h>
-
-int smp_processor_id = 1;
-char debug_file_path[1024] = "/tmp/lustre-log";
-char debug_file_name[1024];
-FILE *debug_file_fd;
-
-int portals_do_debug_dumplog(void *arg)
-{
- printf("Look in %s\n", debug_file_name);
- return 0;
-}
-
-
-void portals_debug_print(void)
-{
- return;
-}
-
-
-void libcfs_debug_dumplog(void)
-{
- printf("Look in %s\n", debug_file_name);
- return;
-}
-
-
-int portals_debug_init(unsigned long bufsize)
-{
- debug_file_fd = stdout;
- return 0;
-}
-
-int portals_debug_cleanup(void)
-{
- return 0; //close(portals_debug_fd);
-}
-
-int portals_debug_clear_buffer(void)
-{
- return 0;
-}
-
-int portals_debug_mark_buffer(char *text)
-{
-
- fprintf(debug_file_fd, "*******************************************************************************\n");
- fprintf(debug_file_fd, "DEBUG MARKER: %s\n", text);
- fprintf(debug_file_fd, "*******************************************************************************\n");
-
- return 0;
-}
-
-int portals_debug_copy_to_user(char *buf, unsigned long len)
-{
- return 0;
-}
-
-/* FIXME: I'm not very smart; someone smarter should make this better. */
-void
-libcfs_debug_msg (int subsys, int mask, char *file, const char *fn,
- const int line, unsigned long stack, char *format, ...)
-{
- va_list ap;
- unsigned long flags;
- struct timeval tv;
- int nob;
-
-
- /* NB since we pass a non-zero sized buffer (at least) on the first
- * print, we can be assured that by the end of all the snprinting,
- * we _do_ have a terminated buffer, even if our message got truncated.
- */
-
- gettimeofday(&tv, NULL);
-
- nob += fprintf(debug_file_fd,
- "%02x:%06x:%d:%lu.%06lu ",
- subsys >> 24, mask, smp_processor_id,
- tv.tv_sec, tv.tv_usec);
-
- nob += fprintf(debug_file_fd,
- "(%s:%d:%s() %d+%ld): ",
- file, line, fn, 0,
- 8192 - ((unsigned long)&flags & 8191UL));
-
- va_start (ap, format);
- nob += fprintf(debug_file_fd, format, ap);
- va_end (ap);
-
-
-}
-
-void
-libcfs_assertion_failed(char *expr, char *file, const char *func,
- const int line)
-{
- libcfs_debug_msg(0, D_EMERG, file, func, line, 0,
- "ASSERTION(%s) failed\n", expr);
- abort();
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-/* this file is only called dispatch.h to prevent it
- from colliding with /usr/include/sys/select.h */
-
-typedef struct io_handler *io_handler;
-
-struct io_handler{
- io_handler *last;
- io_handler next;
- int fd;
- int type;
- int (*function)(void *);
- void *argument;
- int disabled;
-};
-
-
-#define READ_HANDLER 1
-#define WRITE_HANDLER 2
-#define EXCEPTION_HANDLER 4
-#define ALL_HANDLER (READ_HANDLER | WRITE_HANDLER | EXCEPTION_HANDLER)
-
-io_handler register_io_handler(int fd,
- int type,
- int (*function)(void *),
- void *arg);
-
-void remove_io_handler (io_handler i);
-void init_unix_timer(void);
-void select_timer_block(when until);
-when now(void);
-
-/*
- * hacking for CFS internal MPI testing
- */
-#define ENABLE_SELECT_DISPATCH
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* timer.c:
- * this file implements a simple priority-queue based timer system. when
- * combined with a file which implements now() and block(), it can
- * be used to provide course-grained time-based callbacks.
- */
-
-#include <pqtimer.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct timer {
- void (*function)(void *);
- void *arg;
- when w;
- int interval;
- int disable;
-};
-
-typedef struct thunk *thunk;
-struct thunk {
- void (*f)(void *);
- void *a;
- thunk next;
-};
-
-extern when now(void);
-
-static thunk thunks;
-static int internal;
-static void (*block_function)(when);
-static int number_of_timers;
-static int size_of_pqueue;
-static timer *timers;
-
-
-static void heal(int where)
-{
- int left=(where<<1);
- int right=(where<<1)+1;
- int min=where;
- timer temp;
-
- if (left <= number_of_timers)
- if (timers[left]->w < timers[min]->w) min=left;
- if (right <= number_of_timers)
- if (timers[right]->w < timers[min]->w) min=right;
- if (min != where){
- temp=timers[where];
- timers[where]=timers[min];
- timers[min]=temp;
- heal(min);
- }
-}
-
-static void add_pqueue(int i)
-{
- timer temp;
- int parent=(i>>1);
- if ((i>1) && (timers[i]->w< timers[parent]->w)){
- temp=timers[i];
- timers[i]=timers[parent];
- timers[parent]=temp;
- add_pqueue(parent);
- }
-}
-
-static void add_timer(timer t)
-{
- if (size_of_pqueue<(number_of_timers+2)){
- int oldsize=size_of_pqueue;
- timer *new=(void *)malloc(sizeof(struct timer)*(size_of_pqueue+=10));
- memcpy(new,timers,sizeof(timer)*oldsize);
- timers=new;
- }
- timers[++number_of_timers]=t;
- add_pqueue(number_of_timers);
-}
-
-/* Function: register_timer
- * Arguments: interval: the time interval from the current time when
- * the timer function should be called
- * function: the function to call when the time has expired
- * argument: the argument to call it with.
- * Returns: a pointer to a timer structure
- */
-timer register_timer(when interval,
- void (*function)(void *),
- void *argument)
-{
- timer t=(timer)malloc(sizeof(struct timer));
-
- t->arg=argument;
- t->function=function;
- t->interval=interval;
- t->disable=0;
- t->w=now()+interval;
- add_timer(t);
- if (!internal && (number_of_timers==1))
- block_function(t->w);
- return(t);
-}
-
-/* Function: remove_timer
- * Arguments: t:
- * Returns: nothing
- *
- * remove_timer removes a timer from the system, insuring
- * that it will never be called. It does not actually
- * free the timer due to reentrancy issues.
- */
-
-void remove_timer(timer t)
-{
- t->disable=1;
-}
-
-
-
-void timer_fire()
-{
- timer current;
-
- current=timers[1];
- timers[1]=timers[number_of_timers--];
- heal(1);
- if (!current->disable) {
- (*current->function)(current->arg);
- }
- free(current);
-}
-
-when next_timer(void)
-{
- when here=now();
-
- while (number_of_timers && (timers[1]->w <= here)) timer_fire();
- if (number_of_timers) return(timers[1]->w);
- return(0);
-}
-
-/* Function: timer_loop
- * Arguments: none
- * Returns: never
- *
- * timer_loop() is the blocking dispatch function for the timer.
- * Is calls the block() function registered with init_timer,
- * and handles associated with timers that have been registered.
- */
-void timer_loop()
-{
- when here;
-
- while (1){
- thunk z;
- here=now();
-
- for (z=thunks;z;z=z->next) (*z->f)(z->a);
-
- if (number_of_timers){
- if (timers[1]->w > here){
- (*block_function)(timers[1]->w);
- } else {
- timer_fire();
- }
- } else {
- thunk z;
- for (z=thunks;z;z=z->next) (*z->f)(z->a);
- (*block_function)(0);
- }
- }
-}
-
-
-/* Function: register_thunk
- * Arguments: f: the function to call
- * a: the single argument to call it with
- *
- * Thunk functions get called at irregular intervals, they
- * should not assume when, or take a particularily long
- * amount of time. Thunks are for background cleanup tasks.
- */
-void register_thunk(void (*f)(void *),void *a)
-{
- thunk t=(void *)malloc(sizeof(struct thunk));
- t->f=f;
- t->a=a;
- t->next=thunks;
- thunks=t;
-}
-
-/* Function: initialize_timer
- * Arguments: block: the function to call to block for the specified interval
- *
- * initialize_timer() must be called before any other timer function,
- * including timer_loop.
- */
-void initialize_timer(void (*block)(when))
-{
- block_function=block;
- number_of_timers=0;
- size_of_pqueue=10;
- timers=(timer *)malloc(sizeof(timer)*size_of_pqueue);
- thunks=0;
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-typedef unsigned long long when;
-when now(void);
-typedef struct timer *timer;
-timer register_timer(when interval,
- void (*function)(void *),
- void *argument);
-timer register_timer_wait(void);
-void remove_timer(timer);
-void timer_loop(void);
-void initialize_timer(void (*block)(when));
-void timer_fire(void);
-
-
-#define HZ 0x100000000ull
-
-
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2003 Cluster File Systems, Inc.
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* api.c:
- * This file provides the 'api' side for the process-based nals.
- * it is responsible for creating the 'library' side thread,
- * and passing wrapped portals transactions to it.
- *
- * Along with initialization, shutdown, and transport to the library
- * side, this file contains some stubs to satisfy the nal definition.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#ifndef __CYGWIN__
-# include <syscall.h>
-#endif
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <procbridge.h>
-#include <pqtimer.h>
-#include <dispatch.h>
-#include <errno.h>
-#ifdef HAVE_GETHOSTBYNAME
-# include <sys/utsname.h>
-#endif
-
-/* XXX CFS workaround, to give a chance to let nal thread wake up
- * from waiting in select
- */
-static int procbridge_notifier_handler(void *arg)
-{
- static char buf[8];
- procbridge p = (procbridge) arg;
-
- syscall(SYS_read, p->notifier[1], buf, sizeof(buf));
- return 1;
-}
-
-void procbridge_wakeup_nal(procbridge p)
-{
- static char buf[8];
- syscall(SYS_write, p->notifier[0], buf, sizeof(buf));
-}
-
-ptl_nal_t tcpnal_nal = {
- .nal_type = SOCKNAL,
- .nal_startup = procbridge_startup,
- .nal_shutdown = procbridge_shutdown,
- .nal_send = tcpnal_send,
- .nal_recv = tcpnal_recv,
-};
-int tcpnal_running;
-
-/* Function: shutdown
- * Arguments: ni: the instance of me
- *
- * cleanup nal state, reclaim the lower side thread and
- * its state using PTL_FINI codepoint
- */
-void
-procbridge_shutdown(ptl_ni_t *ni)
-{
- bridge b=(bridge)ni->ni_data;
- procbridge p=(procbridge)b->local;
-
- p->nal_flags |= NAL_FLAG_STOPPING;
- procbridge_wakeup_nal(p);
-
- do {
- pthread_mutex_lock(&p->mutex);
- if (p->nal_flags & NAL_FLAG_STOPPED) {
- pthread_mutex_unlock(&p->mutex);
- break;
- }
- pthread_cond_wait(&p->cond, &p->mutex);
- pthread_mutex_unlock(&p->mutex);
- } while (1);
-
- free(p);
- tcpnal_running = 0;
-}
-
-#ifdef ENABLE_SELECT_DISPATCH
-procbridge __global_procbridge = NULL;
-#endif
-
-/* Function: procbridge_startup
- *
- * Arguments: ni: the instance of me
- * interfaces: ignored
- *
- * Returns: portals rc
- *
- * initializes the tcp nal. we define unix_failure as an
- * error wrapper to cut down clutter.
- */
-int
-procbridge_startup (ptl_ni_t *ni)
-{
- procbridge p;
- bridge b;
- int rc;
-
- /* NB The local NID is not assigned. We only ever connect to the socknal,
- * which assigns the src nid/pid on incoming non-privileged connections
- * (i.e. us), and we don't accept connections. */
-
- LASSERT (ni->ni_nal == &tcpnal_nal);
- LASSERT (!tcpnal_running); /* only single instance supported */
- LASSERT (ni->ni_interfaces[0] == NULL); /* explicit interface(s) not supported */
-
- init_unix_timer();
-
- b=(bridge)malloc(sizeof(struct bridge));
- p=(procbridge)malloc(sizeof(struct procbridge));
- b->local=p;
- b->b_ni = ni;
- ni->ni_data = b;
-
- /* init procbridge */
- pthread_mutex_init(&p->mutex,0);
- pthread_cond_init(&p->cond, 0);
- p->nal_flags = 0;
-
- /* initialize notifier */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, p->notifier)) {
- perror("socketpair failed");
- rc = -errno;
- return rc;
- }
-
- if (!register_io_handler(p->notifier[1], READ_HANDLER,
- procbridge_notifier_handler, p)) {
- perror("fail to register notifier handler");
- return -ENOMEM;
- }
-
-#ifdef ENABLE_SELECT_DISPATCH
- __global_procbridge = p;
-#endif
-
- /* create nal thread */
- rc = pthread_create(&p->t, NULL, nal_thread, b);
- if (rc != 0) {
- perror("nal_init: pthread_create");
- return -ESRCH;
- }
-
- do {
- pthread_mutex_lock(&p->mutex);
- if (p->nal_flags & (NAL_FLAG_RUNNING | NAL_FLAG_STOPPED)) {
- pthread_mutex_unlock(&p->mutex);
- break;
- }
- pthread_cond_wait(&p->cond, &p->mutex);
- pthread_mutex_unlock(&p->mutex);
- } while (1);
-
- if (p->nal_flags & NAL_FLAG_STOPPED)
- return -ENETDOWN;
-
- tcpnal_running = 1;
-
- return 0;
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2003 Cluster File Systems, Inc.
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-#ifndef _PROCBRIDGE_H_
-#define _PROCBRIDGE_H_
-
-#include <pthread.h>
-#include <bridge.h>
-
-
-#define NAL_FLAG_RUNNING 1
-#define NAL_FLAG_STOPPING 2
-#define NAL_FLAG_STOPPED 4
-
-typedef struct procbridge {
- /* sync between user threads and nal thread */
- pthread_t t;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-
- /* socket pair used to notify nal thread */
- int notifier[2];
-
- int nal_flags;
-
-} *procbridge;
-
-typedef struct nal_init_args {
- lnet_pid_t nia_requested_pid;
- bridge nia_bridge;
-} nal_init_args_t;
-
-extern void *nal_thread(void *);
-
-extern void procbridge_wakeup_nal(procbridge p);
-
-extern int procbridge_startup (ptl_ni_t *);
-extern void procbridge_shutdown (ptl_ni_t *);
-
-extern int tcpnal_send(ptl_ni_t *ni, void *private, ptl_msg_t *cookie,
- ptl_hdr_t *hdr, int type, lnet_process_id_t target,
- int routing, unsigned int niov, struct iovec *iov,
- size_t offset, size_t len);
-int tcpnal_recv(ptl_ni_t *ni, void *private, ptl_msg_t *cookie,
- unsigned int niov, struct iovec *iov,
- size_t offset, size_t mlen, size_t rlen);
-
-
-
-
-#endif
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2003 Cluster File Systems, Inc.
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* lib.c:
- * This file provides the 'library' side for the process-based nals.
- * it is responsible for communication with the 'api' side and
- * providing service to the generic portals 'library'
- * implementation. 'library' might be better termed 'communication'
- * or 'kernel'.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <procbridge.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <errno.h>
-#include <timer.h>
-#include <dispatch.h>
-
-/* the following functions are stubs to satisfy the nal definition
- without doing anything particularily useful*/
-extern int tcpnal_init(bridge);
-extern void tcpnal_shutdown(bridge);
-
-static void check_stopping(void *z)
-{
- bridge b = z;
- procbridge p = b->local;
-
- if ((p->nal_flags & NAL_FLAG_STOPPING) == 0)
- return;
-
- tcpnal_shutdown(b);
-
- pthread_mutex_lock(&p->mutex);
- p->nal_flags |= NAL_FLAG_STOPPED;
- pthread_cond_broadcast(&p->cond);
- pthread_mutex_unlock(&p->mutex);
-
- pthread_exit(0);
-}
-
-
-/* Function: nal_thread
- * Arguments: z: an opaque reference to a nal control structure
- * allocated and partially populated by the api level code
- * Returns: nothing, and only on error or explicit shutdown
- *
- * This function is the entry point of the pthread initiated on
- * the api side of the interface. This thread is used to handle
- * asynchronous delivery to the application.
- *
- * We define a limit macro to place a ceiling on limits
- * for syntactic convenience
- */
-
-void *nal_thread(void *z)
-{
- bridge b = (bridge) z;
- procbridge p=b->local;
- int rc;
-
- rc = tcpnal_init(b);
-
- /*
- * Whatever the initialization returned is passed back to the
- * user level code for further interpretation. We just exit if
- * it is non-zero since something went wrong.
- */
-
- pthread_mutex_lock(&p->mutex);
- p->nal_flags |= (rc != 0) ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
- pthread_cond_broadcast(&p->cond);
- pthread_mutex_unlock(&p->mutex);
-
- if (rc == 0) {
- /* the thunk function is called each time the timer loop
- performs an operation and returns to blocking mode. we
- overload this function to inform the api side that
- it may be interested in looking at the event queue */
- register_thunk(check_stopping,b);
- timer_loop();
- }
- return(0);
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* select.c:
- * Provides a general mechanism for registering and dispatching
- * io events through the select system call.
- */
-
-#define DEBUG_SUBSYSTEM S_NAL
-
-#ifdef sun
-#include <sys/filio.h>
-#else
-#include <sys/ioctl.h>
-#endif
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <syscall.h>
-#include <pthread.h>
-#include <errno.h>
-#include <pqtimer.h>
-#include <dispatch.h>
-#include <procbridge.h>
-
-
-static struct timeval beginning_of_epoch;
-static io_handler io_handlers;
-
-/* Function: now
- *
- * Return: the current time in canonical units: a 64 bit number
- * where the most significant 32 bits contains the number
- * of seconds, and the least signficant a count of (1/(2^32))ths
- * of a second.
- */
-when now()
-{
- struct timeval result;
-
- gettimeofday(&result,0);
- return((((unsigned long long)result.tv_sec)<<32)|
- (((unsigned long long)result.tv_usec)<<32)/1000000);
-}
-
-
-/* Function: register_io_handler
- * Arguments: fd: the file descriptor of interest
- * type: a mask of READ_HANDLER, WRITE_HANDLER, EXCEPTION_HANDLER
- * function: a function to call when io is available on fd
- * arg: an opaque correlator to return to the handler
- * Returns: a pointer to the io_handler structure
- */
-io_handler register_io_handler(int fd,
- int type,
- int (*function)(void *),
- void *arg)
-{
- io_handler i=(io_handler)malloc(sizeof(struct io_handler));
- if ((i->fd=fd)>=0){
- i->type=type;
- i->function=function;
- i->argument=arg;
- i->disabled=0;
- i->last=&io_handlers;
- if ((i->next=io_handlers)) i->next->last=&i->next;
- io_handlers=i;
- }
- return(i);
-}
-
-/* Function: remove_io_handler
- * Arguments: i: a pointer to the handler to stop servicing
- *
- * remove_io_handler() doesn't actually free the handler, due
- * to reentrancy problems. it just marks the handler for
- * later cleanup by the blocking function.
- */
-void remove_io_handler (io_handler i)
-{
- i->disabled=1;
-}
-
-static void set_flag(io_handler n,fd_set *r, fd_set *w, fd_set *e)
-{
- if (n->type & READ_HANDLER) FD_SET(n->fd, r);
- if (n->type & WRITE_HANDLER) FD_SET(n->fd, w);
- if (n->type & EXCEPTION_HANDLER) FD_SET(n->fd, e);
-}
-
-static int prepare_fd_sets(fd_set *r, fd_set *w, fd_set *e)
-{
- io_handler j;
- io_handler *k;
- int max = 0;
-
- FD_ZERO(r);
- FD_ZERO(w);
- FD_ZERO(e);
- for (k=&io_handlers;*k;){
- if ((*k)->disabled){
- j=*k;
- *k=(*k)->next;
- free(j);
- }
- if (*k) {
- set_flag(*k,r,w,e);
- if ((*k)->fd > max)
- max = (*k)->fd;
- k=&(*k)->next;
- }
- }
- return max + 1;
-}
-
-static int execute_callbacks(fd_set *r, fd_set *w, fd_set *e)
-{
- io_handler j;
- int n = 0, t;
-
- for (j = io_handlers; j; j = j->next) {
- if (j->disabled)
- continue;
-
- t = 0;
- if (FD_ISSET(j->fd, r) && (j->type & READ_HANDLER)) {
- FD_CLR(j->fd, r);
- t++;
- }
- if (FD_ISSET(j->fd, w) && (j->type & WRITE_HANDLER)) {
- FD_CLR(j->fd, w);
- t++;
- }
- if (FD_ISSET(j->fd, e) && (j->type & EXCEPTION_HANDLER)) {
- FD_CLR(j->fd, e);
- t++;
- }
- if (t == 0)
- continue;
-
- if (!(*j->function)(j->argument))
- j->disabled = 1;
-
- n += t;
- }
-
- return n;
-}
-
-#ifdef ENABLE_SELECT_DISPATCH
-
-static struct {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int submitted;
- int nready;
- int maxfd;
- fd_set *rset;
- fd_set *wset;
- fd_set *eset;
- struct timeval *timeout;
- struct timeval submit_time;
-} fd_extra = {
- PTHREAD_MUTEX_INITIALIZER,
- PTHREAD_COND_INITIALIZER,
- 0, 0, 0,
- NULL, NULL, NULL, NULL,
-};
-
-extern int liblustre_wait_event(int timeout);
-extern procbridge __global_procbridge;
-
-/*
- * this will intercept syscall select() of user apps
- * such as MPI libs.
- */
-int select(int n, fd_set *rset, fd_set *wset, fd_set *eset,
- struct timeval *timeout)
-{
- LASSERT(fd_extra.submitted == 0);
-
- fd_extra.nready = 0;
- fd_extra.maxfd = n;
- fd_extra.rset = rset;
- fd_extra.wset = wset;
- fd_extra.eset = eset;
- fd_extra.timeout = timeout;
-
- liblustre_wait_event(0);
- pthread_mutex_lock(&fd_extra.mutex);
- gettimeofday(&fd_extra.submit_time, NULL);
- fd_extra.submitted = 1;
- LASSERT(__global_procbridge);
- procbridge_wakeup_nal(__global_procbridge);
-
-again:
- if (fd_extra.submitted)
- pthread_cond_wait(&fd_extra.cond, &fd_extra.mutex);
- pthread_mutex_unlock(&fd_extra.mutex);
-
- liblustre_wait_event(0);
-
- pthread_mutex_lock(&fd_extra.mutex);
- if (fd_extra.submitted)
- goto again;
- pthread_mutex_unlock(&fd_extra.mutex);
-
- LASSERT(fd_extra.nready >= 0);
- LASSERT(fd_extra.submitted == 0);
- return fd_extra.nready;
-}
-
-static int merge_fds(int max, fd_set *rset, fd_set *wset, fd_set *eset)
-{
- int i;
-
- LASSERT(rset);
- LASSERT(wset);
- LASSERT(eset);
-
- for (i = 0; i < __FD_SETSIZE/__NFDBITS; i++) {
- LASSERT(!fd_extra.rset ||
- !(__FDS_BITS(rset)[i] & __FDS_BITS(fd_extra.rset)[i]));
- LASSERT(!fd_extra.wset ||
- !(__FDS_BITS(wset)[i] & __FDS_BITS(fd_extra.wset)[i]));
- LASSERT(!fd_extra.eset ||
- !(__FDS_BITS(eset)[i] & __FDS_BITS(fd_extra.eset)[i]));
-
- if (fd_extra.rset && __FDS_BITS(fd_extra.rset)[i])
- __FDS_BITS(rset)[i] |= __FDS_BITS(fd_extra.rset)[i];
- if (fd_extra.wset && __FDS_BITS(fd_extra.wset)[i])
- __FDS_BITS(wset)[i] |= __FDS_BITS(fd_extra.wset)[i];
- if (fd_extra.eset && __FDS_BITS(fd_extra.eset)[i])
- __FDS_BITS(eset)[i] |= __FDS_BITS(fd_extra.eset)[i];
- }
-
- return (fd_extra.maxfd > max ? fd_extra.maxfd : max);
-}
-
-static inline
-int timeval_ge(struct timeval *tv1, struct timeval *tv2)
-{
- LASSERT(tv1 && tv2);
- return ((tv1->tv_sec - tv2->tv_sec) * 1000000 +
- (tv1->tv_usec - tv2->tv_usec) >= 0);
-}
-
-/*
- * choose the most recent timeout value
- */
-static struct timeval *choose_timeout(struct timeval *tv1,
- struct timeval *tv2)
-{
- if (!tv1)
- return tv2;
- else if (!tv2)
- return tv1;
-
- if (timeval_ge(tv1, tv2))
- return tv2;
- else
- return tv1;
-}
-
-/* Function: select_timer_block
- * Arguments: until: an absolute time when the select should return
- *
- * This function dispatches the various file descriptors' handler
- * functions, if the kernel indicates there is io available.
- */
-void select_timer_block(when until)
-{
- fd_set fds[3];
- struct timeval timeout;
- struct timeval *timeout_pointer, *select_timeout;
- int max, nready, nexec;
- int fd_handling;
-
-again:
- if (until) {
- when interval;
-
- interval = until - now();
- timeout.tv_sec = (interval >> 32);
- timeout.tv_usec = ((interval << 32) / 1000000) >> 32;
- timeout_pointer = &timeout;
- } else
- timeout_pointer = NULL;
-
- fd_handling = 0;
- max = prepare_fd_sets(&fds[0], &fds[1], &fds[2]);
- select_timeout = timeout_pointer;
-
- pthread_mutex_lock(&fd_extra.mutex);
- fd_handling = fd_extra.submitted;
- pthread_mutex_unlock(&fd_extra.mutex);
- if (fd_handling) {
- max = merge_fds(max, &fds[0], &fds[1], &fds[2]);
- select_timeout = choose_timeout(timeout_pointer, fd_extra.timeout);
- }
-
- /* XXX only compile for linux */
-#if __WORDSIZE == 64
- nready = syscall(SYS_select, max, &fds[0], &fds[1], &fds[2],
- select_timeout);
-#else
- nready = syscall(SYS__newselect, max, &fds[0], &fds[1], &fds[2],
- select_timeout);
-#endif
- if (nready < 0) {
- CERROR("select return err %d, errno %d\n", nready, errno);
- return;
- }
-
- if (nready) {
- nexec = execute_callbacks(&fds[0], &fds[1], &fds[2]);
- nready -= nexec;
- } else
- nexec = 0;
-
- /* even both nready & nexec are 0, we still need try to wakeup
- * upper thread since it may have timed out
- */
- if (fd_handling) {
- LASSERT(nready >= 0);
-
- pthread_mutex_lock(&fd_extra.mutex);
- if (nready) {
- if (fd_extra.rset)
- *fd_extra.rset = fds[0];
- if (fd_extra.wset)
- *fd_extra.wset = fds[1];
- if (fd_extra.eset)
- *fd_extra.eset = fds[2];
- fd_extra.nready = nready;
- fd_extra.submitted = 0;
- } else {
- struct timeval t;
-
- fd_extra.nready = 0;
- if (fd_extra.timeout) {
- gettimeofday(&t, NULL);
- if (timeval_ge(&t, &fd_extra.submit_time))
- fd_extra.submitted = 0;
- }
- }
-
- pthread_cond_signal(&fd_extra.cond);
- pthread_mutex_unlock(&fd_extra.mutex);
- }
-
- /* haven't found portals event, go back to loop if time
- * is not expired */
- if (!nexec) {
- if (timeout_pointer == NULL || now() >= until)
- goto again;
- }
-}
-
-#else /* !ENABLE_SELECT_DISPATCH */
-
-/* Function: select_timer_block
- * Arguments: until: an absolute time when the select should return
- *
- * This function dispatches the various file descriptors' handler
- * functions, if the kernel indicates there is io available.
- */
-void select_timer_block(when until)
-{
- fd_set fds[3];
- struct timeval timeout;
- struct timeval *timeout_pointer;
- int max, nready;
-
-again:
- if (until) {
- when interval;
- interval = until - now();
- timeout.tv_sec = (interval >> 32);
- timeout.tv_usec = ((interval << 32) / 1000000) >> 32;
- timeout_pointer = &timeout;
- } else
- timeout_pointer = NULL;
-
- max = prepare_fd_sets(&fds[0], &fds[1], &fds[2]);
-
- nready = select(max, &fds[0], &fds[1], &fds[2], timeout_pointer);
- if (nready > 0)
- execute_callbacks(&fds[0], &fds[1], &fds[2]);
-}
-#endif /* ENABLE_SELECT_DISPATCH */
-
-/* Function: init_unix_timer()
- * is called to initialize the library
- */
-void init_unix_timer()
-{
- io_handlers=0;
- gettimeofday(&beginning_of_epoch, 0);
- initialize_timer(select_timer_block);
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <table.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* table.c:
- * a very simple hash table implementation with paramerterizable
- * comparison and key generation functions. it does resize
- * in order to accomidate more entries, but never collapses
- * the table
- */
-
-static table_entry *table_lookup (table t,void *comparator,
- unsigned int k,
- int (*compare_function)(void *, void *),
- int *success)
-{
- unsigned int key=k%t->size;
- table_entry *i;
-
- for (i=&(t->entries[key]);*i;i=&((*i)->next)){
- if (compare_function && ((*i)->key==k))
- if ((*t->compare_function)((*i)->value,comparator)){
- *success=1;
- return(i);
- }
- }
- *success=0;
- return(&(t->entries[key]));
-}
-
-
-static void resize_table(table t, int size)
-{
- int old_size=t->size;
- table_entry *old_entries=t->entries;
- int i;
- table_entry j,n;
- table_entry *position;
- int success;
-
- t->size=size;
- t->entries=(table_entry *)malloc(sizeof(table_entry)*t->size);
- memset(t->entries,0,sizeof(table_entry)*t->size);
-
- for (i=0;i<old_size;i++)
- for (j=old_entries[i];j;j=n){
- n=j->next;
- position=table_lookup(t,0,j->key,0,&success);
- j->next= *position;
- *position=j;
- }
- free(old_entries);
-}
-
-
-/* Function: key_from_int
- * Arguments: int i: value to compute the key of
- * Returns: the key
- */
-unsigned int key_from_int(int i)
-{
- return(i);
-}
-
-
-/* Function: key_from_string
- * Arguments: char *s: the null terminated string
- * to compute the key of
- * Returns: the key
- */
-unsigned int key_from_string(char *s)
-{
- unsigned int result=0;
- unsigned char *n;
- int i;
- if (!s) return(1);
- for (n=s,i=0;*n;n++,i++) result^=(*n*57)^*n*i;
- return(result);
-}
-
-
-/* Function: hash_create_table
- * Arguments: compare_function: a function to compare
- * a table instance with a correlator
- * key_function: a function to generate a 32 bit
- * hash key from a correlator
- * Returns: a pointer to the new table
- */
-table hash_create_table (int (*compare_function)(void *, void *),
- unsigned int (*key_function)(void *))
-{
- table new=(table)malloc(sizeof(struct table));
- memset(new, 0, sizeof(struct table));
-
- new->compare_function=compare_function;
- new->key_function=key_function;
- new->number_of_entries=0;
- new->size=4;
- new->entries=(table_entry *)malloc(sizeof(table_entry)*new->size);
- memset(new->entries,0,sizeof(table_entry)*new->size);
- return(new);
-}
-
-
-/* Function: hash_table_find
- * Arguments: t: a table to look in
- * comparator: a value to access the table entry
- * Returns: the element references to by comparator, or null
- */
-void *hash_table_find (table t, void *comparator)
-{
- int success;
- table_entry* entry=table_lookup(t,comparator,
- (*t->key_function)(comparator),
- t->compare_function,
- &success);
- if (success) return((*entry)->value);
- return(0);
-}
-
-
-/* Function: hash_table_insert
- * Arguments: t: a table to insert the object
- * value: the object to put in the table
- * comparator: the value by which the object
- * will be addressed
- * Returns: nothing
- */
-void hash_table_insert (table t, void *value, void *comparator)
-{
- int success;
- unsigned int k=(*t->key_function)(comparator);
- table_entry *position=table_lookup(t,comparator,k,
- t->compare_function,&success);
- table_entry entry;
-
- if (success) {
- entry = *position;
- } else {
- entry = (table_entry)malloc(sizeof(struct table_entry));
- memset(entry, 0, sizeof(struct table_entry));
- entry->next= *position;
- *position=entry;
- t->number_of_entries++;
- }
- entry->value=value;
- entry->key=k;
- if (t->number_of_entries > t->size) resize_table(t,t->size*2);
-}
-
-/* Function: hash_table_remove
- * Arguments: t: the table to remove the object from
- * comparator: the index value of the object to remove
- * Returns:
- */
-void hash_table_remove (table t, void *comparator)
-{
- int success;
- table_entry temp;
- table_entry *position=table_lookup(t,comparator,
- (*t->key_function)(comparator),
- t->compare_function,&success);
- if(success) {
- temp=*position;
- *position=(*position)->next;
- free(temp); /* the value? */
- t->number_of_entries--;
- }
-}
-
-/* Function: hash_iterate_table_entries
- * Arguments: t: the table to iterate over
- * handler: a function to call with each element
- * of the table, along with arg
- * arg: the opaque object to pass to handler
- * Returns: nothing
- */
-void hash_iterate_table_entries(table t,
- void (*handler)(void *,void *),
- void *arg)
-{
- int i;
- table_entry *j,*next;
-
- for (i=0;i<t->size;i++)
- for (j=t->entries+i;*j;j=next){
- next=&((*j)->next);
- (*handler)(arg,(*j)->value);
- }
-}
-
-/* Function: hash_filter_table_entries
- * Arguments: t: the table to iterate over
- * handler: a function to call with each element
- * of the table, along with arg
- * arg: the opaque object to pass to handler
- * Returns: nothing
- * Notes: operations on the table inside handler are not safe
- *
- * filter_table_entires() calls the handler function for each
- * item in the table, passing it and arg. The handler function
- * returns 1 if it is to be retained in the table, and 0
- * if it is to be removed.
- */
-void hash_filter_table_entries(table t, int (*handler)(void *, void *), void *arg)
-{
- int i;
- table_entry *j,*next,v;
-
- for (i=0;i<t->size;i++)
- for (j=t->entries+i;*j;j=next){
- next=&((*j)->next);
- if (!(*handler)(arg,(*j)->value)){
- next=j;
- v=*j;
- *j=(*j)->next;
- free(v);
- t->number_of_entries--;
- }
- }
-}
-
-/* Function: destroy_table
- * Arguments: t: the table to free
- * thunk: a function to call with each element,
- * most likely free()
- * Returns: nothing
- */
-void hash_destroy_table(table t,void (*thunk)(void *))
-{
- table_entry j,next;
- int i;
- for (i=0;i<t->size;i++)
- for (j=t->entries[i];j;j=next){
- next=j->next;
- if (thunk) (*thunk)(j->value);
- free(j);
- }
- free(t->entries);
- free(t);
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-#ifndef E_TABLE
-#define E_TABLE
-
-typedef struct table_entry {
- unsigned int key;
- void *value;
- struct table_entry *next;
-} *table_entry;
-
-
-typedef struct table {
- unsigned int size;
- int number_of_entries;
- table_entry *entries;
- int (*compare_function)(void *, void *);
- unsigned int (*key_function)(void *);
-} *table;
-
-/* table.c */
-unsigned int key_from_int(int i);
-unsigned int key_from_string(char *s);
-table hash_create_table(int (*compare_function)(void *, void *),
- unsigned int (*key_function)(void *));
-void *hash_table_find(table t, void *comparator);
-void hash_table_insert(table t, void *value, void *comparator);
-void hash_table_remove(table t, void *comparator);
-void hash_iterate_table_entries(table t, void (*handler)(void *, void *), void *arg);
-void hash_filter_table_entries(table t, int (*handler)(void *, void *), void *arg);
-void hash_destroy_table(table t, void (*thunk)(void *));
-
-#endif
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2003 Cluster File Systems, Inc.
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* tcpnal.c:
- This file implements the TCP-based nal by providing glue
- between the connection service and the generic NAL implementation */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <pqtimer.h>
-#include <dispatch.h>
-#include <procbridge.h>
-#include <connection.h>
-#include <errno.h>
-#ifndef __CYGWIN__
-#include <syscall.h>
-#endif
-
-/* Function: tcpnal_send
- * Arguments: ni: pointer to NAL instance
- * private: unused
- * cookie: passed back to the portals library
- * hdr: pointer to the portals header
- * nid: destination node
- * pid: destination process
- * data: body of the message
- * len: length of the body
- * Returns: zero on success
- *
- * sends a packet to the peer, after insuring that a connection exists
- */
-int tcpnal_send(ptl_ni_t *ni,
- void *private,
- ptl_msg_t *cookie,
- ptl_hdr_t *hdr,
- int type,
- lnet_process_id_t target,
- int routing,
- unsigned int niov,
- struct iovec *iov,
- size_t offset,
- size_t len)
-{
- connection c;
- bridge b=(bridge)ni->ni_data;
- struct iovec tiov[257];
- static pthread_mutex_t send_lock = PTHREAD_MUTEX_INITIALIZER;
- int rc = 0;
- int sysrc;
- int total;
- int ntiov;
- int i;
-
- if (routing) {
- CERROR("Can't route\n");
- return -EIO;
- }
-
- if (!(c=force_tcp_connection((manager)b->lower, target.nid,
- b->local)))
- return(-EIO);
-
- /* TODO: these results should be checked. furthermore, provision
- must be made for the SIGPIPE which is delivered when
- writing on a tcp socket which has closed underneath
- the application. there is a linux flag in the sendmsg
- call which turns off the signally behaviour, but its
- nonstandard */
-
- LASSERT (niov <= 256);
-
- tiov[0].iov_base = hdr;
- tiov[0].iov_len = sizeof(ptl_hdr_t);
- ntiov = 1 + lnet_extract_iov(256, &tiov[1], niov, iov, offset, len);
-
- pthread_mutex_lock(&send_lock);
-#if 1
- for (i = total = 0; i < ntiov; i++)
- total += tiov[i].iov_len;
-
- sysrc = syscall(SYS_writev, c->fd, tiov, ntiov);
- if (sysrc != total) {
- fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
- rc, total, errno);
- rc = -errno;
- }
-#else
- for (i = total = 0; i <= ntiov; i++) {
- rc = send(c->fd, tiov[i].iov_base, tiov[i].iov_len, 0);
-
- if (rc != tiov[i].iov_len) {
- fprintf (stderr, "BAD SEND rc %d != %d, errno %d\n",
- rc, tiov[i].iov_len, errno);
- rc = -errno;
- break;
- }
- total += rc;
- }
-#endif
-#if 0
- fprintf (stderr, "sent %s total %d in %d frags\n",
- hdr->type == PTL_MSG_ACK ? "ACK" :
- hdr->type == PTL_MSG_PUT ? "PUT" :
- hdr->type == PTL_MSG_GET ? "GET" :
- hdr->type == PTL_MSG_REPLY ? "REPLY" :
- hdr->type == PTL_MSG_HELLO ? "HELLO" : "UNKNOWN",
- total, niov + 1);
-#endif
- pthread_mutex_unlock(&send_lock);
-
- if (rc == 0) {
- /* NB the NAL only calls lnet_finalize() if it returns 0
- * from cb_send() */
- lnet_finalize(ni, private, cookie, 0);
- }
-
- return(rc);
-}
-
-
-/* Function: tcpnal_recv
- * Arguments: ptl_ni_t *: pointer to NAL instance
- * void *private: connection pointer passed through
- * lnet_parse()
- * ptl_msg_t *cookie: passed back to portals library
- * user_ptr data: pointer to the destination buffer
- * size_t mlen: length of the body
- * size_t rlen: length of data in the network
- * Returns: zero on success
- *
- * blocking read of the requested data. must drain out the
- * difference of mainpulated and requested lengths from the network
- */
-int tcpnal_recv(ptl_ni_t *ni,
- void *private,
- ptl_msg_t *cookie,
- unsigned int niov,
- struct iovec *iov,
- size_t offset,
- size_t mlen,
- size_t rlen)
-{
- struct iovec tiov[256];
- int ntiov;
- int i;
-
- if (!niov)
- goto finalize;
-
- LASSERT(mlen);
- LASSERT(rlen);
- LASSERT(rlen >= mlen);
-
- ntiov = lnet_extract_iov(256, tiov, niov, iov, offset, mlen);
-
- /* FIXME
- * 1. Is this effecient enough? change to use readv() directly?
- * 2. need check return from read_connection()
- * - MeiJia
- */
- for (i = 0; i < ntiov; i++)
- read_connection(private, tiov[i].iov_base, tiov[i].iov_len);
-
-finalize:
- /* FIXME; we always assume success here... */
- lnet_finalize(ni, private, cookie, 0);
-
- if (mlen!=rlen){
- char *trash=malloc(rlen-mlen);
-
- /*TODO: check error status*/
- read_connection(private,trash,rlen-mlen);
- free(trash);
- }
-
- return(0);
-}
-
-
-/* Function: from_connection:
- * Arguments: c: the connection to read from
- * Returns: whether or not to continue reading from this connection,
- * expressed as a 1 to continue, and a 0 to not
- *
- * from_connection() is called from the select loop when i/o is
- * available. It attempts to read the portals header and
- * pass it to the generic library for processing.
- */
-static int from_connection(void *a, void *d)
-{
- connection c = d;
- bridge b = a;
- ptl_hdr_t hdr;
- int rc;
-
- if (read_connection(c, (unsigned char *)&hdr, sizeof(hdr))){
- /* replace dest_nid,pid (socknal sets its own) */
- hdr.dest_nid = cpu_to_le64(b->b_ni->ni_nid);
- hdr.dest_pid = cpu_to_le32(lnet_getpid());
-
- rc = lnet_parse(b->b_ni, &hdr, c);
- if (rc != 0) {
- CERROR("Error %d from lnet_parse\n", rc);
- return 0;
- }
-
- return(1);
- }
- return(0);
-}
-
-
-void tcpnal_shutdown(bridge b)
-{
- shutdown_connections(b->lower);
-}
-
-/* Function: PTL_IFACE_TCP
- * Arguments: pid_request: desired port number to bind to
- * desired: passed NAL limits structure
- * actual: returned NAL limits structure
- * Returns: a nal structure on success, or null on failure
- */
-int tcpnal_init(bridge b)
-{
- manager m;
-
- if (!(m=init_connections(from_connection,b))){
- /* TODO: this needs to shut down the
- newly created junk */
- return(-ENXIO);
- }
- b->lower=m;
- return(0);
-}
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- * Copyright (c) 2002 Eric Hoffman
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-/* TODO: make this an explicit type when they become available */
-typedef unsigned long long when;
-
-typedef struct timer {
- void (*function)(void *);
- void *arg;
- when w;
- int interval;
- int disable;
-} *timer;
-
-timer register_timer(when, void (*f)(void *), void *a);
-void remove_timer(timer t);
-void timer_loop(void);
-void initialize_timer(void);
-void register_thunk(void (*f)(void *),void *a);
-
-
-#define HZ 0x100000000ull
-
-
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (c) 2002 Cray Inc.
- *
- * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-typedef unsigned short uint16;
-typedef unsigned long uint32;
-typedef unsigned long long uint64;
-typedef unsigned char uint8;