[commit] r2411 - Merging support files from cogvm branch.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit] r2411 - Merging support files from cogvm branch.

commits-3
 
Author: andreas
Date: 2011-06-09 01:25:48 -0700 (Thu, 09 Jun 2011)
New Revision: 2411

Modified:
   trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h
   trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
Log:
Merging support files from cogvm branch.

Modified: trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h
===================================================================
--- trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h 2011-06-09 08:22:15 UTC (rev 2410)
+++ trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h 2011-06-09 08:25:48 UTC (rev 2411)
@@ -8,6 +8,7 @@
 *   EMAIL:  
 *   RCSID:   $Id$
 *
+* 2009-05-15 EEM add stdio flag; reorder SQFile to make it more compact
 * 2005-03-26 IKP fix unaligned accesses to file member
 * 2004-06-10 IKP 64-bit cleanliness
 * 01/22/2002 JMM change off_t to squeakOffsetFileType
@@ -18,11 +19,13 @@
 
 /* squeak file record; see sqFilePrims.c for details */
 typedef struct {
- int sessionID; /* ikp: must be first */
- void *file;
- int writable;
- squeakFileOffsetType fileSize;
- int lastOp; /* 0 = uncommitted, 1 = read, 2 = write */
+  int sessionID; /* ikp: must be first */
+  void *file;
+  squeakFileOffsetType fileSize; /* 64-bits we hope. */
+  char writable;
+  char lastOp; /* 0 = uncommitted, 1 = read, 2 = write */
+  char lastChar;
+  char isStdioStream;
 } SQFile;
 
 /* file i/o */
@@ -43,6 +46,7 @@
 sqInt   sqFileFlush(SQFile *f);
 sqInt   sqFileTruncate(SQFile *f,squeakFileOffsetType offset);
 sqInt   sqFileThisSession(void);
+sqInt   sqFileStdioHandlesInto(SQFile files[3]);
 
 /* directories */
 

Modified: trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
===================================================================
--- trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c 2011-06-09 08:22:15 UTC (rev 2410)
+++ trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c 2011-06-09 08:25:48 UTC (rev 2411)
@@ -9,8 +9,6 @@
 *   RCSID:   $Id$
 *
 *   NOTES: See change log below.
-*   2010-12-28 dtl add sqFileStdioHandlesInto() adapted from Cog branch
-* 2008-08-29 bf  add stdin/stdout/stderr support
 * 2005-03-26 IKP fix unaligned accesses to file[Size] members
 * 2004-06-10 IKP 64-bit cleanliness
 * 1/28/02    Tim remove non-ansi stuff
@@ -28,7 +26,8 @@
 * handling code. Note that the win32 platform #defines NO_STD_FILE_SUPPORT
 * and thus bypasses this file
 */
-                                                      
+
+#include <errno.h>
 #include "sq.h"
 #ifndef NO_STD_FILE_SUPPORT
 #include "FilePlugin.h"
@@ -54,11 +53,13 @@
  positioning operation to be done automatically if needed.
 
  typedef struct {
+ int sessionID;
  File *file;
- int sessionID;
- int writable;
  squeakFileOffsetType fileSize;  //JMM Nov 8th 2001 64bits we hope
- int lastOp;  // 0 = uncommitted, 1 = read, 2 = write //
+ char writable;
+ char lastOp;   // 0 = uncommitted, 1 = read, 2 = write //
+ char lastChar; // one character peek for stdin //
+ char isStdioStream;
  } SQFile;
 
 ***/
@@ -78,20 +79,32 @@
 int thisSession = 0;
 extern struct VirtualMachine * interpreterProxy;
 
+/* Since SQFile instaces are held on the heap in 32-bit-aligned byte arrays we
+ * may need to use memcpy to avoid alignment faults.
+ */
+#if DOUBLE_WORD_ALIGNMENT
 static void setFile(SQFile *f, FILE *file)
 {
   void *in= (void *)&file;
   void *out= (void *)&f->file;
   memcpy(out, in, sizeof(FILE *));
 }
