Ticket #256: stream_panic.3.diff

File stream_panic.3.diff, 20.7 KB (added by dmik, 12 years ago)

Fixed assertions in kmk in -j >=2 mode plus some optiimizations

  • src/emx/include/emx/io.h

     
    237237{
    238238    if (!stream_validate(stream))
    239239        return 0;
    240     if (   !(stream->_flags & _IOLOCKED)
    241         || !_fmutex_is_owner(&stream->__u.__fsem))
     240    if (!_fmutex_is_owner(&stream->__u.__fsem))
    242241    {
    243242        if (_fmutex_request(&stream->__u.__fsem, _FMR_IGNINT) != 0)
    244243        {
    245244            __stream_abort(stream, "fmutex_request failed");
    246245            return 0;
    247246        }
    248         stream->_flags = 0x01000000 | (stream->_flags & ~_IOLOCKED);
     247        if ((stream->_flags & _IOLOCKED))
     248        {
     249            __stream_abort(stream, "lock, count not 0");
     250            return 0;
     251        }
    249252    }
    250253    else
    251         stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED);
     254    {
     255        if ((stream->_flags & _IOLOCKED) == _IOLOCKED)
     256        {
     257            __stream_abort(stream, "lock, count overflow");
     258            return 0;
     259        }
     260    }
     261    stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED);
    252262    return 1;
    253263}
    254264
     
    256266{
    257267    if (!stream_validate(stream))
    258268        return 0;
    259     if (   !(stream->_flags & _IOLOCKED)
    260         || !_fmutex_is_owner(&stream->__u.__fsem))
     269    if (!_fmutex_is_owner(&stream->__u.__fsem))
    261270    {
    262271        if (_fmutex_request(&stream->__u.__fsem, _FMR_NOWAIT) != 0)
    263272        {
    264273            __stream_abort(stream, "fmutex_request failed");
    265274            return 0;
    266275        }
    267         stream->_flags = 0x01000000 | (stream->_flags & ~_IOLOCKED);
     276        if ((stream->_flags & _IOLOCKED))
     277        {
     278            __stream_abort(stream, "lock, count not 0");
     279            return 0;
     280        }
    268281    }
    269282    else
    270         stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED);
     283    {
     284        if ((stream->_flags & _IOLOCKED) == _IOLOCKED)
     285        {
     286            __stream_abort(stream, "lock, count overflow");
     287            return 0;
     288        }
     289    }
     290    stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED);
    271291    return 1;
    272292}
    273293
     
    275295{
    276296    if (!stream_validate(stream))
    277297        return 0;
    278     if (!(stream->_flags & _IOLOCKED))
    279     {
    280         __stream_abort(stream, "unlock, 0 count");
    281         return 0;
    282     }
    283298#ifdef __LIBC_STRICT
    284299    if (!_fmutex_is_owner(&stream->__u.__fsem))
    285300    {
     
    287302        return 0;
    288303    }
    289304#endif
     305    if (!(stream->_flags & _IOLOCKED))
     306    {
     307        __stream_abort(stream, "unlock, 0 count");
     308        return 0;
     309    }
    290310    stream->_flags = ((stream->_flags & _IOLOCKED) - 0x01000000) | (stream->_flags & ~_IOLOCKED);
    291311    if (   !(stream->_flags & _IOLOCKED)
    292312        && _fmutex_release(&stream->__u.__fsem) != 0)
     
    302322#define STREAM_LOCK_NOWAIT(f)   stream_trylock(f)
    303323#define STREAM_UNLOCKED(f)      ((f)->__uVersion == _FILE_STDIO_VERSION && _fmutex_available(&(f)->__u.__fsem))
    304324
     325typedef struct __STREAM_XCPTREGREC
     326{
     327    void *apv[2]; // EXCEPTIONREGISTRATIONRECORD
     328    struct __sFILE *file;
     329    unsigned fs;
     330} __STREAM_XCPTREGREC, *__STREAM_PXCPTREGREC;
     331
     332void __stream_xcpt_init(__STREAM_PXCPTREGREC pRegRec);
     333void __stream_xcpt_done(__STREAM_PXCPTREGREC pRegRec);
     334
     335#define STREAM_XCPT_BEGIN       { __STREAM_XCPTREGREC __stream_xcptregec; __stream_xcpt_init(&__stream_xcptregec);
     336#define STREAM_XCPT_END         __stream_xcpt_done(&__stream_xcptregec); }
     337
     338#define STREAM_XCPT_LOCK(f)         do { __stream_xcptregec.file = f; stream_lock(f); } while (0)
     339#define STREAM_XCPT_UNLOCK(f)       do { stream_unlock(f); __stream_xcptregec.file = NULL; } while (0)
     340#define STREAM_XCPT_LOCK_NOWAIT(f)  (stream_trylock(f) ? (__stream_xcptregec.file = f, 1) : 0)
     341#define STREAM_XCPT_UNLOCK_END(f)   do { stream_unlock(f); __stream_xcptregec.file = NULL; __stream_xcpt_done(&__stream_xcptregec); } while (0)
     342#define STREAM_XCPT_NOLOCK_END()    do { __stream_xcpt_done(&__stream_xcptregec); } while(0)
     343
    305344#endif /* __FILE_FSEM_DECLARED */
    306345
    307346struct __libc_FileHandle;
  • src/emx/src/lib/app/stdio.c

     
    11/* stdio.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
    22                     -- Copyright (c) 2003-2004 by knut st. osmundsen */
    33
     4#define INCL_DOSEXCEPTIONS
     5#include <os2emx.h>
     6
    47#include "libc-alias.h"
    58#include <sys/builtin.h>        /* For <sys/fmutex.h> */
    69#include <sys/fmutex.h>
     
    157160_CRT_EXIT1(_exit_streams)
    158161
    159162
     163#if defined (__FILE_FSEM_DECLARED)
    160164
    161165/**
    162166 * Fatal stream error.
     
    180184    return 0;
    181185}
    182186
     187/**
     188 * Exception handler for STREAM_XCPT_LOCK()/STREAM_XCPT_UNLOCK().
     189 *
     190 * Releases the stream lock on thread termination.
     191 */
     192ULONG __stream_exception(EXCEPTIONREPORTRECORD *report,
     193                         EXCEPTIONREGISTRATIONRECORD *registration,
     194                         CONTEXTRECORD *context,
     195                         void *dummy);
     196ULONG __stream_exception(EXCEPTIONREPORTRECORD *report,
     197                         EXCEPTIONREGISTRATIONRECORD *registration,
     198                         CONTEXTRECORD *context,
     199                         void *dummy)
     200{
     201    __STREAM_PXCPTREGREC pRegRec = (__STREAM_PXCPTREGREC)registration;
     202
     203    if (report->fHandlerFlags & EH_UNWINDING)
     204    {
     205        if (pRegRec->file)
     206        {
     207            // make sure we won't be called again
     208            DosUnsetExceptionHandler(registration);
     209            // unlock the stream mutex
     210            STREAM_UNLOCK(pRegRec->file);
     211        }
     212    }
     213    return XCPT_CONTINUE_SEARCH;
     214}
     215
     216void __stream_xcpt_init(__STREAM_PXCPTREGREC pRegRec)
     217{
     218    __asm__ __volatile__ ("movl %%fs, %%eax; movl %%eax,%0; movl $DosTIB, %%eax; movl %%eax, %%fs" : : "m" (pRegRec->fs) : "%eax" );
     219
     220    ((PEXCEPTIONREGISTRATIONRECORD)pRegRec)->prev_structure = 0;
     221    ((PEXCEPTIONREGISTRATIONRECORD)pRegRec)->ExceptionHandler = __stream_exception;
     222    pRegRec->file = 0;
     223    DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)pRegRec);
     224}
     225
     226void __stream_xcpt_done(__STREAM_PXCPTREGREC pRegRec)
     227{
     228    DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)pRegRec);
     229
     230    __asm__ __volatile__ ("movl %0, %%eax; movl %%eax,%%fs;" : : "m" (pRegRec->fs) : "%eax" );
     231}
     232
     233#endif /* __FILE_FSEM_DECLARED */
  • src/emx/src/lib/io/fflush.c

     
    7979      return result;
    8080    }
    8181
    82   STREAM_LOCK (stream);
     82  STREAM_XCPT_BEGIN
     83
     84  STREAM_XCPT_LOCK (stream);
    8385  result = fflush_unlocked (stream);
    84   STREAM_UNLOCK (stream);
     86  STREAM_XCPT_UNLOCK (stream);
     87
     88  STREAM_XCPT_END
     89
    8590  return result;
    8691}
  • src/emx/src/lib/io/fgetc.c

     
    1515
    1616int _STD(fgetc)(FILE *stream)
    1717{
    18     STREAM_LOCK(stream);
    19     int rc = _getc_inline(stream);
    20     STREAM_UNLOCK(stream);
     18    int rc;
     19
     20    STREAM_XCPT_BEGIN
     21
     22    STREAM_XCPT_LOCK(stream);
     23    rc = _getc_inline(stream);
     24    STREAM_XCPT_UNLOCK(stream);
     25
     26    STREAM_XCPT_END
     27
    2128    return rc;
    2229}
    2330
  • src/emx/src/lib/io/fgets.c

     
    1010
    1111char *_STD(fgets)(char *buffer, int n, FILE *stream)
    1212{
    13     STREAM_LOCK(stream);
    14     char *psz = fgets_unlocked(buffer, n, stream);
    15     STREAM_UNLOCK(stream);
     13    char *psz;
     14
     15    STREAM_XCPT_BEGIN
     16
     17    STREAM_XCPT_LOCK(stream);
     18    psz = fgets_unlocked(buffer, n, stream);
     19    STREAM_XCPT_UNLOCK(stream);
     20
     21    STREAM_XCPT_END
     22
    1623    return psz;
    1724}
    1825
  • src/emx/src/lib/io/flushall.c

     
    1212  int i, n;
    1313  struct streamvec *sv;
    1414
     15  STREAM_XCPT_BEGIN
     16
    1517  /* Ignore locked streams to avoid deadlock on process
    1618     termination. */
    1719
    1820  n = 0;
    1921  for (sv = _streamvec_head; sv != NULL; sv = sv->pNext)
    2022    for (i = 0; i < sv->cFiles; ++i)
    21       if ((sv->aFiles[i]._flags & _IOOPEN) && STREAM_LOCK_NOWAIT (&sv->aFiles[i]))
     23      if ((sv->aFiles[i]._flags & _IOOPEN) && STREAM_XCPT_LOCK_NOWAIT (&sv->aFiles[i]))
    2224        {
    2325          ++n;
    2426          fflush_unlocked (&sv->aFiles[i]);
    25           STREAM_UNLOCK (&sv->aFiles[i]);
     27          STREAM_XCPT_UNLOCK (&sv->aFiles[i]);
    2628        }
     29
     30  STREAM_XCPT_END
     31
    2732  return n;
    2833}
  • src/emx/src/lib/io/fprintf.c

     
    1414  int result;
    1515  void *tb;
    1616
     17  STREAM_XCPT_BEGIN
     18
    1719  va_start (arg_ptr, format);
    18   STREAM_LOCK (stream);
     20  STREAM_XCPT_LOCK (stream);
    1921  if (nbuf (stream))
    2022    _fbuf (stream);
    2123  _tmpbuf (stream, tb);
    2224  result = _output (stream, format, arg_ptr);
    2325  if (_endbuf (stream) != 0)
    2426    result = -1;
    25   STREAM_UNLOCK (stream);
     27  STREAM_XCPT_UNLOCK (stream);
    2628  va_end (arg_ptr);
     29
     30  STREAM_XCPT_END
     31
    2732  return result;
    2833}
  • src/emx/src/lib/io/fputc.c

     
    1616{
    1717    int r;
    1818
    19     STREAM_LOCK(stream);
     19    STREAM_XCPT_BEGIN
     20
     21    STREAM_XCPT_LOCK(stream);
    2022    r = _putc_inline(c, stream);
    21     STREAM_UNLOCK(stream);
     23    STREAM_XCPT_UNLOCK(stream);
     24
     25    STREAM_XCPT_END
     26
    2227    return r;
    2328}
    2429
     
    3136{
    3237    int r;
    3338
    34     STREAM_LOCK(stream);
     39    STREAM_XCPT_BEGIN
     40
     41    STREAM_XCPT_LOCK(stream);
    3542    r = _putc_inline(c, stream);
    36     STREAM_UNLOCK(stream);
     43    STREAM_XCPT_UNLOCK(stream);
     44
     45    STREAM_XCPT_END
     46
    3747    return r;
    3848}
  • src/emx/src/lib/io/fread.c

     
    1313
    1414size_t _STD(fread)(void *buffer, size_t size, size_t count, FILE *stream)
    1515{
    16     STREAM_LOCK(stream);
    17     size_t cb = fread_unlocked(buffer, size, count, stream);
    18     STREAM_UNLOCK(stream);
     16    size_t cb;
     17
     18    STREAM_XCPT_BEGIN
     19
     20    STREAM_XCPT_LOCK(stream);
     21    cb = fread_unlocked(buffer, size, count, stream);
     22    STREAM_XCPT_UNLOCK(stream);
     23
     24    STREAM_XCPT_END
     25
    1926    return cb;
    2027}
    2128
  • src/emx/src/lib/io/fscanf.c

     
    1313  va_list arg_ptr;
    1414  int result;
    1515
     16  STREAM_XCPT_BEGIN
     17
    1618  va_start (arg_ptr, format);
    17   STREAM_LOCK (stream);
     19  STREAM_XCPT_LOCK (stream);
    1820  result = _input (stream, format, arg_ptr);
    19   STREAM_UNLOCK (stream);
     21  STREAM_XCPT_UNLOCK (stream);
    2022  va_end (arg_ptr);
     23
     24  STREAM_XCPT_END
     25
    2126  return result;
    2227}
  • src/emx/src/lib/io/fseek.c

     
    182182{
    183183    int result;
    184184
    185     STREAM_LOCK (stream);
     185    STREAM_XCPT_BEGIN
     186
     187    STREAM_XCPT_LOCK (stream);
    186188    result = _fseek_unlocked (stream, offset, origin);
    187     STREAM_UNLOCK (stream);
     189    STREAM_XCPT_UNLOCK (stream);
     190
     191    STREAM_XCPT_END
     192
    188193    return result;
    189194}
    190195
  • src/emx/src/lib/io/ftell.c

     
    102102{
    103103  off_t off;
    104104
    105   STREAM_LOCK (stream);
     105  STREAM_XCPT_BEGIN
     106
     107  STREAM_XCPT_LOCK (stream);
    106108  off = _ftello_unlocked (stream);
    107   STREAM_UNLOCK (stream);
     109  STREAM_XCPT_UNLOCK (stream);
     110
     111  STREAM_XCPT_END
     112
    108113  return off;
    109114}
    110115
  • src/emx/src/lib/io/fwide.c

     
    4848    LIBCLOG_ENTER("pStream=%p iOrientation=%d\n", (void *)pStream, iOrientation);
    4949    int iRet = -1;
    5050#if 0 /** @todo LIBC07 */
    51     STREAM_LOCK(pStream);
     51    STREAM_XCPT_BEGIN
     52    STREAM_XCPT_LOCK(pStream);
    5253    if (iOrientation != 0 && pStream->__iOrientation == 0)
    5354        pStream->__iOrientation = iOrientation > 0 ? 1 : -1;
    5455    iRet =  pStream->__iOrientation;
    55     STREAM_UNLOCK(pStream);
     56    STREAM_XCPT_UNLOCK(pStream);
     57    STREAM_XCPT_END
    5658#endif
    5759    LIBCLOG_RETURN_INT(iRet);
    5860}
  • src/emx/src/lib/io/fwrite.c

     
    168168{
    169169  size_t r;
    170170
    171   STREAM_LOCK (stream);
     171  STREAM_XCPT_BEGIN
     172
     173  STREAM_XCPT_LOCK (stream);
    172174  r = fwrite_unlocked (buffer, size, count, stream);
    173   STREAM_UNLOCK (stream);
     175  STREAM_XCPT_UNLOCK (stream);
     176
     177  STREAM_XCPT_END
     178
    174179  return r;
    175180}
  • src/emx/src/lib/io/getdelim.c

     
    7676        *pcchString = 128;
    7777    }
    7878
    79     /*
    80      * Lock the stream and start reading.
    81      */
    82     STREAM_LOCK(pStream);
    8379    ssize_t rc = 0;
    8480    char *psz = *ppszString;
    8581    char *pszEnd = psz + *pcchString - 1;
     82
     83    STREAM_XCPT_BEGIN
     84
     85    /*
     86     * Lock the stream and start reading.
     87     */
     88    STREAM_XCPT_LOCK(pStream);
    8689    for (;;)
    8790    {
    8891        /** @todo this can be done faster by accessing what's in the buffer directly.
     
    117120        if (ch == chDelim)
    118121            break;
    119122    }
    120     STREAM_UNLOCK(pStream);
     123    STREAM_XCPT_UNLOCK(pStream);
     124
     125    STREAM_XCPT_END
    121126
    122127    if (!rc)
    123128        rc = psz - *ppszString;
  • src/emx/src/lib/io/gets.c

     
    3636
    3737char *_STD(gets)(char *buffer)
    3838{
    39     STREAM_LOCK(stdin);
    40     char *psz = gets_unlocked(buffer);
    41     STREAM_UNLOCK(stdin);
     39    char *psz;
     40
     41    STREAM_XCPT_BEGIN
     42
     43    STREAM_XCPT_LOCK(stdin);
     44    psz = gets_unlocked(buffer);
     45    STREAM_XCPT_UNLOCK(stdin);
     46
     47    STREAM_XCPT_END
     48
    4249    return psz;
    4350}
    4451
  • src/emx/src/lib/io/printf.c

     
    1414  int result;
    1515  void *tb;
    1616
     17  STREAM_XCPT_BEGIN
     18
    1719  va_start (arg_ptr, format);
    18   STREAM_LOCK (stdout);
     20  STREAM_XCPT_LOCK (stdout);
    1921  if (nbuf (stdout))
    2022    _fbuf (stdout);
    2123  _tmpbuf (stdout, tb);
    2224  result = _output (stdout, format, arg_ptr);
    2325  if (_endbuf (stdout) != 0)
    2426    result = -1;
    25   STREAM_UNLOCK (stdout);
     27  STREAM_XCPT_UNLOCK (stdout);
    2628  va_end (arg_ptr);
     29
     30  STREAM_XCPT_END
     31
    2732  return result;
    2833}
  • src/emx/src/lib/io/puts.c

     
    1111
    1212int _STD(puts) (const char *string)
    1313{
    14     STREAM_LOCK(stdout);
    15     int rc = puts_unlocked(string);
    16     STREAM_UNLOCK(stdout);
     14    int rc;
     15
     16    STREAM_XCPT_BEGIN
     17   
     18    STREAM_XCPT_LOCK(stdout);
     19    rc = puts_unlocked(string);
     20    STREAM_XCPT_UNLOCK(stdout);
     21   
     22    STREAM_XCPT_END
     23   
    1724    return rc;
    1825}
    1926
  • src/emx/src/lib/io/rewind.c

     
    99
    1010void _STD(rewind) (FILE *stream)
    1111{
    12   STREAM_LOCK (stream);
     12  STREAM_XCPT_BEGIN
     13  STREAM_XCPT_LOCK (stream);
    1314  fflush_unlocked (stream);
    1415  _fseek_unlocked (stream, 0, SEEK_SET);
    1516  stream->_flags &= ~_IOERR;
    16   STREAM_UNLOCK (stream);
     17  STREAM_XCPT_UNLOCK (stream);
     18  STREAM_XCPT_END
    1719}
  • src/emx/src/lib/io/scanf.c

     
    1313  va_list arg_ptr;
    1414  int result;
    1515
     16  STREAM_XCPT_BEGIN
     17
    1618  va_start (arg_ptr, format);
    17   STREAM_LOCK (stdin);
     19  STREAM_XCPT_LOCK (stdin);
    1820  result = _input (stdin, format, arg_ptr);
    19   STREAM_UNLOCK (stdin);
     21  STREAM_XCPT_UNLOCK (stdin);
    2022  va_end (arg_ptr);
     23
     24  STREAM_XCPT_END
     25
    2126  return result;
    2227}
  • src/emx/src/lib/io/setvbuf.c

     
    1313      || (mode != _IONBF && mode != _IOFBF && mode != _IOLBF))
    1414    return EOF;
    1515
    16   STREAM_LOCK (stream);
     16  STREAM_XCPT_BEGIN
     17
     18  STREAM_XCPT_LOCK (stream);
    1719  fflush_unlocked (stream);
    1820  if ((stream->_flags & _IOBUFMASK) == _IOBUFLIB)
    1921    free (stream->_buffer);
     
    4850      buffer = malloc (size);
    4951      if (buffer == NULL)
    5052        {
    51           STREAM_UNLOCK (stream);
     53          STREAM_XCPT_UNLOCK_END(stream);
    5254          return EOF;
    5355        }
    5456      stream->_buf_size = size;
     
    5860  stream->_ptr = stream->_buffer;
    5961  stream->_rcount = 0;
    6062  stream->_wcount = 0;
    61   STREAM_UNLOCK (stream);
     63  STREAM_XCPT_UNLOCK (stream);
     64
     65  STREAM_XCPT_END
     66
    6267  return 0;
    6368}
  • src/emx/src/lib/io/ungetc.c

     
    153153{
    154154  int result;
    155155
    156   STREAM_LOCK (stream);
     156  STREAM_XCPT_BEGIN
     157
     158  STREAM_XCPT_LOCK (stream);
    157159  result = _ungetc_nolock (c, stream);
    158   STREAM_UNLOCK (stream);
     160  STREAM_XCPT_UNLOCK (stream);
     161
     162  STREAM_XCPT_END
     163
    159164  return result;
    160165}
  • src/emx/src/lib/io/vfprintf.c

     
    1212  int result;
    1313  void *tb;
    1414
    15   STREAM_LOCK (stream);
     15  STREAM_XCPT_BEGIN
     16
     17  STREAM_XCPT_LOCK (stream);
    1618  if (nbuf (stream))
    1719    _fbuf (stream);
    1820  _tmpbuf (stream, tb);
    1921  result = _output (stream, format, arg_ptr);
    2022  if (_endbuf (stream) != 0)
    2123    result = -1;
    22   STREAM_UNLOCK (stream);
     24  STREAM_XCPT_UNLOCK (stream);
     25
     26  STREAM_XCPT_END
     27
    2328  return result;
    2429}
  • src/emx/src/lib/io/vfscanf.c

     
    1212{
    1313  int r;
    1414
    15   STREAM_LOCK (stream);
     15  STREAM_XCPT_BEGIN
     16
     17  STREAM_XCPT_LOCK (stream);
    1618  r = _input (stream, format, arg_ptr);
    17   STREAM_UNLOCK (stream);
     19  STREAM_XCPT_UNLOCK (stream);
     20
     21  STREAM_XCPT_END
     22
    1823  return r;
    1924}
  • src/emx/src/lib/io/vprintf.c

     
    1212  int result;
    1313  void *tb;
    1414
    15   STREAM_LOCK (stdout);
     15  STREAM_XCPT_BEGIN
     16
     17  STREAM_XCPT_LOCK (stdout);
    1618  if (nbuf (stdout))
    1719    _fbuf (stdout);
    1820  _tmpbuf (stdout, tb);
    1921  result = _output (stdout, format, arg_ptr);
    2022  if (_endbuf (stdout) != 0)
    2123    result = -1;
    22   STREAM_UNLOCK (stdout);
     24  STREAM_XCPT_UNLOCK (stdout);
     25
     26  STREAM_XCPT_END
     27
    2328  return result;
    2429}
  • src/emx/src/lib/io/vscanf.c

     
    1212{
    1313  int r;
    1414
    15   STREAM_LOCK (stdin);
     15  STREAM_XCPT_BEGIN
     16
     17  STREAM_XCPT_LOCK (stdin);
    1618  r = _input (stdin, format, arg_ptr);
    17   STREAM_UNLOCK (stdin);
     19  STREAM_XCPT_UNLOCK (stdin);
     20
     21  STREAM_XCPT_END
     22
    1823  return r;
    1924}