Changeset 1072 for trunk/dll/fortify.c


Ignore:
Timestamp:
Jul 17, 2008, 7:39:14 PM (17 years ago)
Author:
Steven Levine
Message:

Add Fortify_SetOwner Fortify_ChangeOwner to support cross thread allocations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dll/fortify.c

    r1019 r1072  
    4343 /* 06 May 08 SHL Rework scope logic to be MT capable
    4444    26 May 08 SHL Show TID for leaking scope
     45    17 Jul 08 SHL Add Fortify_SetOwner Fortify_ChangeOwner
    4546 */
    4647
     
    6465
    6566
    66 #if defined(__WATCOMC__) && defined(_MT)
    67 #define MT_SCOPES 1
     67#ifdef MT_SCOPES
    6868unsigned long Get_TID_Ordinal(void);
    6969// Get tib_ptib2 from TIB
     
    100100    struct Header *Next;        /* Next link                         */
    101101    char          *Label;       /* User's Label (may be null)        */
    102     unsigned char  Scope;       /* Scope level of the caller         */
     102    unsigned char  Scope;       /* Scope level of the owner          */
    103103    unsigned char  Allocator;   /* malloc/realloc/new/etc            */
    104104#   ifdef MT_SCOPES
    105     unsigned short Ordinal;     /* TID ordinal of caller             */
     105    unsigned short Owner;       /* TID ordinal of block owner        */
    106106#   endif
    107107};
    108108
    109109#define FORTIFY_HEADER_SIZE ROUND_UP(sizeof(struct Header), sizeof(unsigned short))
    110 
    111110
    112111
     
    177176static unsigned long  st_LastVerifiedLine;
    178177#ifdef MT_SCOPES
    179 static unsigned volatile st_cScopes;
    180 static unsigned volatile char*  st_pScopes;
     178static unsigned volatile st_cOrdinals;          // Number of known threads
     179static unsigned volatile char*  st_pScopes;     // Scope level of blocks allocated by thread
     180static unsigned volatile long*  st_pOwners;     // Owner of blocks allocated by thread
    181181#else
    182182static unsigned char  st_Scope            = 0;
     
    416416#   ifdef MT_SCOPES
    417417    ordinal = Get_TID_Ordinal();
     418    // In case owner overridden by Fortify_SetOwner
     419    if (ordinal < st_cOrdinals)
     420        ordinal = st_pOwners[ordinal];
    418421#   endif
    419422
     
    428431    h->Prev      = 0;
    429432#   ifdef MT_SCOPES
    430     h->Scope     = ordinal < st_cScopes ? st_pScopes[ordinal] : 0;
    431     h->Ordinal = ordinal;
     433    h->Scope     = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0;
     434    h->Owner = ordinal;
    432435#   else
    433436    h->Scope     = st_Scope;
     
    690693#ifdef MT_SCOPES
    691694    ordinal = Get_TID_Ordinal();
    692     if (ordinal < st_cScopes && st_pScopes[ordinal] > 0)
     695    if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0)
    693696#else
    694697    if(st_Scope > 0)
     
    977980#ifdef MT_SCOPES
    978981    unsigned ordinal = Get_TID_Ordinal();
    979 
    980     if (ordinal >= st_cScopes) {
    981         st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * (st_cScopes = (ordinal + 1)));
    982         st_pScopes[ordinal] = 0;
     982    unsigned i;
     983    unsigned c;
     984
     985    if (ordinal >= st_cOrdinals) {
     986        // Expand arrays
     987        FORTIFY_LOCK();
     988        i = st_cOrdinals;
     989        c = ordinal + 1;
     990        st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c);
     991        st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c);
     992        for (; i <= ordinal; i++) {
     993            st_pScopes[i] = 0;          // Default to scope level 0
     994            st_pOwners[i] = i;          // Default block owner to self
     995        }
     996        st_cOrdinals = c;
     997        FORTIFY_UNLOCK();
    983998    }
    984999    return(++st_pScopes[ordinal]);
     
    10101025    // Complain on leave without enter 06 May 08 SHL
    10111026    ordinal = Get_TID_Ordinal();
    1012     if (ordinal < st_cScopes && st_pScopes[ordinal] > 0)
     1027    if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0)
    10131028        st_pScopes[ordinal]--;
    10141029    else {
     
    10291044    {
    10301045#ifdef MT_SCOPES
    1031         if(curr->Ordinal == ordinal && ordinal < st_cScopes && curr->Scope > st_pScopes[ordinal])
     1046        if(curr->Owner == ordinal && ordinal < st_cOrdinals && curr->Scope > st_pScopes[ordinal])
    10321047#else
    10331048        if(curr->Scope > st_Scope)
     
    10711086     */
    10721087#ifdef MT_SCOPES
    1073     st_PurgeDeallocatedScope( ordinal < st_cScopes ? st_pScopes[ordinal] : 0,
     1088    st_PurgeDeallocatedScope( ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0,
    10741089                              file, line );
    10751090#else
     
    10801095    FORTIFY_UNLOCK();
    10811096#ifdef MT_SCOPES
    1082     return(ordinal < st_cScopes ? st_pScopes[ordinal] : 0);
     1097    return(ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0);
    10831098#else
    10841099    return(st_Scope);
     
    17001715        next = curr->Next;
    17011716#ifdef MT_SCOPES
    1702         if(curr->Ordinal == ordinal && curr->Scope >= Scope)
     1717        if(curr->Owner == ordinal && curr->Scope >= Scope)
    17031718#else
    17041719        if(curr->Scope >= Scope)
     
    23992414#endif /* __cplusplus */
    24002415
     2416#ifdef MT_SCOPES
     2417
     2418/**
     2419 * Set/reset owner of blocks allocated by this thread
     2420 * Use when worker thread will allocate blocks for another thread
     2421 * and other thread is known
     2422 * More efficient than Fortify_ChangeOwner
     2423 * @param lOwnerTID is new owner TID, -1 requests reset of self
     2424 */
     2425
     2426void Fortify_SetOwner(long lOwnerTID)
     2427{
     2428    unsigned ordinal = Get_TID_Ordinal();
     2429
     2430    if (ordinal >= st_cOrdinals) {
     2431        // Expand arrays
     2432        unsigned i;
     2433        unsigned c;
     2434        FORTIFY_LOCK();
     2435        i = st_cOrdinals;
     2436        c = ordinal + 1;
     2437        st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c);
     2438        st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c);
     2439        for (; i <= ordinal; i++) {
     2440            st_pScopes[i] = 0;
     2441            st_pOwners[i] = i;          // Block owner is self
     2442        }
     2443        st_cOrdinals = c;
     2444        FORTIFY_UNLOCK();
     2445    }
     2446    // Set owner for blocks allocated by this thread
     2447    st_pOwners[ordinal] = lOwnerTID != -1 ? lOwnerTID : ordinal;
     2448}
     2449
     2450/**
     2451 * Take ownership of block allocated by some other thread
     2452 * Allows scope enter/exit logic to correctly report leaks in
     2453 * cross thread allocations
     2454 * @param pVoid is point to block allocated by Fortify
     2455 */
     2456
     2457void Fortify_ChangeOwner(void *pBlock)
     2458{
     2459    unsigned char *ptr = (unsigned char *)pBlock -
     2460                             FORTIFY_HEADER_SIZE -
     2461                             FORTIFY_ALIGNED_BEFORE_SIZE;
     2462    struct Header *h = (struct Header *)ptr;
     2463
     2464    unsigned ordinal = Get_TID_Ordinal();
     2465
     2466    h->Scope = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0;
     2467    h->Owner = ordinal;         // Take ownership
     2468}
     2469
     2470#endif // MT_SCOPES
     2471
    24012472#endif /* FORTIFY */
Note: See TracChangeset for help on using the changeset viewer.