+#else
+# define setFile(f,fileptr) ((f)->file = (fileptr))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static void setSize(SQFile *f, squeakFileOffsetType size)
 {
   void *in= (void *)&size;
   void *out= (void *)&f->fileSize;
   memcpy(out, in, sizeof(squeakFileOffsetType));
 }
+#else
+# define setSize(f,size) ((f)->fileSize = (size))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static FILE *getFile(SQFile *f)
 {
   FILE *file;
@@ -100,7 +113,11 @@
   memcpy(out, in, sizeof(FILE *));
   return file;
 }
+#else
+# define getFile(f) ((FILE *)((f)->file))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static squeakFileOffsetType getSize(SQFile *f)
 {
   squeakFileOffsetType size;
@@ -109,28 +126,43 @@
   memcpy(out, in, sizeof(squeakFileOffsetType));
   return size;
 }
+#else
+# define getSize(f) ((f)->fileSize)
+#endif
 
+#if 0
+# define pentry(func) do { int fn = fileno(getFile(f)); if (f->isStdioStream) printf("\n"#func "(%s) %lld %d\n", fn == 0 ? "in" : fn == 1 ? "out" : "err", (long long)ftell(getFile(f)), f->lastChar); } while (0)
+# define pexit(expr) (f->isStdioStream && printf("\n\t^"#expr " %lld %d\n", (long long)(sqFileValid(f) ? ftell(getFile(f)) : -1), f->lastChar)), expr
+# define pfail() printf("\tFAIL\n");
+#else
+# define pentry(func) 0
+# define pexit(expr) expr
+# define pfail() 0
+#endif
 
 sqInt sqFileAtEnd(SQFile *f) {
  /* Return true if the file's read/write head is at the end of the file. */
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
- return ftell(getFile(f)) >= getSize(f);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ pentry(sqFileAtEnd);
+ if (f->isStdioStream)
+ return pexit(feof(getFile(f)));
+ return ftell(getFile(f)) == getSize(f);
 }
 
 sqInt sqFileClose(SQFile *f) {
  /* Close the given file. */
 
- FILE *file;
- if (!sqFileValid(f)) return interpreterProxy->success(false);
- file = getFile(f);
- if (file != stdin && file != stdout && file != stderr)
-  fclose(file);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ fclose(getFile(f));
  setFile(f, 0);
  f->sessionID = 0;
  f->writable = false;
  setSize(f, 0);
  f->lastOp = UNCOMMITTED;
+ return 1;
 }
 
 sqInt sqFileDeleteNameSize(char* sqFileName, sqInt sqFileNameSize) {
@@ -148,6 +180,7 @@
  if (err) {
  return interpreterProxy->success(false);
  }
+ return 1;
 }
 
 squeakFileOffsetType sqFileGetPosition(SQFile *f) {
@@ -155,9 +188,15 @@
 
  squeakFileOffsetType position;
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ pentry(sqFileGetPosition);
+ if (f->isStdioStream
+ && !f->writable)
+ return pexit(f->lastChar == EOF ? 0 : 1);
  position = ftell(getFile(f));
- if (position == -1) return interpreterProxy->success(false);
+ if (position == -1)
+ return interpreterProxy->success(false);
  return position;
 }
 
@@ -167,7 +206,7 @@
    Should be called once at startup time.
  */
 #if VM_PROXY_MINOR > 6
- thisSession = (int) interpreterProxy->getThisSessionID();
+ thisSession = interpreterProxy->getThisSessionID();
 #else
  thisSession = ioLowResMSecs() + time(NULL);
  if (thisSession == 0) thisSession = 1; /* don't use 0 */
@@ -179,15 +218,6 @@
  return 1;
 }
 
