Beispiel #1
0
_CODE_ACCESS int remove_device(char *name)
{
   _DEVICE *ptr;

   /*-------------------------------------------------------------------------*/
   /* FIND RECORD AND SET NAME TO NULL                                        */
   /*-------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS ACCESS TO _device[]                            */
   /*-------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_DEVICE_TBL);

   if (!(ptr = finddevice(name))) 
   { 
      __TI_data_synch_INV(&_device, sizeof(_device));
      __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
      return -1; 
   }

   ptr->name[0] = '\0';
   
   __TI_data_synch_WBINV(&_device, sizeof(_device));
   __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);

   return 0;
}
Beispiel #2
0
_CODE_ACCESS int rename(const char *old_name, const char *new_name)
{
   _DEVICE *old_dev, *new_dev;
   int result;

   /*------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS _device[] ACCESS THAT OCCURS IN getdevice()   */
   /* (see file header comment for more on mutex and data coherence).        */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_DEVICE_TBL);

   old_dev = getdevice(&old_name);
   new_dev = getdevice(&new_name);

   /*------------------------------------------------------------------------*/
   /* IF THE DEVICES ARE NOT THE SAME, RENAME WOULD REQUIRE A FILE COPY.     */
   /*------------------------------------------------------------------------*/
   if (old_dev != new_dev) 
   { 
      __TI_data_synch_INV(&_device, sizeof(_device));
      __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
      return -1; 
   }

   /*------------------------------------------------------------------------*/
   /* CALL FUNCTION FROM DEVICE TABLE TO PERFORM RENAME FOR THIS DEVICE/FILE */
   /*------------------------------------------------------------------------*/
   result = (*(old_dev->RENAME)) (old_name, new_name);

   __TI_data_synch_INV(&_device, sizeof(_device));
   __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
   
   return result;
}
Beispiel #3
0
_CODE_ACCESS int close(int llv_fd)
{
   int      result;
#if defined(__TI_SHARED_DATA_SYNCHRONIZATION)
   _DEVICE *dev_ptr = NULL;
#endif

   if (llv_fd < 0 || llv_fd >= _NSTREAM) return -1;

   /*------------------------------------------------------------------------*/
   /* CALL FUNCTION FROM DEVICE TABLE TO PERFORM CLOSE FOR THIS DEVICE/FILE  */
   /* CLEAR STREAM TABLE ENTRY AND DEVICE FLAGS                              */
   /*------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS ACCESS TO _stream[] (see file header comment).*/
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_STREAM_TBL);

   if (_stream[llv_fd].dev == NULL) 
   { 
      __TI_data_synch_INV(&_stream[llv_fd], sizeof(_stream[llv_fd]));
      __TI_resource_unlock(__TI_LOCK_STREAM_TBL);
      return -1;
   }

   /*------------------------------------------------------------------------*/
   /* We'll need to invalidate the device table entry that has the address   */
   /* of the CLOSE function in it, so hold on to its address. We guard the   */
   /* definition of dev_ptr here to avoid a "set but never refed" compile    */
   /* time error when building the RTS in a config that doesn't have shared  */
   /* data synchronization turned on.                                        */
   /*------------------------------------------------------------------------*/
#if defined(__TI_SHARED_DATA_SYNCHRONIZATION)
   dev_ptr = _stream[llv_fd].dev;
