Changeset 318 for trunk/src


Ignore:
Timestamp:
Mar 15, 2011, 8:56:28 PM (14 years ago)
Author:
katerina
Message:

Fix for ticket #238: Avoid mutex in sl_create_ticket()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/slib.c

    r290 r318  
    15951595static char badfd_orig_mesg[128];
    15961596
    1597 SH_MUTEX_STATIC(mutex_ticket, PTHREAD_MUTEX_INITIALIZER);
    1598 
    1599 static unsigned int nonce_counter = TOFFSET;
    16001597
    16011598char * sl_check_stale()
     
    16221619}
    16231620
     1621typedef struct { volatile unsigned int atom; } atomic_t;
     1622static atomic_t nonce_counter = { TOFFSET };
     1623
     1624#if defined(__GNUC__) && (defined(__i486__) || defined(__x86_64__))
     1625/* from linux/include/asm-i386/atomic.h */
     1626static unsigned int atomic_add ( unsigned int i, atomic_t *var)
     1627{
     1628  unsigned int j = i;
     1629
     1630  __asm__ __volatile__ ("lock; xaddl %0, %1"
     1631                        : "+r" (i), "+m" (var->atom)
     1632                        : : "memory");
     1633  return j+i;
     1634}
     1635#else
     1636SH_MUTEX_STATIC(mutex_ticket, PTHREAD_MUTEX_INITIALIZER);
     1637
     1638static unsigned int atomic_add ( unsigned int i, atomic_t *var)
     1639{
     1640  volatile unsigned int j;
     1641
     1642  SH_MUTEX_LOCK_UNSAFE(mutex_ticket);
     1643  var->atom += i;
     1644  j = var->atom;
     1645  SH_MUTEX_UNLOCK_UNSAFE(mutex_ticket);
     1646
     1647  return j;
     1648}
     1649#endif
     1650
    16241651static
    16251652SL_TICKET sl_create_ticket (unsigned int myindex)
     
    16281655  unsigned int low;  /* nonce */
    16291656  SL_TICKET    retval = SL_EINTERNAL;
     1657  unsigned int nonce;/* nonce */
    16301658
    16311659  SL_ENTER(_("sl_create_ticket"));
     
    16481676    }
    16491677
    1650   SH_MUTEX_LOCK_UNSAFE(mutex_ticket);
    1651 
    1652   low = nonce_counter & 0xffff;
    1653 
    1654   /* Overflow -> nonce too big.
    1655    */
    1656   if ((low != nonce_counter++) || low == 0)
    1657     {
    1658       retval = SL_EINTERNAL03;
    1659       goto out_ticket;
    1660     }
    1661  
     1678  nonce = atomic_add(1, &nonce_counter);
     1679
    16621680  /* Wrap around the nonce counter.
    16631681   * This is a dirty trick.
    16641682   */
    1665   if (nonce_counter > 0x7fff)
    1666     nonce_counter = TOFFSET;
     1683  if (nonce > 0x7fff)
     1684    {
     1685      nonce_counter.atom = TOFFSET;
     1686      nonce = atomic_add(1, &nonce_counter);
     1687    }
     1688
     1689  low = nonce & 0xffff;
     1690
     1691  /* Overflow -> nonce too big.
     1692   */
     1693  if ((low != nonce) || low == 0)
     1694    {
     1695      retval = SL_EINTERNAL03;
     1696      goto out_ticket;
     1697    }
    16671698
    16681699  retval = (SL_TICKET) ((high << 16) | low);
    16691700
    16701701 out_ticket:
    1671   ;
    1672 
    1673   SH_MUTEX_UNLOCK_UNSAFE(mutex_ticket);
    16741702  SL_RETURN (retval, _("sl_create_ticket"));
    16751703}
Note: See TracChangeset for help on using the changeset viewer.