-static int setStdFilename(char* stdFilename, char *cFileName, char *sqFileName, sqInt sqFileNameSize)
-{
-  if (!strncmp(stdFilename, sqFileName,sqFileNameSize)) {
-    strcpy(cFileName, stdFilename);
-    return 1;
-  } else
-    return 0;
-}
-
 sqInt sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeFlag) {
  /* Opens the given file using the supplied sqFile structure
    to record its state. Fails with no side effects if f is
@@ -198,26 +228,18 @@
  char cFileName[1001];
 
  /* don't open an already open file */
- if (sqFileValid(f)) return interpreterProxy->success(false);
+ if (sqFileValid(f))
+ return interpreterProxy->success(false);
 
  /* copy the file name into a null-terminated C string */
  if (sqFileNameSize > 1000) {
  return interpreterProxy->success(false);
  }
+ interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true);
 
- if (setStdFilename("/dev/stdin", cFileName, sqFileName, sqFileNameSize))
-  setFile(f, stdin);
- else if (setStdFilename("/dev/stdout", cFileName, sqFileName, sqFileNameSize))
-  setFile(f, stdout);
- else if (setStdFilename("/dev/stderr", cFileName, sqFileName, sqFileNameSize))
-  setFile(f, stderr);
- else
-  interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true);
-
  if (writeFlag) {
  /* First try to open an existing file read/write: */
- if (getFile(f) == NULL)
- setFile(f, fopen(cFileName, "r+b"));
+ setFile(f, fopen(cFileName, "r+b"));
  if (getFile(f) == NULL) {
  /* Previous call fails if file does not exist. In that case,
    try opening it in write mode to create a new, empty file.
@@ -232,8 +254,7 @@
  }
  f->writable = true;
  } else {
- if (getFile(f) == NULL)
- setFile(f, fopen(cFileName, "rb"));
+ setFile(f, fopen(cFileName, "rb"));
  f->writable = false;
  }
 
@@ -250,6 +271,7 @@
  fseek(file, 0, SEEK_SET);
  }
  f->lastOp = UNCOMMITTED;
+ return 1;
 }
 
 /*
@@ -260,26 +282,36 @@
 sqInt
 sqFileStdioHandlesInto(SQFile files[3])
 {
-#if defined(_IONBF)
+#if defined(_IONBF) && 0
  if (isatty(fileno(stdin)))
- setvbuf(stdin,0,_IONBF,0);
+# if 0
+ setvbuf(stdin,0,_IONBF,1);
+# else
+ setvbuf(stdin,0,_IOFBF,0);
+# endif
 #endif
  files[0].sessionID = thisSession;
  files[0].file = stdin;
  files[0].fileSize = 0;
  files[0].writable = false;
  files[0].lastOp = READ_OP;
+ files[0].isStdioStream = true;
+ files[0].lastChar = EOF;
 
  files[1].sessionID = thisSession;
  files[1].file = stdout;
  files[1].fileSize = 0;
  files[1].writable = true;
+ files[1].isStdioStream = true;
+ files[1].lastChar = EOF;
  files[1].lastOp = WRITE_OP;
 
  files[2].sessionID = thisSession;
  files[2].file = stderr;
  files[2].fileSize = 0;
  files[2].writable = true;
+ files[2].isStdioStream = true;
+ files[2].lastChar = EOF;
  files[2].lastOp = WRITE_OP;
 
  return 7;
@@ -296,14 +328,47 @@
  char *dst;
  size_t bytesRead;
  FILE *file;
+#if COGMTVM
+ sqInt myThreadIndex;
+#endif
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
- file= getFile(f);
- if (f->writable && (f->lastOp == WRITE_OP)) fseek(file, 0, SEEK_CUR);  /* seek between writing and reading */
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ pentry(sqFileReadIntoAt);
+ file = getFile(f);
+ if (f->writable) {
+ if (f->isStdioStream)
+ return interpreterProxy->success(false);
+ if (f->lastOp == WRITE_OP)
+ fseek(file, 0, SEEK_CUR);  /* seek between writing and reading */
+ }
  dst = byteArrayIndex + startIndex;
- bytesRead = fread(dst, 1, count, file);
+#if COGMTVM
+ if (f->isStdioStream) {
+ if (interpreterProxy->isInMemory((sqInt)f)
+ && interpreterProxy->isYoung((sqInt)f)
+ || interpreterProxy->isInMemory((sqInt)dst)
+ && interpreterProxy->isYoung((sqInt)dst)) {
+ interpreterProxy->primitiveFailFor(PrimErrObjectMayMove);
+ return 0;
+ }
+ myThreadIndex = interpreterProxy->disownVM(DisownVMLockOutFullGC);
+ }
+#endif
+ do {
+ clearerr(file);
+ bytesRead = fread(dst, 1, count, file);
+ } while (bytesRead <= 0 && ferror(file) && errno == EINTR);
+#if COGMTVM
+ if (f->isStdioStream)
+ interpreterProxy->ownVM(myThreadIndex);
+#endif
+ /* support for skipping back 1 character for stdio streams */
+ if (f->isStdioStream)
+ if (bytesRead > 0)
+ f->lastChar = dst[bytesRead-1];
  f->lastOp = READ_OP;
- return bytesRead;
+ return pexit(bytesRead);
 }
 
 sqInt sqFileRenameOldSizeNewSize(char* oldNameIndex, sqInt oldNameSize, char* newNameIndex, sqInt newNameSize) {
@@ -323,38 +388,61 @@
  if (err) {
  return interpreterProxy->success(false);
  }
+ return 1;
 }
 
 sqInt sqFileSetPosition(SQFile *f, squeakFileOffsetType position) {
  /* Set the file's read/write head to the given position. */
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ if (f->isStdioStream) {
+ pentry(sqFileSetPosition);
+ /* support one character of pushback for stdio streams. */
+ if (!f->writable
+ && f->lastChar != EOF) {
+ squeakFileOffsetType currentPos = f->lastChar == EOF ? 0 : 1;
+ if (currentPos == position)
+ return pexit(1);
+ if (currentPos - 1 == position) {
+ ungetc(f->lastChar, getFile(f));
+ f->lastChar = EOF;
+ return pexit(1);
+ }
+ }
+ pfail();
+ return interpreterProxy->success(false);
+ }
  fseek(getFile(f), position, SEEK_SET);
  f->lastOp = UNCOMMITTED;
+ return 1;
 }
 
 squeakFileOffsetType sqFileSize(SQFile *f) {
  /* Return the length of the given file. */
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ if (f->isStdioStream)
+ return interpreterProxy->success(false);
  return getSize(f);
 }
 
 sqInt sqFileFlush(SQFile *f) {
- /* Return the length of the given file. */
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ pentry(sqFileFlush);
  fflush(getFile(f));
  return 1;
 }
 
 sqInt sqFileTruncate(SQFile *f,squeakFileOffsetType offset) {
- /* Truncate the file*/
 
- if (!sqFileValid(f)) return interpreterProxy->success(false);
- if (sqFTruncate(getFile(f), offset)) {
-            return interpreterProxy->success(false);
-        }
+ if (!sqFileValid(f))
+ return interpreterProxy->success(false);
+ if (sqFTruncate(getFile(f), offset))
+ return interpreterProxy->success(false);
  setSize(f, ftell(getFile(f)));
  return 1;
 }
@@ -378,8 +466,10 @@
  squeakFileOffsetType position;
  FILE *file;
 
- if (!(sqFileValid(f) && f->writable)) return interpreterProxy->success(false);
- file= getFile(f);
+ if (!(sqFileValid(f) && f->writable))
+ return interpreterProxy->success(false);
+ pentry(sqFileWriteFromAt);
+ file = getFile(f);
  if (f->lastOp == READ_OP) fseek(file, 0, SEEK_CUR);  /* seek between reading and writing */
  src = byteArrayIndex + startIndex;
  bytesWritten = fwrite(src, 1, count, file);
@@ -393,12 +483,10 @@
  interpreterProxy->success(false);
  }
  f->lastOp = WRITE_OP;
- return bytesWritten;
+ return pexit(bytesWritten);
 }
 
 sqInt sqFileThisSession() {
  return thisSession;
 }
-
 #endif /* NO_STD_FILE_SUPPORT */
-