Show
Ignore:
Timestamp:
07/16/07 03:30:29 (17 months ago)
Author:
krobillard
Message:

Atoms should now be thread safe. First thread experiment runs.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/thune/thread_safe/context.c

    r427 r431  
    2525 
    2626#define LOWERCASE(c)    if(c >= 'A' && c <= 'Z') c -= 'A' - 'a' 
     27 
     28 
     29/* 
     30   UrlanEnv::atoms & UrlanEnv::atomNames can be made thread safe through one 
     31   of the following: 
     32 
     33   1. Use LOCK_ATOMS in or around these functions: 
     34        ur_internT() 
     35        ur_atomStrT() 
     36        ur_atomCStrT() (and all use of returned pointer) 
     37        ur_atomHash() 
     38        dumpAtoms() 
     39 
     40   2. Fix size of atom arrays and throw error/assert when full. 
     41      Must still lock these functions to access head/chain AtomRec members: 
     42        ur_internT() 
     43        dumpAtoms() 
     44 
     45   Option #2 is currently being used. 
     46*/ 
    2747 
    2848 
     
    120140void dumpAtoms( UThread* ut ) 
    121141{ 
    122     LOCK_GLOBAL 
     142    LOCK_ATOMS 
    123143    { 
    124144    const char* names = ut->env->atomNames.ptr.c; 
     
    143163    } 
    144164    } 
    145     UNLOCK_GLOBAL 
     165    UNLOCK_ATOMS 
    146166} 
    147167#endif 
     
    151171  Add atom to environment. 
    152172 
    153   If the environment has multiple threads, the caller must have called 
    154   LOCK_GLOBAL. 
    155  
    156173  \param str  Name of atom. 
    157174  \param len  Number of characters. 
    158175 
    159   \returns Atom  
     176  \return  Atom  
    160177*/ 
    161178UAtom ur_internT( UThread* ut, const char* str, int len ) 
     
    171188    AtomRec* node; 
    172189 
    173  
    174190    assert( len > 0 ); 
    175191 
    176192 
    177193    // Check if atom already exists. 
     194 
     195    hash = ur_hash( str, str + len ); 
     196 
     197    LOCK_ATOMS 
    178198 
    179199    atoms = &ut->env->atoms; 
    180200    table = (AtomRec*) atoms->ptr.v; 
    181201    names = &ut->env->atomNames; 
    182  
    183     hash = ur_hash( str, str + len ); 
    184202 
    185203    node = table + (hash % atoms->avail); 
     
    228246    // Nope, add new atom. 
    229247 
    230     /* TODO: Make atoms & atomNames thread safe through one of the following: 
    231  
    232        1. Halt all other threads. 
    233        2. Fix size of atom arrays and throw error/assert when full. 
    234        3. Use LOCK_GLOBAL in or around these functions in addition to ur_intern: 
    235             ur_atomStrT() 
    236             ur_atomCStrT() 
    237             dumpAtoms() 
    238     */ 
    239  
    240248    if( atoms->used == atoms->avail ) 
    241249    { 
     250#if 1 
     251        // Atom table size is fixed so read only access does not need to be 
     252        // locked.  When the table is full, we are finished. 
     253        assert( 0 && "Atom table is full" ); 
     254        return 0;       // TODO: Report fatal error 
     255#else 
    242256        ur_arrayReserve( atoms, sizeof(AtomRec), atoms->used + 1 ); 
    243257        ur_rebuildAtomHash( atoms ); 
     
    245259 
    246260        HASH_INSERT( atoms, table, node, hash, atoms->used ) 
     261#endif 
    247262    } 
    248263    node = table + atoms->used; 
     
    253268    node->nameLen   = len; 
    254269 
     270#if 1 
     271    if( (names->used + len + 1) > names->avail ) 
     272    { 
     273        assert( 0 && "Atom name buffer is full" ); 
     274        return 0;       // TODO: Report fatal error 
     275    } 
     276#else 
    255277    ur_arrayReserve( names, sizeof(char), names->used + len + 1 ); 
     278#endif 
     279 
    256280    cp = names->ptr.c + names->used; 
    257281    ep = cp + len; 
     
    267291done: 
    268292 
    269     return node - table; 
     293    c = node - table; 
     294 
     295    UNLOCK_ATOMS 
     296 
     297    return c; 
    270298} 
    271299 
     
    278306  If added, the word is initialied as unset. 
    279307 
    280   \returns  Index of word in context. 
     308  \return  Index of word in context. 
    281309*/ 
    282310int ur_internWordT( UThread* ut, const UContext* ctx, UAtom atom ) 
     
    424452/** 
    425453  Find word in context by atom. 
    426   \returns  Word index or -1 if not found. 
     454  \return  Word index or -1 if not found. 
    427455*/ 
    428456int ur_lookupT( UThread* ut, const UContext* ctx, UAtom atom )