[Mit-cadr-cvs] r359 - trunk/emulator/usim
ggilley at common-lisp.net
ggilley at common-lisp.net
Tue Nov 27 05:52:35 UTC 2012
Author: ggilley
Date: Mon Nov 26 21:52:35 2012
New Revision: 359
Log:
get local chaose working on linux
Modified:
trunk/emulator/usim/Files.c
trunk/emulator/usim/Makefile
trunk/emulator/usim/chaos.c
trunk/emulator/usim/chaos.h
Modified: trunk/emulator/usim/Files.c
==============================================================================
--- trunk/emulator/usim/Files.c Mon Nov 26 21:42:49 2012 (r358)
+++ trunk/emulator/usim/Files.c Mon Nov 26 21:52:35 2012 (r359)
@@ -44,7 +44,9 @@
#include <sys/timeb.h>
#include <sys/socket.h>
+#if defined(OSX)
#import <dispatch/dispatch.h>
+#endif
#include <time.h>
#include <sys/dir.h>
@@ -83,7 +85,7 @@
/* use utimes instead of "outmoded" utime */
#endif
-#if defined(__NetBSD__) || defined(OSX)
+#if defined(__NetBSD__) || defined(OSX) || defined(linux)
#include <utime.h>
#include <sys/statvfs.h>
#endif
@@ -201,7 +203,12 @@
#define x_pbuf x_pkt.cp_data /* Packet data buffer */
char **x_glob; /* Files for DIRECTORY */
char **x_gptr; /* Ptr into x_glob vector */
- dispatch_semaphore_t x_hangsem;
+#if defined(OSX)
+ dispatch_semaphore_t x_hangsem;
+#else
+ pthread_mutex_t x_hangsem;
+ pthread_cond_t x_hangcond;
+#endif
#ifdef SELECT
struct transaction *x_work; /* Queued transactions */
#else
@@ -741,6 +748,8 @@
fflush(stderr);
}
+#if defined(OSX)
+
void processdata(chaos_connection *conn)
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
@@ -755,49 +764,29 @@
});
}
-#if 0
-/*
- * Process receipts and acknowledgements using recnum as the receipt.
- */
-static void
-receipt(struct connection *conn, unsigned short acknum, unsigned short recnum)
+#else // !defined(OSX)
+
+static void *_processdata(void *conn)
{
- struct packet *pkt, *pktl;
-
- /*
- * Process a receipt, freeing packets that we now know have been
- * received.
- */
- if (cmp_gt(recnum,conn->cn_trecvd)) {
- for (pktl = conn->cn_thead;
- pktl != NOPKT && cmp_le(LE_TO_SHORT(pktl->LE_pk_pkn),
- recnum);
- pktl = pkt)
- {
- pkt = pktl->pk_next;
- ch_free_pkt(pktl);
- }
- if ((conn->cn_thead = pktl) == NOPKT)
- conn->cn_ttail = NOPKT;
- conn->cn_trecvd = recnum;
+ register struct transaction *t;
+
+ while ((t = getwork((chaos_connection *)conn))) {
+ if (t->t_command->c_flags & C_XFER)
+ xcommand(t);
+ else
+ (*t->t_command->c_func)(t);
}
-
- /*
- * If the acknowledgement is new, update our idea of the
- * latest acknowledged packet, and wakeup output that might be blocked
- * on a full transmit window.
- */
- if (cmp_gt(acknum,conn->cn_tacked))
- if (cmp_gt(acknum, conn->cn_tlast))
- debugf(DBG_WARN,
- "receipt: Invalid acknowledgment(%d,%d)",
- acknum, conn->cn_tlast);
- else {
- conn->cn_tacked = acknum;
- OUTPUT(conn);
- }
+ return 0;
}
-#endif
+
+static pthread_t processdata_thread;
+
+void processdata(chaos_connection *conn)
+{
+ pthread_create(&processdata_thread, NULL, _processdata, (void *)conn);
+}
+
+#endif // defined(OSX)
/*
00000000 00 80 18 00 04 01 00 01 01 01 45 37 01 00 01 00 ..........E7....
@@ -2427,7 +2416,13 @@
x->x_next = xfers;
x->x_realname = x->x_dirname = x->x_tempname = NOSTR;
x->x_glob = (char **)0;
+#if defined(OSX)
x->x_hangsem = dispatch_semaphore_create(0);
+#else
+ pthread_mutex_init(&x->x_hangsem, NULL);
+ pthread_cond_init(&x->x_hangcond, NULL);
+#endif
+
xfers = x;
}
else
@@ -2448,8 +2443,14 @@
errstring = "No transfer in progress on this file handle";
error(t, f ? f->f_name : "", BUG);
} else {
- (*t->t_command->c_func)(x, t);
- dispatch_semaphore_signal(x->x_hangsem);
+ (*t->t_command->c_func)(x, t);
+#if defined(OSX)
+ dispatch_semaphore_signal(x->x_hangsem);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_signal(&x->x_hangcond);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
}
}
#ifdef SELECT
@@ -2505,10 +2506,15 @@
free(x->x_tempname);
if (x->x_dirname)
free(x->x_dirname);
- if (x->x_glob)
- blkfree(x->x_glob);
+ if (x->x_glob)
+ blkfree(x->x_glob);
+#if defined(OSX)
dispatch_release(x->x_hangsem);
- sfree(x);
+#else
+ pthread_mutex_destroy(&x->x_hangsem);
+ pthread_cond_destroy(&x->x_hangcond);
+#endif
+ sfree(x);
}
/*
* Here are commands that operate on existing transfers. There execution
@@ -2659,7 +2665,7 @@
log(LOG_INFO, "xclose (3c)\n");
-#if defined(OSX) || defined(BSD42)
+#if defined(OSX) || defined(BSD42) || defined(linux)
if (utimes(x->x_realname, timep)) {
log(LOG_INFO, "error from utimes: errno = %d %s\n", errno, strerror(errno));
}
@@ -2678,14 +2684,22 @@
#endif
if (protocol > 0)
(void)sprintf(response,
+#if defined(linux)
+ "%02d/%02d/%02d %02d:%02d:%02d %ld%c%s%c",
+#else
"%02d/%02d/%02d %02d:%02d:%02d %lld%c%s%c",
+#endif
tm->tm_mon+1, tm->tm_mday, tm->tm_year,
tm->tm_hour, tm->tm_min, tm->tm_sec,
sbuf.st_size, CHNL,
x->x_realname, CHNL);
else
(void)sprintf(response,
+#if defined(linux)
+ "%d %02d/%02d/%02d %02d:%02d:%02d %ld%c%s%c",
+#else
"%d %02d/%02d/%02d %02d:%02d:%02d %lld%c%s%c",
+#endif
-1, tm->tm_mon+1, tm->tm_mday,
tm->tm_year, tm->tm_hour, tm->tm_min,
tm->tm_sec, sbuf.st_size, CHNL,
@@ -2840,7 +2854,13 @@
respond(t, NOSTR);
f->f_xfer->x_flags |= X_DELETE;
+#if defined(OSX)
dispatch_semaphore_signal(x->x_hangsem);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_signal(&x->x_hangcond);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
}
else if (t->t_args == ANULL ||
(file = t->t_args->a_strings[0]) == NOSTR) {
@@ -2988,7 +3008,13 @@
x->x_realname = real1;
real1 = NOSTR;
respond(t, NOSTR);
+#if defined(OSX)
dispatch_semaphore_signal(x->x_hangsem);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_signal(&x->x_hangcond);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
}
}
else if (file2 == NOSTR) {
@@ -3666,7 +3692,11 @@
used = total - free;
(void)
+#if defined(linux)
+ sprintf(cp, "%s (%s): %ld free, %ld/%ld used (%ld%%)", mtab.path, mtab.spec,
+#else
sprintf(cp, "%s (%s): %lld free, %lld/%lld used (%lld%%)", mtab.path, mtab.spec,
+#endif
free, used, total, (100L * used + total / 2) / total);
while (*cp)
cp++;
@@ -3678,7 +3708,11 @@
static char *
xgetbsize(struct stat *s, char *cp)
{
+#if defined(linux)
+ (void)sprintf(cp, "%ld", (s->st_size + FSBSIZE - 1) / FSBSIZE);
+#else
(void)sprintf(cp, "%lld", (s->st_size + FSBSIZE - 1) / FSBSIZE);
+#endif
while (*cp)
cp++;
@@ -3697,7 +3731,11 @@
char *
getsize(register struct stat *s, register char *cp)
{
+#if defined(linux)
+ (void)sprintf(cp, "%ld", s->st_size);
+#else
(void)sprintf(cp, "%lld", s->st_size);
+#endif
while (*cp)
cp++;
return cp;
@@ -3881,7 +3919,13 @@
} else if (x) {
x->x_mtime = mtime;
x->x_flags |= X_MTIME;
+#if defined(OSX)
dispatch_semaphore_signal(x->x_hangsem);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_signal(&x->x_hangcond);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
}
}
return 0;
@@ -3907,7 +3951,13 @@
} else if (x) {
x->x_mtime = atime;
x->x_flags |= X_ATIME;
+#if defined(OSX)
dispatch_semaphore_signal(x->x_hangsem);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_signal(&x->x_hangcond);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
}
}
return 0;
@@ -4755,6 +4805,9 @@
* Start the transfer task running.
* Returns errcode if an error occurred, else 0
*/
+
+#if defined(OSX)
+
int
startxfer(struct xfer *ax)
{
@@ -4790,6 +4843,57 @@
return 0;
}
+#else // !defined(OSX)
+
+void *
+_startxfer(void *ax)
+{
+ register struct xfer *x = (struct xfer *)ax;
+
+ myxfer = x;
+ log(LOG_INFO, "startxfer: entering\n");
+ setjmp(closejmp);
+ for (;;) {
+ if (log_verbose) {
+ log(LOG_INFO, "Switch pos: %ld, status: %ld\n",
+ tell(x->x_fd), x->x_state);
+ }
+ switch (dowork(x)) {
+ case X_SYNCMARK:
+ syncmark(x->x_fh); /* Ignore errors */
+ break;
+ case X_FLUSH: /* Totally done */
+ break;
+ case X_CONTINUE: /* In process */
+ continue;
+ case X_HANG: /* Need more instructions */
+ log(LOG_INFO, "Hang pos: %ld\n", tell(x->x_fd));
+#if defined(OSX)
+ dispatch_semaphore_wait(x->x_hangsem, DISPATCH_TIME_FOREVER);
+#else
+ pthread_mutex_lock(&x->x_hangsem);
+ pthread_cond_wait(&x->x_hangcond, &x->x_hangsem);
+ pthread_mutex_unlock(&x->x_hangsem);
+#endif
+ continue;
+ }
+ xflush(x);
+ log(LOG_INFO, "startxfer: exiting\n");
+ return 0;
+ }
+ return 0;
+}
+
+static pthread_t startxfer_thread;
+
+int
+startxfer(struct xfer *ax)
+{
+ pthread_create(&startxfer_thread, NULL, _startxfer, (void *)ax);
+}
+
+#endif // defined(OSX)
+
/*
* Character set conversion routines.
*/
@@ -4826,6 +4930,8 @@
}
}
+#if defined(OSX)
+
void
processmini(chaos_connection *conn)
{
@@ -4900,3 +5006,84 @@
});
}
+#else // !defined(OSX)
+
+void *
+_processmini(void *vconn)
+{
+ printf("processmini:\n");
+
+ int binary = 0;
+ chaos_packet *packet;
+ chaos_packet *output;
+ int length, fd;
+ char tbuf[20];
+ struct stat sbuf;
+ struct tm *ptm;
+ chaos_connection *conn = (chaos_connection *)vconn;
+
+ for (;;) {
+
+ packet = chaos_connection_dequeue(conn);
+
+ switch (packet->opcode >> 8) {
+ case 0200:
+ case 0201:
+ output = chaos_allocate_packet(conn, DWDOP, CHMAXDATA);
+
+ packet->data[packet->length] = '\0';
+ printf("MINI: op %o %s\n", packet->opcode, packet->data);
+ if ((fd = open((char *)packet->data, O_RDONLY)) < 0) {
+ output->opcode = 0203 << 8;
+ printf("MINI: open failed %s\n", strerror(errno));
+ chaos_connection_queue(conn, output);
+ continue;
+ } else {
+ output->opcode = 0202 << 8;
+ fstat(fd, &sbuf);
+ ptm = localtime(&sbuf.st_mtime);
+ strftime(tbuf, sizeof(tbuf), "%D %T", ptm);
+ length = sprintf((char *)output->data, "%s%c%s",
+ packet->data, 0215, tbuf);
+ output->length = (unsigned short)length;
+ chaos_connection_queue(conn, output);
+ binary = (packet->opcode >> 8) & 1;
+ log(LOG_INFO, "MINI: binary = %d\n", binary);
+ }
+ free(packet);
+
+ do {
+ char buffer[CHMAXDATA];
+
+ length = read(fd, buffer, CHMAXDATA);
+ /*log(LOG_INFO, "MINI: read %d\n", length);*/
+ if (length == 0)
+ break;
+ output = chaos_allocate_packet(conn, (binary) ? DWDOP : DATOP, length);
+ memcpy(output->data, buffer, length);
+ if (binary == 0)
+ buffer_to_lispm((unsigned char *)output->data, length);
+ chaos_connection_queue(conn, output);
+ } while (length > 0);
+
+ printf("MINI: before eof\n");
+ output = chaos_allocate_packet(conn, EOFOP, 0);
+ chaos_connection_queue(conn, output);
+ close(fd);
+ break;
+ default:
+ log(LOG_INFO, "MINI: op %o\n", packet->opcode >> 8);
+ break;
+ }
+ }
+}
+
+static pthread_t processmini_thread;
+
+void
+processmini(chaos_connection *conn)
+{
+ pthread_create(&processmini_thread, NULL, _processmini, (void *)conn);
+}
+
+#endif // defined(OSX)
Modified: trunk/emulator/usim/Makefile
==============================================================================
--- trunk/emulator/usim/Makefile Mon Nov 26 21:42:49 2012 (r358)
+++ trunk/emulator/usim/Makefile Mon Nov 26 21:52:35 2012 (r359)
@@ -40,7 +40,7 @@
ifeq ($(DISPLAY), SDL)
DISPLAY_SRC = sdl.c
-USIM_LIBS = -lSDL
+USIM_LIBS = -lSDL -lpthread
DEFINES = -DDISPLAY_SDL
endif
@@ -82,7 +82,9 @@
#CFLAGS = -O3 -fomit-frame-pointer -mcpu=i686 -g $(DEFINES)
#CFLAGS= -O3 -mfpmath=sse -mmmx -msse $(DEFINES) -Walle
CFLAGS = -O3 -mfpmath=sse -mmmx -msse $(DEFINES) $(M32) -g
-LFLAGS = $(M32) -L/usr/lib
+LFLAGS = $(M32) -ldl -L/usr/lib
+USIM_SRC += Files.c glob.c
+USIM_HDR += Files.h glob.h
endif
# NetBSD
Modified: trunk/emulator/usim/chaos.c
==============================================================================
--- trunk/emulator/usim/chaos.c Mon Nov 26 21:42:49 2012 (r358)
+++ trunk/emulator/usim/chaos.c Mon Nov 26 21:52:35 2012 (r359)
@@ -36,7 +36,7 @@
#include "endian.h"
#include "chaos.h"
-#if defined(OSX)
+#if defined(OSX) || defined(linux)
#define USE_LOCAL_CHAOS 1
#endif
@@ -48,7 +48,7 @@
# define CHAOS_DEBUG 0
#endif
-#define CHAOS_DEBUG_PKT 1
+#define CHAOS_DEBUG_PKT 0
//#define CHAOS_TOSS_IF_RXBUFF_FULL
#define CHAOS_BUF_SIZE_BYTES 8192
@@ -525,7 +525,11 @@
static chaos_packet *lastpacket;
int connectionstate = 0;
+#if defined(OSX)
static dispatch_queue_t recvqueue;
+#else
+static pthread_mutex_t recvqueue;
+#endif
chaos_connection *connections[256];
@@ -533,6 +537,8 @@
#define CONNECTION_RFC_OPN 2
#define CONNECTION_RFC_STS 3
+#if defined(OSX)
+
void
chaos_queue(chaos_packet *packet)
{
@@ -549,6 +555,26 @@
});
}
+#else // !defined(OSX)
+
+void
+chaos_queue(chaos_packet *packet)
+{
+ packet_queue *node = malloc(sizeof(packet_queue));
+
+ node->next = 0;
+ node->packet = packet;
+ pthread_mutex_lock(&recvqueue);
+ if (queuetail)
+ queuetail->next = node;
+ queuetail = node;
+ if (queuehead == 0)
+ queuehead = node;
+ pthread_mutex_unlock(&recvqueue);
+}
+
+#endif // defined(OSX)
+
chaos_connection *
chaos_make_connection(void)
{
@@ -572,8 +598,15 @@
pthread_mutex_init(&conn->queuelock, NULL);
+#if defined(OSX)
conn->queuesem = dispatch_semaphore_create(0);
conn->twsem = dispatch_semaphore_create(0);
+#else
+ pthread_mutex_init(&conn->queuesem, NULL);
+ pthread_cond_init(&conn->queuecond, NULL);
+ pthread_mutex_init(&conn->twsem, NULL);
+ pthread_cond_init(&conn->twcond, NULL);
+#endif
conn->lastreceived = 0;
conn->lastsent = 0;
conn->remotelastreceived = 0;
@@ -593,7 +626,9 @@
void
chaos_dump_connection(chaos_connection *conn)
{
- for (int i = 0; i < 255; i++)
+ int i;
+
+ for (i = 0; i < 255; i++)
{
if (connections[i] == conn)
{
@@ -610,7 +645,9 @@
void
chaos_delete_connection(chaos_connection *conn)
{
- for (int i = 0; i < 255; i++)
+ int i;
+
+ for (i = 0; i < 255; i++)
if (connections[i] == conn)
{
connections[i] = 0;
@@ -618,8 +655,15 @@
}
pthread_mutex_destroy(&conn->queuelock);
+#if defined(OSX)
dispatch_release(conn->queuesem);
dispatch_release(conn->twsem);
+#else
+ pthread_mutex_destroy(&conn->queuesem);
+ pthread_cond_destroy(&conn->queuecond);
+ pthread_mutex_destroy(&conn->twsem);
+ pthread_cond_destroy(&conn->twcond);
+#endif
free(conn);
}
@@ -639,6 +683,7 @@
printf("waiting for remote ack packet=%d\n", packet->number);
printf("lastsent = %d remotelastreceived = %d twsize = %d\n", conn->lastsent, conn->remotelastreceived, conn->twsize);
#endif
+#if defined(OSX)
if (dispatch_semaphore_wait(conn->twsem, dispatch_time(DISPATCH_TIME_NOW, 5LL * NSEC_PER_SEC)))
{
if (lastpacket)
@@ -650,6 +695,25 @@
chaos_queue(retransmit);
}
}
+#else // !defined(OSX)
+ pthread_mutex_lock(&conn->twsem);
+ struct timespec ts;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 5;
+ if (pthread_cond_timedwait(&conn->twcond, &conn->twsem, &ts))
+ {
+ if (lastpacket)
+ {
+ printf("re-transmit last packet\n");
+// dumpbuffer(lastpacket, CHAOS_PACKET_HEADER_SIZE + lastpacket->length);
+ chaos_packet *retransmit = lastpacket;
+ lastpacket = 0;
+ chaos_queue(retransmit);
+ }
+ }
+ pthread_mutex_unlock(&conn->twsem);
+#endif // defined(OSX)
}
else
break;
@@ -689,7 +753,13 @@
conn->queuehead = node;
pthread_mutex_unlock(&conn->queuelock);
}
+#if defined(OSX)
dispatch_semaphore_signal(conn->queuesem);
+#else
+ pthread_mutex_lock(&conn->queuesem);
+ pthread_cond_signal(&conn->queuecond);
+ pthread_mutex_unlock(&conn->queuesem);
+#endif
}
chaos_packet *chaos_connection_dequeue(chaos_connection *conn)
@@ -751,7 +821,13 @@
return packet;
}
+#if defined(OSX)
dispatch_semaphore_wait(conn->queuesem, DISPATCH_TIME_FOREVER);
+#else
+ pthread_mutex_lock(&conn->queuesem);
+ pthread_cond_wait(&conn->queuecond, &conn->queuesem);
+ pthread_mutex_unlock(&conn->queuesem);
+#endif
}
}
@@ -784,7 +860,9 @@
chaos_connection *
chaos_find_connection(unsigned short index)
{
- for (int i = 0; i < 255; i++)
+ int i;
+
+ for (i = 0; i < 255; i++)
if (connections[i] && connections[i]->localindex == index)
return connections[i];
return 0;
@@ -892,6 +970,8 @@
return 0;
}
+#if defined(OSX)
+
__block chaos_packet *packet;
__block packet_queue *node;
@@ -902,6 +982,20 @@
if (queuehead == 0)
queuetail = 0;
});
+
+#else // !defined(OSX)
+ chaos_packet *packet;
+ packet_queue *node;
+
+ pthread_mutex_lock(&recvqueue);
+ node = queuehead;
+ packet = queuehead->packet;
+ queuehead = node->next;
+ if (queuehead == 0)
+ queuetail = 0;
+ pthread_mutex_unlock(&recvqueue);
+
+#endif // defined(OSX)
int size = ((packet->length & 0x0fff) + CHAOS_PACKET_HEADER_SIZE + 1) / 2;
unsigned short dest_addr = packet->destaddr;
@@ -1171,7 +1265,13 @@
#if CHAOS_DEBUG
printf("STS: twsize = %d\n", conn->twsize);
#endif
+#if defined(OSX)
dispatch_semaphore_signal(conn->twsem);
+#else
+ pthread_mutex_lock(&conn->twsem);
+ pthread_cond_signal(&conn->twcond);
+ pthread_mutex_unlock(&conn->twsem);
+#endif
}
return 0;
}
@@ -1219,9 +1319,13 @@
int
chaos_init(void)
{
+#if defined(OSX)
recvqueue = dispatch_queue_create("com.xxx.yyy", NULL);
+#else
+ pthread_mutex_init(&recvqueue, NULL);
+#endif
- chaos_rcv_buffer_empty = 1;
+ chaos_rcv_buffer_empty = 1;
return 0;
}
Modified: trunk/emulator/usim/chaos.h
==============================================================================
--- trunk/emulator/usim/chaos.h Mon Nov 26 21:42:49 2012 (r358)
+++ trunk/emulator/usim/chaos.h Mon Nov 26 21:52:35 2012 (r359)
@@ -24,7 +24,7 @@
int chaos_init(void);
int chaos_reconnect(void);
-#if defined(OSX)
+#if defined(OSX) || defined(linux)
#define CHAOS_SERVER_ADDRESS 0404
#define CHAOS_SERVER_NAME "server"
@@ -113,8 +113,15 @@
packet_queue *queuehead;
packet_queue *queuetail;
pthread_mutex_t queuelock;
+#if defined(OSX)
dispatch_semaphore_t queuesem;
dispatch_semaphore_t twsem;
+#else
+ pthread_mutex_t queuesem;
+ pthread_cond_t queuecond;
+ pthread_mutex_t twsem;
+ pthread_cond_t twcond;
+#endif
packet_queue *orderhead;
packet_queue *ordertail;
} chaos_connection;
More information about the mit-cadr-cvs
mailing list