2016-02-12 78 views
2

我想了解一個庫實現,但是某些方法是動態鏈接的方式,讓我感到困惑。 我知道使用派生類的對象但沒有對象的調度機制,我不知道它是如何工作的。 我想了解的庫是gcc的libitm在類之外聲明的方法的動態分派

頭文件libitm.h將所有ABI方法聲明爲沒有圍繞它們的類或結構的頂級方法。而且對於他們中的大多數人來說,我找到了一個獨特的定義,所以我對他們毫無疑問,並且在此省略。但下面的摘錄顯示了70種方法的聲明,這些定義讓我感到困惑。

typedef uint8_t _ITM_TYPE_U1; 
    typedef uint16_t _ITM_TYPE_U2; 
    typedef uint32_t _ITM_TYPE_U4; 
    typedef uint64_t _ITM_TYPE_U8; 
    typedef float _ITM_TYPE_F; 
    typedef double _ITM_TYPE_D; 
    typedef long double _ITM_TYPE_E; 
    typedef float _Complex _ITM_TYPE_CF; 
    typedef double _Complex _ITM_TYPE_CD; 
    typedef long double _Complex _ITM_TYPE_CE; 

    #define ITM_BARRIERS(T) \ 
     extern _ITM_TYPE_##T _ITM_R##T(const _ITM_TYPE_##T *) ITM_REGPARM; \ 
     extern _ITM_TYPE_##T _ITM_RaR##T(const _ITM_TYPE_##T *) ITM_REGPARM; \ 
     extern _ITM_TYPE_##T _ITM_RaW##T(const _ITM_TYPE_##T *) ITM_REGPARM; \ 
     extern _ITM_TYPE_##T _ITM_RfW##T(const _ITM_TYPE_##T *) ITM_REGPARM; \ 
     extern void _ITM_W##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM; \ 
     extern void _ITM_WaR##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM; \ 
     extern void _ITM_WaW##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM; 

    ITM_BARRIERS(U1) 
    ITM_BARRIERS(U2) 
    ITM_BARRIERS(U4) 
    ITM_BARRIERS(U8) 
    ITM_BARRIERS(F) 
    ITM_BARRIERS(D) 
    ITM_BARRIERS(E) 
    ITM_BARRIERS(CF) 
    ITM_BARRIERS(CD) 
    ITM_BARRIERS(CE) 

在文件dispatch.h一個結構abi_dispatch被聲明,其被用作用於TM-算法的特定調度的位置。在這個結構體中,上面70個方法的聲明是純虛擬方法。以下摘錄顯示了方法和結構的宏定義。

#define ITM_READ_M(T, LSMOD, M, M2)           \ 
    M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \ 
    {                   \ 
    return load(ptr, abi_dispatch::LSMOD);         \ 
    } 

#define ITM_READ_M_PV(T, LSMOD, M, M2)          \ 
    M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \ 
    = 0; 

#define ITM_WRITE_M(T, LSMOD, M, M2)       \ 
    M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \ 
        _ITM_TYPE_##T val) \ 
    {               \ 
    store(ptr, val, abi_dispatch::LSMOD);     \ 
    } 

#define ITM_WRITE_M_PV(T, LSMOD, M, M2)      \ 
    M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \ 
        _ITM_TYPE_##T val) \ 
    = 0; 

#define CREATE_DISPATCH_METHODS_T(T, M, M2) \ 
    ITM_READ_M(T, R, M, M2)    \ 
    ITM_READ_M(T, RaR, M, M2)    \ 
    ITM_READ_M(T, RaW, M, M2)    \ 
    ITM_READ_M(T, RfW, M, M2)    \ 
    ITM_WRITE_M(T, W, M, M2)    \ 
    ITM_WRITE_M(T, WaR, M, M2)    \ 
    ITM_WRITE_M(T, WaW, M, M2) 
#define CREATE_DISPATCH_METHODS_T_PV(T, M, M2) \ 
    ITM_READ_M_PV(T, R, M, M2)    \ 
    ITM_READ_M_PV(T, RaR, M, M2)    \ 
    ITM_READ_M_PV(T, RaW, M, M2)    \ 
    ITM_READ_M_PV(T, RfW, M, M2)    \ 
    ITM_WRITE_M_PV(T, W, M, M2)    \ 
    ITM_WRITE_M_PV(T, WaR, M, M2)    \ 
    ITM_WRITE_M_PV(T, WaW, M, M2) 

#define CREATE_DISPATCH_METHODS(M, M2) \ 
    CREATE_DISPATCH_METHODS_T (U1, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (U2, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (U4, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (U8, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (F, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (D, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (E, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (CF, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (CD, M, M2) \ 
    CREATE_DISPATCH_METHODS_T (CE, M, M2) 
#define CREATE_DISPATCH_METHODS_PV(M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (U1, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (U2, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (U4, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (U8, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (F, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (D, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (E, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (CF, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (CD, M, M2) \ 
    CREATE_DISPATCH_METHODS_T_PV (CE, M, M2) 

struct abi_dispatch 
{ 
public: 
    enum ls_modifier { NONTXNAL, R, RaR, RaW, RfW, W, WaR, WaW }; 

public: 
    CREATE_DISPATCH_METHODS_PV(virtual,) 
} 

abi_dispatch的衍生結構可以在例如method-mlmethod-gl找到。他們使用CREATE_DISPATCH_METHODS(virtual,)和上面的宏來生成70個讀/寫方法,並將它們映射到加載/存儲模板函數。

我的一個大問題是:當調用某個庫函數時,運行系統如何知道應該使用哪個方法定義(method-gl或method-ml中的那個)?在讀/寫方法的定義中,沒有提到abi_dispatch對象。在線程本地存儲中存在一個abi-dispatch對象,但我不知道如何適合這個。

謝謝你的幫助。

回答

2

找到了缺少的鏈接。

還有另一個宏(CREATE_DISPATCH_FUNCTIONS),它定義了來自上面的70個函數聲明並調用了派發對象中相應的方法。

相關問題