码迷,mamicode.com
首页 > 其他好文 > 详细

如何实现一个引用计数?

时间:2016-04-12 17:34:35      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

  • 要保证线程安全、要保证高效。
  • 这是一个跟芯片架构、编译器都相关的工作。
  • 剖析boost::detail::shared_ptr的计数实现机制:
// shared_ptr中的引用计数成员属性pn
boost::detail::shared_count pn;    // reference counter

// shared_count中的pi成员属性
sp_counted_base * pi_;

// sp_counted_base中的use_count_成员属性(取w32实现为例)
long use_count_;        // #shared

// 增减引用计数的w32平台具体实现
bool add_ref_lock() // true on success
    {
        for( ;; )
        {
            long tmp = static_cast< long const volatile& >( use_count_ );
            if( tmp == 0 ) return false;

#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )

            // work around a code generation bug

            long tmp2 = tmp + 1;
            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;

#else

            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;

#endif
        }
    }

    void release() // nothrow
    {
        if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
        {
            dispose();
            weak_release();
        }
    }

// 也有直接用汇编实现线程安全的自增自减,例如gcc编译器相关的mips架构下的实现

inline void atomic_increment( int * pw )
{
    // ++*pw;

    int tmp;

    __asm__ __volatile__
    (
        "0:\n\t"
        ".set push\n\t"
        ".set mips2\n\t"
        "ll %0, %1\n\t"
        "addiu %0, 1\n\t"
        "sc %0, %1\n\t"
        ".set pop\n\t"
        "beqz %0, 0b":
        "=&r"( tmp ), "=m"( *pw ):
        "m"( *pw )
    );
}

inline int atomic_decrement( int * pw )
{
    // return --*pw;

    int rv, tmp;

    __asm__ __volatile__
    (
        "0:\n\t"
        ".set push\n\t"
        ".set mips2\n\t"
        "ll %1, %2\n\t"
        "addiu %0, %1, -1\n\t"
        "sc %0, %2\n\t"
        ".set pop\n\t"
        "beqz %0, 0b\n\t"
        "addiu %0, %1, -1":
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
        "m"( *pw ):
        "memory"
    );

    return rv;
}
Created with Rapha?l 2.1.0shared_ptrshared_count sp_counted_base各平台实现结束

实际上,实现一个跨平台的引用计数相当困难,但是boost做到了。
各编译器-芯片架构平台列表如下,
技术分享
sp_counted_base_后面的部分即是编译器-芯片架构。例如sp_counted_base_acc_ia64,是acc编译器的ia64的CPU芯片架构。

为什么会与编译器和芯片架构都有关系?因为代码最终转为二进制代码时是通过编译器转的,而编译器如果对应不同芯片架构,没有实现统一的api接口,就需要与芯片架构相关。
而w32和clang都没有后缀对应的芯片架构,是指它们都实现了各种架构下的统一底层api。

如何实现一个引用计数?

标签:

原文地址:http://blog.csdn.net/lonelyrains/article/details/51134338

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!