#endif
   if ( (result = (*(_stream[llv_fd].dev->CLOSE))(_stream[llv_fd].dfd)) != -1 )
   {
      _stream[llv_fd].dev->flags &= ~_BUSY;
      _stream[llv_fd].dev = NULL;
   }

   /*------------------------------------------------------------------------*/
   /* Invalidate both the device table entry that was referenced and the     */
   /* stream table entry associated with the input file descriptor (llv_fd). */
   /* It is possible (though unlikely) that the contents of the device table */
   /* entry and/or the stream table entry could be updated by another thread */
   /* before this thread accesses either of those objects again.             */
   /*------------------------------------------------------------------------*/
   /* For the address of the device table entry, we use a copy of            */
   /* _stream[llv_fd].dev (dev_ptr) that was made before _stream[llv_fd].dev */
   /* gets modified in the above if block.                                   */
   /*------------------------------------------------------------------------*/
   __TI_data_synch_INV(dev_ptr, sizeof(_DEVICE));
   __TI_data_synch_WBINV(&_stream[llv_fd], sizeof(_stream[llv_fd]));
   __TI_resource_unlock(__TI_LOCK_STREAM_TBL);

   return result;
}
Beispiel #4
0
_CODE_ACCESS FILE *tmpfile(void)
{
   char tfname[L_tmpnam];
   FILE *_fp = NULL;
   
   if (tmpnam(tfname)) _fp = fopen(tfname, "wb+");

   /*------------------------------------------------------------------------*/
   /* A non-NULL _fp returned from fopen() is assumed to be a pointer to a   */
   /* file stream which is a shared resource.                                */
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to the file stream and __TI_tmpnams[]. In this case, _fp will be       */
   /* updated, so we must ensure that the local copy of _fp and _tmpnams[]   */
   /* are flushed to shared memory before leaving the critical section       */
   /* (invalidated if it is not modified).                                   */
   /*------------------------------------------------------------------------*/
   if (_fp)
   {
      __TI_file_lock(_fp);
      _SET(_fp, _TMPFILE);
      
      __TI_resource_lock(__TI_LOCK_TMPNAMS);
      
      strcpy(__TI_tmpnams[_fp->fd], tfname);
      
      __TI_data_synch_WBINV(&__TI_tmpnams[_fp->fd], L_tmpnam);
      __TI_data_synch_WBINV(_fp, sizeof(FILE));
      __TI_resource_unlock(__TI_LOCK_TMPNAMS);
      __TI_file_unlock(_fp);
   }


   return (_fp);
}
Beispiel #5
0
_CODE_ACCESS int HOSTread(int dev_fd, char *buf, unsigned count)
{
   int result;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);

   if (count > BUFSIZ) count = BUFSIZ;

   LOADSHORT(parmbuf,dev_fd,0);
   LOADSHORT(parmbuf,count,2);

   __TI_writemsg(_DTREAD,parmbuf,NULL,0);
   __TI_readmsg(parmbuf,buf);

   result = UNLOADSHORT(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return result;
}
Beispiel #6
0
_CODE_ACCESS void __TI_buff_read(FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int   errchk,
         j,
         buffer_size    = _fp->bufend - _fp->buf;

   /*------------------------------------------------------------------------*/
   /* If this is a line buffered stream, flush all line buffered streams.    */
   /* The current thread in a multi-threaded application must protect access */
   /* to __TI_LOCK_FILE_TBL shared resources (_ftable[] and __TI_ft_end) and */
   /* each file stream that is flushed. Ensure that the local copy of        */
   /* _ftable[] is flushed to shared memory and the local copy of            */
   /* __TI_ft_end is invalidated before leaving the critical section.        */
   /*------------------------------------------------------------------------*/
   if (_BUFFMODE(_fp) == _IOLBF)
   {
      __TI_resource_lock(__TI_LOCK_FILE_TBL);
      for (j=0; j < __TI_ft_end; j++)
	 if (_BUFFMODE(&_ftable[j]) == _IOLBF)
         {
            __TI_file_lock(&_ftable[j]);
	    __TI_doflush(&_ftable[j]);
            __TI_data_synch_WBINV(&_ftable[j], sizeof(FILE));
            __TI_file_unlock(&_ftable[j]);
         }
      __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
      __TI_data_synch_INV(&__TI_ft_end, sizeof(__TI_ft_end));
      __TI_resource_unlock(__TI_LOCK_FILE_TBL);
   }

   /*------------------------------------------------------------------------*/
   /* Read in the next characters from the file.                             */
   /*------------------------------------------------------------------------*/
   errchk = read(_fp->fd, (char *)_fp->buf, buffer_size);

   /*------------------------------------------------------------------------*/
   /* Adjust the buffer pointers.                                            */
   /*------------------------------------------------------------------------*/
   _fp->buff_stop = _fp->buf + errchk;
   _fp->pos = _fp->buf;

   /*------------------------------------------------------------------------*/
   /* Set any error flags if necessary.                                      */
   /*------------------------------------------------------------------------*/
   switch (errchk)
   {
      case -1 : _SET(_fp, _STATERR);
                break;
 
      case 0  : _SET(_fp, _STATEOF);
                break;
   }

   return;
 
}
Beispiel #7
0
_CODE_ACCESS char *tmpnam(char *_s)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int  fd;
 
   __TI_resource_lock(__TI_LOCK_TMPNAM_COUNTER);

   /*------------------------------------------------------------------------*/ 
   /* Get a filename from _GETNAME                                           */
   /*------------------------------------------------------------------------*/ 
   _getname(counter++, tfname);

   /*------------------------------------------------------------------------*/ 
   /* Check to see if the filename exists.  Keep getting filenames until     */
   /* a unique one is found, or this function has reached its limit.         */
   /*------------------------------------------------------------------------*/ 
   while (((fd=open(tfname, O_RDONLY, 0666)) >= 0) && (counter < TMP_MAX))
   {
      close(fd);
      _getname(counter++, tfname);
   }
 
   if (counter >= TMP_MAX) 
   {
      __TI_data_synch_WBINV(&counter, sizeof(counter));
      __TI_resource_unlock(__TI_LOCK_TMPNAM_COUNTER);
      return (NULL);
   }

   __TI_data_synch_WBINV(&counter, sizeof(counter));
   __TI_resource_unlock(__TI_LOCK_TMPNAM_COUNTER);
 
   /*------------------------------------------------------------------------*/ 
   /* If _S is not NULL, store the new filename in it.                       */
   /*------------------------------------------------------------------------*/ 
   if (_s)
   {
      strcpy(_s, tfname);
      return (_s);
   }
 
   return (tfname);
}
Beispiel #8
0
_CODE_ACCESS FILE *fopen(const char *_fname, const char *_mode)
{
    FILE *f;

    /*-----------------------------------------------------------------------*/
    /* This is a critical section because search_fp looks for a new file     */
    /* slot in the global table _ftable.				     */
    /*-----------------------------------------------------------------------*/
    __TI_resource_lock(__TI_LOCK_FILE_TBL);
    f = _openfile(_fname, _search_fp(), _mode);
    __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
    __TI_resource_unlock(__TI_LOCK_FILE_TBL);
    return f;
}
Beispiel #9
0
_CODE_ACCESS void srand(unsigned seed)
{
     /*---------------------------------------------------------------------*/
     /* To maintain backwards compatibility with releases that do not use   */
     /* TLS, we use a mutex lock to protect accesses to the variable 'next'.*/
     /*---------------------------------------------------------------------*/
#if !defined(__TI_USE_TLS)
     __TI_resource_lock(__TI_LOCK_RAND);
#endif
     next = seed;
#if !defined(__TI_USE_TLS)
     __TI_resource_unlock(__TI_LOCK_RAND);
#endif
}
Beispiel #10
0
int atexit(void (*fun)())
{
   int err_code = 1;

   /*-----------------------------------------------------------------------*/
   /* For multi-threaded applications, access to shared resources must be   */
   /* protected. In this case, both atexit_func_count and atexit_func[] are */
   /* shared resources that may be accessed and updated by this function.   */
   /* Use the __TI_LOCK_ATEXIT mutex to create a critical section and       */
   /* that the local copies of both atexit_func_count and atexit_func[] are */
   /* flushed to shared memory.                                             */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_ATEXIT);
   
   /*-----------------------------------------------------------------------*/
   /* We allow MAX_ATEXIT_FUN calls to atexit(); see the comment above the  */
   /* definition of MAX_ATEXIT_FUN for more details. BIOS has a specific    */
   /* request that we NOT use malloc here. If anyone requires additional    */
   /* atexit calls for use by RTS or OS, then the MAX_ATEXIT_FUN limit      */
   /* (above) must be adjusted and the library rebuilt (CQ20012, CQ20600).  */
   /*-----------------------------------------------------------------------*/
   if (atexit_func_count < MAX_ATEXIT_FUN)
   {
      /*--------------------------------------------------------------------*/
      /* Choose the next available entry for registering atexit functions.  */
      /*--------------------------------------------------------------------*/
      int allocated_entry = atexit_func_count++;

      /*--------------------------------------------------------------------*/
      /* Populate the allocated entry with the necessary details.           */
      /*--------------------------------------------------------------------*/
      atexit_func[allocated_entry].next     = NULL;
      atexit_func[allocated_entry].object   = &__atexit_func_id__;
      atexit_func[allocated_entry].fun.dfun = fun;

      /*--------------------------------------------------------------------*/
      /* Register the atexit function for processing at exit.               */
      /*--------------------------------------------------------------------*/
      __add_dtor(&(atexit_func[allocated_entry]));

      err_code = 0;
   }
   
   __TI_data_synch_WBINV(&atexit_func_count, sizeof(int));
   __TI_data_synch_WBINV(&atexit_func, sizeof(atexit_func));
   __TI_resource_unlock(__TI_LOCK_ATEXIT);

   return err_code;
}
Beispiel #11
0
_CODE_ACCESS FILE *freopen(const char *_fname, const char *_mode, register FILE *_fp)
{
    FILE *f;

    /*-----------------------------------------------------------------------*/
    /* This is a critical section because it expects the same slot in the    */
    /* global table _ftable to be available.				     */
    /*-----------------------------------------------------------------------*/
    __TI_resource_lock(__TI_LOCK_FILE_TBL);
    _closefile(_fp); 
    f = _openfile(_fname, _fp, _mode);
    __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
    __TI_resource_unlock(__TI_LOCK_FILE_TBL);
    return f;
}
Beispiel #12
0
_CODE_ACCESS int fflush(register FILE *_fp)
{
   int result = 0;
 
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to __TI_LOCK_FILE_TBL shared resources (_ftable[], __TI_ft_end, init   */
   /* and __TI_cleanup_ptr. init is a static local in __TI_search_fp() in    */
   /* fopen.c). In this case, __TI_doflush will update the specified file     */
   /* streams, so we must also protect access to the streams.                */
   /* The below loop will cache a local copy of _ftable[] and __TI_ft_end.   */
   /* Ensure that the  local copy of _ftable[] and each flushed file stream  */
   /* is flushed to shared memory and the local copy of __TI_ft_end is       */
   /* invalidated before leaving the critical section.                       */
   /*------------------------------------------------------------------------*/

   /*------------------------------------------------------------------------*/
   /* If _fp is not a NULL pointer, call __TI_doflush for that stream.       */
   /* Otherwise, call __TI_doflush for all file streams in the table that are*/
   /* active.                                                                */
   /*------------------------------------------------------------------------*/
   if (_fp) 
   {
      __TI_file_lock(_fp);
      result = __TI_doflush(_fp);
      __TI_data_synch_WBINV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
   }
   else
   {
      int index;
      __TI_resource_lock(__TI_LOCK_FILE_TBL);
      for(index = 0; index < __TI_ft_end; index++)
         if(_ftable[index].fd != -1) 
         {
            __TI_file_lock(&_ftable[index]);
            result |= __TI_doflush(&_ftable[index]);
            __TI_data_synch_WBINV(&_ftable[index], sizeof(_ftable[index]));
            __TI_file_unlock(&_ftable[index]);
         }
      __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
      __TI_data_synch_INV(&__TI_ft_end, sizeof(__TI_ft_end));
      __TI_resource_unlock(__TI_LOCK_FILE_TBL);
   }

   return (result);
}
Beispiel #13
0
_CODE_ACCESS int rand(void)
{
     int r;

     /*---------------------------------------------------------------------*/
     /* To maintain backwards compatibility with releases that do not use   */
     /* TLS, we use a mutex lock to protect accesses to the variable 'next'.*/
     /*---------------------------------------------------------------------*/
#if !defined(__TI_USE_TLS)
     __TI_resource_lock(__TI_LOCK_RAND);
#endif
     next = next * 1103515245 + 12345;
     r = (int)((next/65536) % ((unsigned long)RAND_MAX + 1));
#if !defined(__TI_USE_TLS)
     __TI_resource_unlock(__TI_LOCK_RAND);
#endif
     return r;
}
Beispiel #14
0
_CODE_ACCESS int HOSTunlink(const char *path)
{
   int result;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);

   __TI_writemsg(_DTUNLINK,parmbuf,(char *)path,strlen(path) + 1);
   __TI_readmsg(parmbuf,NULL);

   result = UNLOADSHORT(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return result;
}
Beispiel #15
0
_CODE_ACCESS int HOSTclose(int dev_fd)
{
   int result;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);

   LOADSHORT(parmbuf,dev_fd,0);

   __TI_writemsg(_DTCLOSE,parmbuf,NULL,0);
   __TI_readmsg(parmbuf,NULL);

   result = UNLOADSHORT(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return result;
}
Beispiel #16
0
_CODE_ACCESS int unlink(const char *path)
{
   _DEVICE *dev;
   int      result;

   /*------------------------------------------------------------------------*/
   /* GET A DEVICE AND CALL FUNCTION FROM DEVICE TABLE TO PERFORM UNLINK     */
   /* FOR THIS DEVICE/FILE                                                   */
   /*------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS _device[] ACCESS THAT OCCURS IN getdevice()   */
   /* (see file header comment for more on mutex and data coherence).        */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_DEVICE_TBL);

   dev = getdevice(&path);
   result = (*(dev->UNLINK)) (path);

   __TI_data_synch_INV(&_device, sizeof(_device));
   __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);

   return result;
}
Beispiel #17
0
__bool uncaught_exception() THROW_NOTHING()
/*
Return TRUE if an exception is in the process of being thrown.
*/
{
  an_eh_stack_entry_ptr	ehsep;
  __bool		result;

  /* This function is used instead of simply using __curr_eh_stack_entry
     because of a problem using this variable in code that also uses
     it via generated EH code. */
  ehsep = __get_curr_eh_stack_entry();

/*** START TI ADD ***/
  __TI_resource_lock(__TI_LOCK_ATEXIT);
/*** END TI ADD ***/

  /* TRUE should be returned if uncaught_exception() is called after
     terminate() has been called by the implementation. */
  result = terminate_called_by_runtime;

/*** START TI ADD ***/
  __TI_data_synch_WBINV(&terminate_called_by_runtime,
                        sizeof(terminate_called_by_runtime));
  __TI_resource_unlock(__TI_LOCK_ATEXIT);
/*** END TI ADD ***/

  for (; result == FALSE && ehsep != NULL; ehsep = ehsep->next) {
    if (ehsep->kind == ehsek_throw_processing_marker) {
      /* We are processing a throw.  An exception cannot be thrown here
         without resulting in a call to terminate().  Note that this is
         TRUE even if a try block is nested inside the throw processing
         marker. */
      result = TRUE;
    }  /* if */
  }  /* for */
  return result;
}  /* uncaught_exception */
Beispiel #18
0
_CODE_ACCESS int HOSTopen(const char *path, unsigned flags, int llv_fd)
{
   int dev_fd;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);


   LOADSHORT(parmbuf,llv_fd,0);
   LOADSHORT(parmbuf,flags,2);
   __TI_writemsg(_DTOPEN,parmbuf,(char *)path,strlen(path)+1);
					 /* SEND NULL ACROSS ALSO */
   __TI_readmsg(parmbuf,NULL);

   dev_fd = UNLOADSHORT(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return (dev_fd < 0) ? dev_fd : llv_fd;
}
Beispiel #19
0
_CODE_ACCESS off_t HOSTlseek(int dev_fd, off_t offset, int origin)
{
   off_t result;

   /*-----------------------------------------------------------------------*/
   /* CRITICAL REGION TO PROTECT ACCESSES TO parmbuf[] AND _CIOBUF_ (see    */
   /* file header comment above for more about mutexes and data coherency). */
   /*-----------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_HOST_CIO);

   LOADSHORT(parmbuf,dev_fd,0);
   LOAD32(parmbuf,offset,2);
   LOADSHORT(parmbuf,origin,6);

   __TI_writemsg(_DTLSEEK,parmbuf,NULL,0);
   __TI_readmsg(parmbuf,NULL);

   result = UNLOAD32(parmbuf,0);

   __TI_data_synch_WBINV(&parmbuf, sizeof(parmbuf));
   __TI_resource_unlock(__TI_LOCK_HOST_CIO);

   return result;
}
Beispiel #20
0
_CODE_ACCESS
int add_device(char     *name,
               unsigned  flags,
               int     (*dopen)  (const char *path, unsigned flags, int llv_fd),
               int     (*dclose) (int dev_fd),
               int     (*dread)  (int dev_fd, char *buf, unsigned count),
               int     (*dwrite) (int dev_fd, const char *buf, unsigned count),
               off_t   (*dlseek) (int dev_fd, off_t offset, int origin),
               int     (*dunlink)(const char *path),
               int     (*drename)(const char *old_name, const char *new_name))
{
   static _DATA_ACCESS int device_init = 0;
   _DEVICE *dt;

   /*-------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS ACCESS TO _device[]                            */
   /*-------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_DEVICE_TBL);

   /*-------------------------------------------------------------------------*/
   /* INITIALIZE DEVICE TABLE FIRST TIME AROUND                               */
   /*-------------------------------------------------------------------------*/
   if (!device_init)
   {
      for (device_init = 1, dt = &_device[1]; dt != &_device[_NDEVICE]; 
            *(dt++)->name = '\0');
       __TI_data_synch_WBINV(&device_init, sizeof(device_init));
   }

   /*-------------------------------------------------------------------------*/
   /* IF DEVICE WITH SPECIFIED 'name' ALREADY EXISTS IN _device[], THEN WE    */
   /* CAN'T ADD A NEW ONE WITH THE SAME NAME (note that the function pointers */
   /* associated with the existing device are not updated).                   */
   /*-------------------------------------------------------------------------*/
   if (finddevice(name)) 
   {
      __TI_data_synch_INV(&_device, sizeof(_device));
      __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
      return 1;
   }

   /*-------------------------------------------------------------------------*/
   /* SEARCH THE DEVICE TABLE FOR AN EMPTY SLOT, RETURN -1 IF NONE FOUND      */
   /*-------------------------------------------------------------------------*/
   for (dt = &_device[1]; dt != _device+_NDEVICE && dt->name[0] != '\0'; ++dt);
   if (dt == &_device[_NDEVICE]) 
   { 
      __TI_data_synch_INV(&_device, sizeof(_device));
      __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
      return -1; 
   }

   strncpy(dt->name,name,8);
   dt->name[8] = '\0';
   dt->flags   = flags;
   dt->OPEN    = dopen;
   dt->CLOSE   = dclose;
   dt->READ    = dread;
   dt->WRITE   = dwrite;
   dt->LSEEK   = dlseek;
   dt->UNLINK  = dunlink;
   dt->RENAME  = drename;

   __TI_data_synch_WBINV(&_device, sizeof(_device));
   __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);


   return 0;
}
Beispiel #21
0
_CODE_ACCESS int open(const char *path, unsigned flags, int mode)
{
   static _DATA_ACCESS int stream_init = 0;
   struct stream_info *ptr;
   _DEVICE    	      *dev;
   int        	      dev_fd;
   int        	      llv_fd;

   /*-------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS ACCESS TO _stream[] (see file header comment). */
   /*-------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_STREAM_TBL);

   /*-------------------------------------------------------------------------*/
   /* INITIALIZE STREAM TABLE FIRST TIME AROUND                               */
   /*-------------------------------------------------------------------------*/
   if (!stream_init)
   {
      for (stream_init = 1, ptr = &_stream[3]; ptr != &_stream[_NSTREAM]; 
            (ptr++)->dev = NULL);
       __TI_data_synch_WBINV(&stream_init, sizeof(stream_init));
   }

   /*-------------------------------------------------------------------------*/
   /* GET THE NEXT AVAILABLE FILE DESCRIPTOR - RETURN -1 IF NONE AVAILABLE    */
   /*-------------------------------------------------------------------------*/
   for (ptr = &_stream[3]; ptr != &_stream[_NSTREAM] && ptr->dev; ++ptr);
   if (ptr == &_stream[_NSTREAM]) 
   { 
      __TI_data_synch_INV(&_stream, sizeof(_stream));
      __TI_resource_unlock(__TI_LOCK_STREAM_TBL);
      return -1;
   }

   llv_fd = ptr - &_stream[0];

   /*------------------------------------------------------------------------*/
   /* GET DEVICE AND PEFORM OPEN - SET STREAM TABLE ENTRY AND FLAGS          */
   /*------------------------------------------------------------------------*/
   /* CRITICAL REGION PROTECTS _device[] ACCESS THAT OCCURS IN getdevice()   */
   /* (see file header comment for more on mutex and data coherence).        */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_DEVICE_TBL);

   dev    = getdevice(&path);
   dev_fd = (dev->flags & _BUSY) ? -1 : (*(dev->OPEN))(path,flags,llv_fd);

   if (dev_fd < 0) 
   { 
      __TI_data_synch_INV(&_stream, sizeof(_stream));
      __TI_data_synch_INV(&_device, sizeof(_device));
      __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
      __TI_resource_unlock(__TI_LOCK_STREAM_TBL);
      return dev_fd;
   }
   
   _stream[llv_fd].dev = dev;
   _stream[llv_fd].dfd = dev_fd;
   if (!(dev->flags & _MSA)) dev->flags |= _BUSY;

   __TI_data_synch_WBINV(&_stream, sizeof(_stream));
   __TI_data_synch_WBINV(&_device, sizeof(_device));
   __TI_resource_unlock(__TI_LOCK_DEVICE_TBL);
   __TI_resource_unlock(__TI_LOCK_STREAM_TBL);

   return llv_fd;
}
Beispiel #22
0
_CODE_ACCESS int setvbuf(register FILE *_fp, register char *_buf,
			 register int _type, register size_t _size)
{
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to the file stream. In this case, _fp may be updated, so we must       */
   /* ensure that the local copy of _fp is flushed to shared memory before   */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_file_lock(_fp);

   /*------------------------------------------------------------------------*/
   /* If the current stream is not associated with a file, return an error.  */
   /*------------------------------------------------------------------------*/
   if (_fp->fd == -1 || (_type != _IONBF && _size <= 0)) 
   { 
      __TI_data_synch_INV(_fp, sizeof(FILE));
      __TI_file_unlock(_fp);
      return (EOF);
   }

   /*------------------------------------------------------------------------*/
   /* If a buffer already exists, free it if it was malloc'd, and reset all  */
   /* of the stream's buffer pointers.                                       */
   /*------------------------------------------------------------------------*/
   if (_fp->buf)
   {
      if(_STCHK(_fp, _BUFFALOC)) free((_fp->buf)-1);
      _UNSET(_fp, _BUFFALOC);
      _fp->buf = NULL;
      _fp->pos = NULL;
      _fp->bufend = NULL;
      _fp->buff_stop = NULL;
   }

   /*------------------------------------------------------------------------*/
   /* If NULL was used for the buffering mode, default to fully-buffered.    */
   /*------------------------------------------------------------------------*/
   if (!_type) _type = _IOFBF;

   /*------------------------------------------------------------------------*/
   /* Clear any previous buffering flags, and set the new one.               */
   /*------------------------------------------------------------------------*/
   _UNSET(_fp, (_IOLBF | _IOFBF | _IONBF));
   _SET(_fp, _type);

   /*------------------------------------------------------------------------*/
   /* If a buffer was provided, but its size is only one byte, allocate a    */
   /* different one.  Also, do not allow a buffer size greater than BUFSIZ.  */
   /* The buffer will always have one space at the beginning that is         */
   /* for UNGETC, in the event that an UNGETC is performed on an empty file, */
   /* or when the buffer is full, but unread.                                */
  /*------------------------------------------------------------------------*/
   if (_size == 1) _buf = NULL;
   if (_size > BUFSIZ) _size = BUFSIZ;

   if (_buf) _fp->buf = (unsigned char*)_buf+1;
   else
   {
      /*---------------------------------------------------------------------*/
      /* If allocating a buffer, provide _size bytes of usable space by      */
      /* incrementing _size, unless it is greater than BUFSIZ.               */
      /*---------------------------------------------------------------------*/
      if (_size <= BUFSIZ) _size++;
      if (! (_fp->buf = (unsigned char*)malloc(_size))) 
      {
         _SET(_fp, _STATERR);
         __TI_data_synch_WBINV(_fp, sizeof(FILE));
         __TI_file_unlock(_fp);
         return (EOF);
      }
      _fp->buf++;
      _SET(_fp, _BUFFALOC);
   }

   _fp->pos = _fp->buff_stop = _fp->buf;
   _fp->bufend = _fp->buf + _size -1;
   
   __TI_data_synch_WBINV(_fp, sizeof(FILE));
   __TI_file_unlock(_fp);

   /*------------------------------------------------------------------------*/
   /* SETUP _CLEANUP_PTR SO ALL BUFFERS WILL BE FLUSHED AT EXIT.             */
   /*------------------------------------------------------------------------*/
   /* __TI_cleanup_ptr is also a shared resource in multi-threaded           */
   /* applications, so accesses to it are also protected by the              */
   /* __TI_LOCK_FILE_TBL mutex.  The current thread will also invalidate any */
   /* local copy of __TI_cleanup_ptr in the data cache of the core that it   */
   /* is running on before leaving the critical section.                     */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_FILE_TBL);
   __TI_cleanup_ptr = __TI_cleanup;
   __TI_data_synch_WBINV(&__TI_cleanup_ptr, sizeof(__TI_cleanup_ptr));
   __TI_resource_unlock(__TI_LOCK_FILE_TBL);

   return (0);
}
Beispiel #23
0
_CODE_ACCESS int fgetc(register FILE *_fp)
{
   int retval = EOF;

   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to __TI_LOCK_FILE_TBL shared resources (_ftable[], _ft_end, and        */
   /* _tmpnams[]). In this case, _ftable[] may be updated, so we must ensure */
   /* that the local copy of _ftable[] is flushed to shared memory before    */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_FILE_TBL);

   /*------------------------------------------------------------------------*/
   /* Make sure that it is OK to read from this stream.                      */
   /*------------------------------------------------------------------------*/
   if (!_rd_ok(_fp)) goto fgetc_exit;
   
   /*------------------------------------------------------------------------*/
   /* For non-buffered streams, call the lowlevel READ function.             */
   /*------------------------------------------------------------------------*/
   if (_BUFFMODE(_fp) == _IONBF)
   {
      int   errchk;
      char  result;

      if (_STCHK(_fp, _UNGETC)) 
      {
         _UNSET(_fp, _UNGETC);
	 retval = (int)*(_fp->pos++);
	 goto fgetc_exit;
      }

      errchk = read(_fp->fd, &result, 1);

      if (errchk <= 0)
      {
         _SET(_fp, (errchk == 0) ? _STATEOF : _STATERR);
	 goto fgetc_exit;
      }

      retval = (int)result;
      goto fgetc_exit;
   }

   /*------------------------------------------------------------------------*/
   /* If the buffer has been entirely read, or is empty, call _BUFF_READ to  */
   /* fill the buffer.                                                       */
   /*------------------------------------------------------------------------*/
   if (_fp->pos == _fp->buff_stop) _buff_read(_fp);
 
   /*------------------------------------------------------------------------*/
   /* If the buffer read was unsuccessful, return an EOF.  Otherwise, clear  */
   /* the _UNGETC flag in the stream, and return the next character.         */
   /*------------------------------------------------------------------------*/
   if (_STCHK(_fp, (_STATERR | _STATEOF))) goto fgetc_exit;

   _UNSET(_fp, _UNGETC);
   retval = *(_fp->pos++);

fgetc_exit:
   __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
   __TI_resource_unlock(__TI_LOCK_FILE_TBL);

   return (retval);
   
}
Beispiel #24
0
_CODE_ACCESS size_t fread(void *_ptr, size_t _size, size_t _count, FILE *_fp)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   unsigned char     *fpos       = (unsigned char *)_ptr;
            size_t   num_left    = _size * _count,
                     num_read    = 0,
                     num_to_read = 0;
 
   /*------------------------------------------------------------------------*/
   /* The current thread in a multi-threaded application must protect access */
   /* to __TI_LOCK_FILE_TBL shared resources (_ftable[], _ft_end, and        */
   /* _tmpnams[]). In this case, _ftable[] may be updated, so we must ensure */
   /* that the local copy of _ftable[] is flushed to shared memory before    */
   /* leaving the critical section (invalidated if it is not modified).      */
   /*------------------------------------------------------------------------*/
   __TI_resource_lock(__TI_LOCK_FILE_TBL);

   /*------------------------------------------------------------------------*/
   /* Make sure that the file is readable.                                   */
   /*------------------------------------------------------------------------*/
   if (!_rd_ok(_fp) || _size == 0 || _count == 0) 
   { 
      __TI_data_synch_INV(&_ftable, sizeof(_ftable));
      __TI_resource_unlock(__TI_LOCK_FILE_TBL); 
      return (0);
   }
 
   /*------------------------------------------------------------------------*/
   /* If the stream is non-buffered, call the lowlevel READ function.	     */
   /*------------------------------------------------------------------------*/
   if (_BUFFMODE(_fp) == _IONBF)
   {
       int num_read = 0;

       while (num_left > 0)
       {
	   int read_return; 

           if (_STCHK(_fp, _UNGETC))
	   {
	      *fpos = *(_fp->pos++); 
	      _UNSET(_fp, _UNGETC);
	      read_return = 1;
	   }
	   else 
	      read_return = (size_t)(read(_fp->fd, 
					   (char *)fpos + num_read, num_left));
	   if (read_return < 0)
	   {
	       _SET(_fp, _STATERR);
	       break;
	   }
	   else if (read_return == 0) 
	   {
	       _SET(_fp, _STATEOF);
	       break;
	   }
	   else 
	   {
	       num_read += read_return;
	       num_left -= read_return;
	   }
       }

       __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
       __TI_resource_unlock(__TI_LOCK_FILE_TBL);
       return (num_read / _size);
   }
   
   while (num_left > 0)
   {
      /*---------------------------------------------------------------------*/
      /* If the buffer has been completely read, fill it up.  Exit the loop  */
      /* if an I/O error occurs, or the end of the file is reached.          */
      /*---------------------------------------------------------------------*/
      if(_fp->pos == _fp->buff_stop)  _buff_read(_fp);
      if(_STCHK(_fp, (_STATERR | _STATEOF))) break;

      /*---------------------------------------------------------------------*/
      /* Determine how many characters can fit in the buffer, and read them  */
      /* in.                                                                 */
      /*---------------------------------------------------------------------*/
      num_to_read = (num_left < (_fp->buff_stop - _fp->pos)) ?
                    num_left : (_fp->buff_stop - _fp->pos);
      memcpy(fpos, _fp->pos, num_to_read);

      /*---------------------------------------------------------------------*/
      /* Update pointers and counters.                                       */
      /*---------------------------------------------------------------------*/
      fpos += num_to_read;
      _fp->pos += num_to_read;
      num_read += num_to_read;
      num_left -= num_to_read; 
   }

   /*------------------------------------------------------------------------*/
   /* Clear the _UNGETC flag in the stream, and return the number of blocks  */
   /* read.                                                                  */
   /*------------------------------------------------------------------------*/
   _UNSET(_fp, _UNGETC);
   __TI_data_synch_WBINV(&_ftable, sizeof(_ftable));
   __TI_resource_unlock(__TI_LOCK_FILE_TBL);
 
   return (num_read / _size);
}