рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рдиреЛрдЯреЛрдВ рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЙрдХ-рдлреНрд░реА рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдореБрдЦреНрдп рдХрдард┐рдирд╛рдЗрдпрд╛рдБ ABA рд╕рдорд╕реНрдпрд╛ рдФрд░ рдореЗрдореЛрд░реА рдбрд┐рд▓реАрдЯ рд╣реИрдВред рдореИрдВ рдЗрди рджреЛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рддрд╛ рд╣реВрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВ: рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╣реИрдВ рдЬреЛ рдЙрдирдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдХреЛ рд╣рд▓ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рд▓реЙрдХ-рдореБрдХреНрдд рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд┐рдд рдореЗрдореЛрд░реА рд░рд┐рдХреНрд▓реЗрдореЗрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдореБрдЭреЗ рдЬреНрдЮрд╛рдд рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЕрд╡рд▓реЛрдХрди рджреВрдВрдЧрд╛ред рдореИрдВ рдорд╛рдЗрдХрд▓-рд╕реНрдХреЙрдЯ рдХреА рдХреНрд▓рд╛рд╕рд┐рдХ рд▓реЙрдХ-рдлреНрд░реА рдХрддрд╛рд░ [MS98] рдкрд░ рдЗрд╕ рдпрд╛ рдЙрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░реВрдВрдЧрд╛ред
рдЯреИрдЧ рдХрд┐рдП рдЧрдП рд╕рдВрдХреЗрдд
рдЯреИрдЧ рдХреА рдЧрдИ рдкреЙрдЗрдВрдЯрд░реНрд╕ рд╕реНрдХреАрдо рдЖрдИрдмреАрдПрдо рджреНрд╡рд╛рд░рд╛ ABA рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХреА рдЧрдИ рдереАред рд╢рд╛рдпрдж рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрд╣рд▓рд╛ рдЬреНрдЮрд╛рдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╣реИред
рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдкреНрд░рддреНрдпреЗрдХ рдкреЙрдЗрдВрдЯрд░ рдореЗрдореЛрд░реА рд╕реЗрд▓ рдФрд░ рдЙрд╕рдХреЗ рдЯреИрдЧ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрддреЗ рдХреА рдПрдХ рдЕрд╡рд┐рднрд╛рдЬреНрдп рдЬреЛрдбрд╝реА рд╣реИ - рдПрдХ 32-рдмрд┐рдЯ рдкреВрд░реНрдгрд╛рдВрдХред
template <typename T> struct tagged_ptr { T * ptr ; unsigned int tag ; tagged_ptr(): ptr(nullptr), tag(0) {} tagged_ptr( T * p ): ptr(p), tag(0) {} tagged_ptr( T * p, unsigned int n ): ptr(p), tag(n) {} T * operator->() const { return ptr; } };
рдЯреИрдЧ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рд▓реЗрдмрд▓ рдХрд┐рдП рдЧрдП рдкреЙрдЗрдВрдЯрд░ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреИрд╕ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ
рдХрднреА рднреА рд░реАрд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЕрд░реНрдерд╛рдд рдпрд╣ рд╕рдЦреНрддреА рд╕реЗ рдмрдврд╝рддрд╛ рд╣реИред рдХрдВрдЯреЗрдирд░ рд╕реЗ рдХрд┐рд╕реА рдЖрдЗрдЯрдо рдХреЛ рд╣рдЯрд╛рддреЗ рд╕рдордп, рднреМрддрд┐рдХ рд░реВрдк рд╕реЗ рдЖрдЗрдЯрдо рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдЗрдЯрдо рдХреЛ рдХреБрдЫ рдореБрдлреНрдд рд╕реВрдЪреА рдореЗрдВ рдореБрдлреНрдд рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрд╕реА рд╕рдордп, рдпрд╣ рдХрд╛рдлреА рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ рдпрджрд┐ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдореЗрдВ рд╕реНрдерд┐рдд рд░рд┐рдореЛрдЯ рдПрд▓реАрдореЗрдВрдЯ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реЙрдХ-рдлреНрд░реА рд╕реНрдЯреНрд░рдХреНрдЪрд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рдПрдХ рдереНрд░реЗрдб рдПрдХреНрд╕ рдПрд▓рд┐рдореЗрдВрдЯ рдХреЛ рд╣рдЯрд╛рддрд╛ рд╣реИ, рддреЛ рджреВрд╕рд░реЗ рдереНрд░реЗрдб рдореЗрдВ рд▓реЗрдмрд▓ рдкреЙрдЗрдВрдЯрд░ рдХреА рдПрдХреНрд╕ рдХреА рд▓реЛрдХрд▓ рдХреЙрдкреА рд╣реЛ рд╕рдХрддреА рд╣реИ рдФрд░ рдПрд▓реАрдореЗрдВрдЯ рдХреЗ рдлреАрд▓реНрдб рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред ред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рд╕реВрдЪреА рдЕрд▓рдЧ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдЯреА рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЬрдм рдПрдХ рддрддреНрд╡ рдХреЛ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдореЗрдВ рд░рдЦрдирд╛ рдХрдИ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЕрдиреБрдкрдпреБрдХреНрдд рд╣реИ (рд╕рдорд╡рд░реНрддреА рдкрд╣реБрдВрдЪ рдХреЗ рдХрд╛рд░рдг, рдПрдХ рдЕрдиреНрдп рдзрд╛рдЧрд╛ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдЗрд╕ рддрддреНрд╡ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝ рд╕рдХрддрд╛ рд╣реИ)ред
рдЯреИрдЧ рдХреА рдЧрдИ рдкреЙрдЗрдВрдЯрд░ рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдиреБрдХрд╕рд╛рди рд╣реИрдВ:
- рдпрд╣ рдпреЛрдЬрдирд╛ рдЙрди рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ, рдЬрд┐рди рдкрд░ рджреЛрд╣рд░реЗ рд╢рдмреНрдж (dwCAS) рдХреЗ рдКрдкрд░ рдПрдХ рдХреИрд╕ рдкрд░рдорд╛рдгреБ рдЖрджрд┐рдо рд╣реИред 32-рдмрд┐рдЯ рдЖрдзреБрдирд┐рдХ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдкреВрд░реА рд╣реЛ рдЧрдИ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ dwCAS 64-рдмрд┐рдЯ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рднреА рдЖрдзреБрдирд┐рдХ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореЗрдВ 64-рдмрд┐рдЯ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рдкреВрд░рд╛ рд╕реЗрдЯ рд╣реИред рд▓реЗрдХрд┐рди 64-рдмрд┐рдЯ рдСрдкрд░реЗрд╢рди рдореЛрдб рдХреЗ рд▓рд┐рдП, 128-рдмрд┐рдЯ (рдпрд╛ рдХрдо рд╕реЗ рдХрдо 96-рдмрд┐рдЯ) dwCAS рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╕рднреА рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рд╣рд╛рдБ, рдЖрдкрдиреЗ рдмрдХрд╡рд╛рд╕ рд▓рд┐рдЦрд╛, рдореЗрд░реЗ рджреЛрд╕реНрдд!рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд▓реЙрдХ-рдлреНрд░реА рдореЗрдВ рдкрд░рд┐рд╖реНрдХреГрдд рдЖрдкрддреНрддрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЯреИрдЧ рдХрд┐рдП рдЧрдП рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддреГрдд 128-рдмрд┐рдЯ (рдпрд╛ 96-рдмрд┐рдЯ) рдХреИрд╕ рд╣реЛрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдЖрдк 64-рдмрд┐рдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдЖрдзреБрдирд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрддреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ 48 рдмрд┐рдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдкрддреЗ рдХреЗ рдЙрдЪреНрдЪрддрдо 16 рдмрд┐рдЯ рдореБрдлреНрдд рд╣реИрдВ рдФрд░ рдЯреИрдЧ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЦреИрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣
boost.lockfree
рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рджреЛ "рдмрдЯ" рд╣реИрдВ:
- рдХреМрди рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдкрддреЗ рдХреЗ рдЗрди 16 рдмрд┐рдЯреНрд╕ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ? рдЬреИрд╕реЗ рд╣реА рдЕрдЧрд▓реА рд╕рдлрд▓рддрд╛ рдореЗрдореЛрд░реА рдЪрд┐рдкреНрд╕ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЖрддреА рд╣реИ рдФрд░ рдЗрд╕рдХреА рдорд╛рддреНрд░рд╛ рдкрд░рд┐рдорд╛рдг рдХреЗ рдПрдХ рдХреНрд░рдо рд╕реЗ рдмрдврд╝ рдЬрд╛рдПрдЧреА, рд╡рд┐рдХреНрд░реЗрддрд╛рдУрдВ рддреБрд░рдВрдд 64-рдмрд┐рдЯ рдкрддреЗ рдХреЗ рд╕рд╛рде рдирдП рдкреНрд░реЛрд╕реЗрд╕рд░ рдЬрд╛рд░реА рдХрд░реЗрдВрдЧреЗ
- рдХреНрдпрд╛ 16 рдмрд┐рдЯреНрд╕ рдЯреИрдЧ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ? рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдЕрдзреНрдпрдпрди рдХрд┐рдП рдЧрдП рдереЗ, рдФрд░ рдЗрди рдЕрдзреНрдпрдпрдиреЛрдВ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ: 16 рдмрд┐рдЯ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИрдВ, рдЕрддрд┐рдкреНрд░рд╡рд╛рд╣ рдХрд╛рдлреА рд╕рдВрднрд╡ рд╣реИ, рдЬреЛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдПрдмреАрдП рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди 32 рдмрд┐рдЯреНрд╕ рдХрд╛рдлреА рд╣реИред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, 16 рдмрд┐рдЯреНрд╕ 0 - 65535 рдЯреИрдЧ рдХреЗ рдорд╛рди рд╣реИрдВред рдЖрдзреБрдирд┐рдХ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ, рд╕реНрдЯреНрд░реАрдо рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рд╕рдордп рд╕реНрд▓реЙрдЯ 300-500 рд╣рдЬрд╛рд░ рдХреЛрдбрд╛рдВрддрд░рдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ (рд▓рд┐рдирдХреНрд╕ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкрддреНрд░рд╛рдЪрд╛рд░ рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛) рдХреЗ рдЖрджреЗрд╢ рдХрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдХреНрд╡рд╛рдВрдЯрдо рдХреЗрд╡рд▓ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдмрдврд╝рддреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдПрдХ рдорд╛рддреНрд░рд╛ рдореЗрдВ рдХреИрд╕ рдХреЗ рд░реВрдк рдореЗрдВ 65 рд╣рдЬрд╛рд░ рднреА рдРрд╕реЗ рднрд╛рд░реА рдСрдкрд░реЗрд╢рди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ (рдареАрдХ рд╣реИ, рдЕрдЧрд░ рдпрд╣ рдЖрдЬ рдЕрд╕рдВрднрд╡ рд╣реИ, рддреЛ рдпрд╣ рдХрд▓ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛)ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, 16-рдмрд┐рдЯ рдЯреИрдЧ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ ABA рд╕рдорд╕реНрдпрд╛ рд╣реЛрдиреЗ рдХрд╛ рдХрд╛рдлреА рдЦрддрд░рд╛ рд╣реИред
- рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рд▓реЙрдХ-рдлреНрд░реА рд╕реНрдЯреИрдХ рдпрд╛ рд▓реЙрдХ-рдлреНрд░реА рдХрддрд╛рд░ рд╣реИ, рдЬреЛ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдирдХрд╛рд░рд╛рддреНрдордХ рдпреЛрдЧрджрд╛рди рджреЗрддрд╛ рд╣реИ: рдХрдо рд╕реЗ рдХрдо рдПрдХ рдФрд░ рд╕реАрдПрдПрд╕ рдХреЙрд▓ рдЬрдм рдПрдХ рдЖрдЗрдЯрдо рдХреЛ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рджреВрд╕рд░реА рдУрд░, рдПрдХ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдХреА рдореМрдЬреВрджрдЧреА рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХреЛ рдмрдврд╝рд╛ рд╕рдХрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЖрдорддреМрд░ рдкрд░ рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдзреАрдорд╛ рдФрд░ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдкреНрд░рддреНрдпреЗрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рд╣реЛрдирд╛ рдХреБрдЫ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рдХреНрдЬрд░реА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рд╕реЗ рдореЗрдореЛрд░реА рдХрд╛ рдЕрдХреБрд╢рд▓ рдЙрдкрдпреЛрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдФрд╕рддрди рд▓реЙрдХ-рдлреНрд░реА рдХрддрд╛рд░ рдореЗрдВ 10 рддрддреНрд╡ рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╢рд┐рдЦрд░ рдореЗрдВ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ 1 рдорд┐рд▓рд┐рдпрди рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЪрд░рдо рдкрд░ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рдмрд╛рдж рдлреНрд░реА-рд▓рд┐рд╕реНрдЯ рдХрд╛ рдЖрдХрд╛рд░ рд▓рдЧрднрдЧ 1 рдорд┐рд▓рд┐рдпрди рд╕реНрдерд┐рд░ рд╣реЛрдЧрд╛ред рдЕрдХреНрд╕рд░ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЯреИрдЧ рдХреА рдЧрдИ рд╕реВрдЪрдХ рдпреЛрдЬрдирд╛ рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рдПрдмреАрдП рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддреА рд╣реИ рдФрд░ рд╕реНрдореГрддрд┐ рдХреЛ
рдореБрдХреНрдд рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдирд╣реАрдВ рдХрд░рддреА рд╣реИред
Libcds рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреИрдЧ рдХрд┐рдП рдЧрдП рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдЗрд╕рдХреА рд╕рд╛рдкреЗрдХреНрд╖ рд╕рд╛рджрдЧреА рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдпрд╣ рдпреЛрдЬрдирд╛ рдкреНрд░рддреНрдпреЗрдХ рдХрдВрдЯреЗрдирд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдореБрдлреНрдд-рд╕реВрдЪреА рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдХрд╛рд░рдг рдореЗрдореЛрд░реА рдЦрдкрдд рдореЗрдВ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рд╡реГрджреНрдзрд┐ рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддреА рд╣реИред Libcds рдореЗрдВ, рдореИрдВрдиреЗ dwCAS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛, рдЕрдиреБрдорд╛рдирд┐рдд рдореЗрдореЛрд░реА рдЦрдкрдд рдХреЗ рд╕рд╛рде рд▓реЙрдХ-рдлреНрд░реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд┐рдпрд╛ред
рдЯреИрдЧ рдХрд┐рдП рдЧрдП рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг
boost.lockfree
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИред
рдЯреИрдЧ рдХрд┐рдП рдЧрдП рд╕рдВрдХреЗрдд рдЙрджрд╛рд╣рд░рдг
рд╢реАрдЯ рдХреЗ рдкреНрд░рд╢рдВрд╕рдХ (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) - pseudocode
MSQueue
[MS98] рдЯреИрдЧ рдХрд┐рдП рдЧрдП рд╕реВрдЪрдХ рдХреЗ рд╕рд╛рдеред рд╣рд╛рдВ, рд▓реЙрдХ-рдлреНрд░реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдмрд╣реБрдд рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╣реИрдВ!
рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ
std:atomic
рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛
std:atomic
ред
template <typename T> struct node { tagged_ptr next; T data; } ; template <typename T> class MSQueue { tagged_ptr<T> volatile m_Head; tagged_ptr<T> volatile m_Tail; FreeList m_FreeList; public: MSQueue() {
рдЖрдЗрдП рдПрдиреНрдХреНрдпреВ рдФрд░ рдбреАрдХреНрдпреВ рдСрдкрд░реЗрд╢рди рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдкрд░ рдПрдХ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдЙрдирдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рд▓реЙрдХ-рдлреНрд░реА рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╕рдордп рдХрдИ рдорд╛рдирдХ рдЪрд╛рд▓ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╣реИ рдХрд┐ рджреЛрдиреЛрдВ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рд▓реВрдк рд╣реЛрддреЗ рд╣реИрдВ - рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкреВрд░рд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣рд┐рд╕реНрд╕рд╛ рддрдм рддрдХ рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рд╕рдлрд▓ рди рд╣реЛ (рдпрд╛ рд╕рдлрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдЕрд╕рдВрднрд╡ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЦрд╛рд▓реА рдХрддрд╛рд░ рд╕реЗ
dequeue
)ред рд▓реВрдк рдХреА рдорджрдж рд╕реЗ рдРрд╕реА "рд╕реНрд╡реЙрдЯрд┐рдВрдЧ" рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд▓реЙрдХ-рдлреНрд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рддрдХрдиреАрдХ рд╣реИред
рдХрддрд╛рд░ рдореЗрдВ рдкрд╣рд▓рд╛ рддрддреНрд╡ (
m_Head
рджреНрд╡рд╛рд░рд╛
m_Head
) рдПрдХ рдбрдореА рддрддреНрд╡ (рдбрдореА рдиреЛрдб) рд╣реИред рдПрдХ рдбрдореА рддрддреНрд╡ рд╣реЛрдиреЗ рд╕реЗ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрддрд╛рд░ рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдореЗрдВ рд╕рдВрдХреЗрдд рдХрднреА рднреА рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдПрдХ рдЦрд╛рд▓реА рдХрддрд╛рд░ рдХрд╛ рдПрдХ рд╕рдВрдХреЗрдд
m_Head == m_Tail && m_Tail->next == NULL
(рд▓рд╛рдЗрдиреЗрдВ D6-D8) рд╣реИред рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ (
m_Tail->next == NULL
) рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрддрд╛рд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╣рдо
m_Tail
рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВ , рд▓рд╛рдЗрди E9 рдХреЗрд╡рд▓
m_Tail->next
рдмрджрд▓рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ,
enqueue
рд╡рд┐рдзрд┐ рдХрддрд╛рд░ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддреА рд╣реИред рджрд░рдЕрд╕рд▓,
m_Tail
рдкреВрдВрдЫ рджреВрд╕рд░реА рд╡рд┐рдзрд┐ рдФрд░ / рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдереНрд░реЗрдб рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреА рд╣реИ: рддрддреНрд╡ рдЬрд╛рдБрдЪ (рд▓рд╛рдЗрди E8) рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ
enqueue
рдСрдкрд░реЗрд╢рди рдЬреЛ рдХрд┐
m_Tail
рдЕрдВрддрд┐рдо рддрддреНрд╡ (рдпрд╛рдиреА
m_Tail->next == NULL
) рдХреЛ
m_Tail->next == NULL
, рдФрд░ рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИ рдЗрд╕рд▓рд┐рдП, рд╕реВрдЪрдХ рдХреЛ рдЕрдВрдд рддрдХ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ (рд▓рд╛рдЗрди E12); рдЗрд╕реА рддрд░рд╣, рдЕрдкрдиреЗ "рддрддреНрдХрд╛рд▓ рдХрд░реНрддрд╡реНрдпреЛрдВ" рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ
m_Tail
рдмрджрд▓
m_Tail
рдпрджрд┐ рдпрд╣ рдХрддрд╛рд░ рдХреЗ рдЕрдВрдд рдореЗрдВ рдЗрдВрдЧрд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рд▓рд╛рдЗрди D9)ред рдпрд╣ рд╣рдореЗрдВ рд▓реЙрдХ-рдлреНрд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ - рдкреНрд░рд╡рд╛рд╣ рдХреА рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд╕рд╣рд╛рдпрддрд╛ (
рд╕рд╣рд╛рдпрддрд╛ ) рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рджрд┐рдЦрд╛рддрд╛ рд╣реИ: рдПрдХ рдСрдкрд░реЗрд╢рди рдХрд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрдВрдЯреЗрдирд░ рдХреЗ рд╕рднреА рд╕рдВрдЪрд╛рд▓рди рдкрд░ "рдзрдмреНрдмрд╛" рд╣реИ рдФрд░ рдПрдХ рдСрдкрд░реЗрд╢рди рдЗрд╕ рддрдереНрдп рдкрд░ рдмрд╣реБрдд рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдЕрдЧрд▓реЗ рдХреЙрд▓ рджреНрд╡рд╛рд░рд╛ рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рд╕рдВрднрд╡рддрдГ рдПрдХ рдФрд░) рдСрдкрд░реЗрд╢рди рдореЗрдВ ( рд╢рд╛рдпрдж) рдПрдХ рдФрд░ рдзрд╛рдЧрд╛ред
рдПрдХ рдЕрдиреНрдп рдореМрд▓рд┐рдХ рдЕрд╡рд▓реЛрдХрди: рд╕рдВрдЪрд╛рд▓рди рд╕реНрдерд╛рдиреАрдп рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рд╕рдВрдЪрдп рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рд▓рд╛рдЗрдиреЛрдВ рдХреЛ E5-E6, D2-D4)ред рддрдм (рд░реЗрдЦрд╛рдПрдБ E7, D5), рдореВрд▓ рд░реВрдк рд╕реЗ рдкрдврд╝реЗ рдЧрдП рдореВрд▓реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореВрд▓ рдХреЗ рд╕рд╛рде рдХреА рдЬрд╛рддреА рд╣реИ - рдПрдХ рдареЗрда рд▓реЙрдХ-рдлреНрд░реА рдЯреНрд░рд┐рдХ, рдЧреИрд░-рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЕрдирд╛рд╡рд╢реНрдпрдХ: рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдЧреБрдЬрд░реЗ рд╕рдордп рдХреЗ рджреМрд░рд╛рди, рдореВрд▓ рдорд╛рди рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдХрдВрдкрд╛рдЗрд▓рд░ рдХрддрд╛рд░ рдХреЗ рд╕рд╛рдЭрд╛ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдФрд░ "рд╕реНрдорд╛рд░реНрдЯ" рдХрдВрдкрд╛рдЗрд▓рд░ E7 рдпрд╛ D5 рддреБрд▓рдирд╛ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ),
m_Head
рдФрд░
m_Tail
рдХреЛ C ++ 11 (рдЫрджреНрдо-рдХреЛрдб -
volatile
) рдореЗрдВ
atomic
рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ CAS рдЖрджрд┐рдо рджрд┐рдП рдЧрдП рдПрдХ рдХреЗ рд╕рд╛рде рд▓рдХреНрд╖реНрдп рдкрддреЗ рдХреЗ рдореВрд▓реНрдп рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рд╡реЗ рд╕рдорд╛рди рд╣реИрдВ, рддреЛ рд▓рдХреНрд╖реНрдп рдкрддреЗ рдкрд░ рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдирдП рдореВрд▓реНрдп рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, CAS рдЖрджрд┐рдо рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рд╡рд░реНрддрдорд╛рди рдорд╛рди рдХреА рдПрдХ рд╕реНрдерд╛рдиреАрдп рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП;
CAS(&val, val, newVal)
рдХреЛ
CAS(&val, val, newVal)
рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рд╕рдлрд▓ рд╣реЛрдЧрд╛, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рдЧрд▓рддреА рд╣реИред
рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ
рдХрд┐ dequeue
рдХрдм dequeue
рд╡рд┐рдзрд┐ (рд▓рд╛рдЗрди D11) рдореЗрдВ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдЗрдЯрдо рдХреЛ рдХрддрд╛рд░ (рд▓рд╛рдЗрди D12) рд╕реЗ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рдПред рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдПрдХ рддрддреНрд╡ рдЕрдкрд╡рд╛рдж (рд▓рд╛рдЗрди D12 рдкрд░
m_Head
рдЕрдЧреНрд░рд┐рдо) рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдбреЗрдЯрд╛ (D11) рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред C ++ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрддрд╛рд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдбреЗрдЯрд╛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рд▓рд╛рдЗрди D11 рдореЗрдВ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдУрд╡рд░рд╣реЗрдб рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛ред рддрджрдиреБрд╕рд╛рд░, рдЙрдЪреНрдЪ рд▓реЛрдб рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рддрд╣рдд, рд╕реАрдПрдПрд╕ рдЖрджрд┐рдо рдХреА рд╡рд┐рдлрд▓рддрд╛ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред D11 рд▓рд╛рдЗрди рдХреЛ рд▓реВрдк рд╕реЗ рдмрд╛рд╣рд░ рд▓реЗ рдЬрд╛рдХрд░ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЛ "рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝" рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреА:
next
рддрддреНрд╡ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдереНрд░реЗрдб рд╕реЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдкреНрд░рд╢реНрди рдореЗрдВ рдХрддрд╛рд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЯреИрдЧреЗрдб рдкреЙрдЗрдВрдЯрд░ рд╕реНрдХреАрдо рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреЛ рдХрднреА рднреА рдирд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ "рдЕрдиреБрдХреВрд▓рди" рдЗрд╕ рддрдереНрдп рдХреЛ рдЬрдиреНрдо рджреЗрдЧрд╛ рдХрд┐ рд╣рдо
рдЧрд▓рдд рдбреЗрдЯрд╛ (рдбреА 12 рд▓рд╛рдЗрди рдХреЗ рд╕рдлрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдордп рдХрддрд╛рд░ рдореЗрдВ рдореМрдЬреВрдж рд▓реЛрдЧреЛрдВ рдХреЛ рдирд╣реАрдВ) рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдПрдо рдПрдВрдб рдПрд╕-рдХрддрд╛рд░ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, MSQueue
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЙрд╕ m_Head
рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдЬреЛ рд╣рдореЗрд╢рд╛ рдПрдХ рдбрдореА рдиреЛрдб рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдЧреИрд░-рдЦрд╛рд▓реА рдХрддрд╛рд░ рдХрд╛ рдкрд╣рд▓рд╛ рддрддреНрд╡ m_Head
рдмрд╛рдж рдЕрдЧрд▓рд╛ рддрддреНрд╡ рд╣реИред dequeue
рджреМрд░рд╛рди dequeue
рдкрд╣рд▓реЗ рддрддреНрд╡ рдХрд╛ рдорд╛рди рдПрдХ рдЧреИрд░-рд░рд┐рдХреНрдд рдХрддрд╛рд░ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ m_Head.next
, рдбрдореА рддрддреНрд╡ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓рд╛ рддрддреНрд╡ рдирдпрд╛ рдбрдореА рддрддреНрд╡ (рдФрд░ рдирдпрд╛ рд╣реЗрдб) рдмрди рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдЬрд┐рд╕рдХрд╛ рдореВрд▓реНрдп рд╣рдо рд╡рд╛рдкрд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЕрдЧрд▓реЗ dequeue
рдСрдкрд░реЗрд╢рди рдХреЗ рдмрд╛рдж рд╣реА рдХрд┐рд╕реА рддрддреНрд╡ рдХреЛ рднреМрддрд┐рдХ рд░реВрдк рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдпрджрд┐ рдЖрдк cds::intrusive::MSQueue
рдХреЗ рдШреБрд╕рдкреИрда рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рдорд╕реНрдпрд╛ cds::intrusive::MSQueue
ред
рдпреБрдЧ-рдЖрдзрд╛рд░рд┐рдд рдкреБрдирд░реНрд╡рд┐рдЪрд╛рд░
рдлреНрд░реЗрдЬрд░ [Fra03] рдиреЗ рдПрдХ
рдпреБрдЧ- рдЖрдзрд╛рд░рд┐рдд рдпреЛрдЬрдирд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХреАред рд╡рд┐рд▓рдВрдмрд┐рдд рд╡рд┐рд▓реЛрдкрди рдХреЛ рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдХреНрд╖рдг рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рдкреВрд░реНрдг рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╣рдЯрд╛рдП рдЧрдП рддрддреНрд╡ рдХреЗ рд▓рд┐рдВрдХ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдЧрд╛рд░рдВрдЯреА
рдпреБрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИ:
nGlobalEpoch
рдХрд╛ рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб
nThreadEpoch
рдЕрдкрдиреЗ рд╕реНрдерд╛рдиреАрдп рдпреБрдЧ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпреБрдЧ-рдЖрдзрд╛рд░рд┐рдд рдпреЛрдЬрдирд╛ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХреЛрдб рджрд░реНрдЬ рдХрд░рдиреЗ рдкрд░, рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рд╕реНрдерд╛рдиреАрдп рдпреБрдЧ рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдмрд╛рд░ рдЬрдм рд╕рднреА рдзрд╛рдЧреЗ рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рдореЗрдВ рдкрд╣реБрдВрдЪ рдЧрдП рд╣реИрдВ, рддреЛ
nGlobalEpoch
ред
рд╕реНрдХреАрдорд╛ рд╕реНрдпреВрдбреЛ рдХреЛрдб:
рд░рд┐рд▓реАрдЬрд╝ рдХрд┐рдП рдЧрдП рд▓реЙрдХ-рдлрд╝реНрд░реА рдХрдВрдЯреЗрдирд░ рддрддреНрд╡реЛрдВ рдХреЛ рдЙрди рдЖрдЗрдЯрдореЛрдВ рдХреА рдереНрд░реЗрдб-рд▓реЛрдХрд▓ рд╕реВрдЪреА рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ
m_arrRetired[m_nThreadEpoch % EPOCH_COUNT]
рд╣рдЯрд╛рдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЬреИрд╕реЗ рд╣реА рд╕рднреА рдкреНрд░рд╡рд╛рд╣
m_nGlobalEpoch
рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рд╕реЗ
m_nGlobalEpoch
, рд╕рднреА
m_nGlobalEpoch тАУ 1
рдХреА рд╕рднреА
m_nGlobalEpoch тАУ 1
рдпреБрдЧ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдореБрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рдореЗрдВ рд╣реА рд╡реГрджреНрдзрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИред
рдпреВрдкреАрдбреА 2016UPD 2016: рдЗрд╕ рдЫрджреНрдо рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж
рдкрд░рдлрд╝реЙрд░реНрдорд░ :
рдХреГрдкрдпрд╛ рд▓реЗрдЦ "рд▓реЙрдХ-рдлреНрд░реА рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ" рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рд╕реА рддреНрд░реБрдЯрд┐ рдХреЛ рдареАрдХ рдХрд░реЗрдВред рдЕрдВрджрд░ред рдореЗрдореЛрд░реА рдкреНрд░рдмрдВрдзрди рдпреЛрдЬрдирд╛рдПрдБ - "рдПрдХреНрдкреЛрдЪ-рдЖрдзрд╛рд░рд┐рдд рдкреБрдирд░реНрд╕реНрдорд░рдг" рдЕрдиреБрднрд╛рдЧ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓реЗрдВ () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрдерд╛рди рдкрд░, m_arrRetired [(m_nGlobalEpoch - 2)% ┬й_COUNT] рдХреЛ m_arrRetired [(m_nGlobalEpoch - 1)% ┬й_COUNT] рд╕реЗ рдмрджрд▓реЗрдВред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рдпреБрдЧ рдпрд╛ рддреЛ m_nGlobalEpoch рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдЙрди рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рд╡реЗрд╢ рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ), рдпрд╛ m_nGlobalEpoch + 1 (рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЦрдВрдб рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдзрд╛рд░рд╛рдПрдБ), рдФрд░ рдкреАрдврд╝реА m_nGlobalEpoch - 1 рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░ рдСрдкрд░реЗрд╢рди
ThreadEpoch::enter()
рдФрд░
ThreadEpoch::exit()
рдХреЙрд▓реНрд╕ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реИ, рдЬреЛ рдХрд┐ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реЗрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реИ:
lock_free_op( тАж ) { get_current_thread()->ThreadEpoch.enter() ; . . .
рдпрд╣ рдпреЛрдЬрдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд▓рд┐рдВрдХ (рдЬреЛ рдХрдВрдЯреЗрдирд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рднреАрддрд░ рд▓рд┐рдВрдХ рд╣реИ) рдХреЛ рддрд╛рд▓рд╛-рдореБрдХреНрдд рдХрдВрдЯреЗрдирд░ рддрддреНрд╡реЛрдВ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИред рдпрд╣ рдпреЛрдЬрдирд╛ рд╡реИрд╢реНрд╡рд┐рдХ рд▓рд┐рдВрдХ рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА (рдХрдВрдЯреЗрдирд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдмрд╛рд╣рд░), рдЕрд░реНрдерд╛рддреН, рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░ рдХреЗ рддрддреНрд╡реЛрдВ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдпреБрдЧ рдЖрдзрд╛рд░рд┐рдд рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдпреЛрдЬрдирд╛ рдХрд╛ рдиреБрдХрд╕рд╛рди рдпрд╣ рд╣реИ рдХрд┐
рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рд╡рд╛рд╣ рдЕрдЧрд▓реЗ рдпреБрдЧ рдореЗрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрд░реНрдерд╛рддреН, рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реЙрдХ-рдореБрдХреНрдд рдХрдВрдЯреЗрдирд░ рдХреА рдУрд░ рдореБрдбрд╝реЗрдВ; рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдзрд╛рдЧрд╛ рдЕрдЧрд▓реЗ рдпреБрдЧ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд▓рдВрдмрд┐рдд рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рд╣рдЯрд╛рдирд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдзрд╛рд░рд╛рдУрдВ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИ, рддреЛ рдирд┐рдореНрди-рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реА рдзрд╛рд░рд╛рдПрдБ рдЙрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реА рдзрд╛рд░рд╛рдУрдВ рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╕реНрдердЧрд┐рдд рд▓реЛрдЧреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рд╡реГрджреНрдзрд┐ рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддреА рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдпреБрдЧ-рдЖрдзрд╛рд░рд┐рдд рдпреЛрдЬрдирд╛ рдХрд╛ рдиреЗрддреГрддреНрд╡ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рдПрдХ рдзрд╛рдЧреЗ рдХреЗ рджреБрд░реНрдШрдЯрдирд╛рдЧреНрд░рд╕реНрдд рд╣реЛрдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдиреЗрддреГрддреНрд╡ рдХрд░реЗрдЧрд╛) рдЕрд╕реАрдорд┐рдд рд╕реНрдореГрддрд┐ рдЦрдкрдд рдХреЗ рд▓рд┐рдПред
Libcds рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдпреБрдЧ-рдЖрдзрд╛рд░рд┐рдд рдпреЛрдЬрдирд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдХрд╛рд░рдг: рдореИрдВ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рдкреНрд░рднрд╛рд╡реА рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рдерд╛ рдХрд┐ рдХреНрдпрд╛ рд╕рднреА рдкреНрд░рд╡рд╛рд╣ рд╡реИрд╢реНрд╡рд┐рдХ рдпреБрдЧ рдореЗрдВ рдкрд╣реБрдВрдЪреЗред рд╢рд╛рдпрдж рдкрд╛рдардХреЛрдВ рдореЗрдВ рд╕реЗ рдХреЛрдИ рдПрдХ рд╕рдорд╛рдзрд╛рди рд╕реБрдЭрд╛рдПрдЧрд╛?
рдЦрддрд░рд╛ рд╕реВрдЪрдХ
рдЗрд╕ рдпреЛрдЬрдирд╛ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдорд╛рдЗрдХрд▓ [Mic02a, Mic03] рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп
рд╕реНрдерд╛рдиреАрдп рд▓рд┐рдВрдХ рдХреЛ рд▓реЙрдХ-рдлреНрд░реА рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рддрддреНрд╡реЛрдВ рд╕реЗ рдмрдЪрд╛рдирд╛ рд╣реИред рд╢рд╛рдпрдж рдпрд╣ рд╕реНрдердЧрд┐рдд рд╣рдЯрд╛рдиреЗ рдХреА рд╕рдмрд╕реЗ рдкреНрд░рд╕рд┐рджреНрдз рдФрд░ рд╡рд┐рд╕реНрддреГрдд рдпреЛрдЬрдирд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рдкрд░рдорд╛рдгреБ рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдФрд░ рдХреИрд╕ рдХреА рддрд░рд╣ "рднрд╛рд░реА" рддреБрд▓реНрдпрдХрд╛рд▓рди рдЖрджрд┐рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдпреЛрдЬрдирд╛ рдХреА рдЖрдзрд╛рд░рд╢рд┐рд▓рд╛ рдпрд╣ рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓реЙрдХ-рдлрд╝реНрд░реА рдСрдкрд░реЗрд╢рди рдХреЗ рдЕрдВрджрд░ рдХрдВрдЯреЗрдирд░ рдХреЛ рд▓реЙрдХ-рдлреНрд░реА рдПрд▓рд┐рдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП
рдЦрд╝рддрд░рд╛ (рдЦрд╝рддрд░рдирд╛рдХ) рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдмрд╛рдзреНрдпрддрд╛ рд╣реИ, рдпрд╛рдиреА рдПрд▓реАрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рдПрд▓рд┐рдореЗрдВрдЯ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЗрд╕реЗ рд╡рд░реНрддрдорд╛рди рд╕реНрдЯреНрд░реАрдо рдХреЗ рдЦрддрд░реЛрдВ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЗ
HP
рд╕рд░рдгреА рдореЗрдВ рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ред
HP
рд╕рд░рдгреА рд╕реНрдЯреНрд░реАрдо рдХреЗ рд▓рд┐рдП рдирд┐рдЬреА рд╣реИ: рдХреЗрд╡рд▓ рд╕реНрд╡рд╛рдореА рд╕реНрдЯреНрд░реАрдо рдЗрд╕реЗ рд▓рд┐рдЦрддрд╛ рд╣реИ, рд╕рднреА рд╕реНрдЯреНрд░реАрдо рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ (
Scan
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ)ред рдпрджрд┐ рдЖрдк рд╡рд┐рднрд┐рдиреНрди рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдзреНрдпрд╛рди рджреЗрдВрдЧреЗ рдХрд┐
HP
рд╕рд░рдгреА (рдкреНрд░рддрд┐ рдереНрд░реЗрдб рдмрд┐рдВрджреБрдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛) рдХрд╛ рдЖрдХрд╛рд░ 3 - 4 рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ, рддрд╛рдХрд┐ рд╕рд░реНрдХрд┐рдЯ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд╣реЗрдб рдЫреЛрдЯрд╛ рд╣реЛред
рд╡рд┐рд╢рд╛рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдБрдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рдореЗрдВ, рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ 64 рд╕реЗ рдЕрдзрд┐рдХ рдЦрддрд░рдирд╛рдХ рдмрд┐рдВрджреБрдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╡рд╛рд▓реЗ "рд╡рд┐рд╢рд╛рд▓" рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдВ рд╣реИрдВред рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реНрдХрд┐рдк-рд▓рд┐рд╕реНрдЯ рд╣реИ ( cds::container::SkipListMap
) - рдПрдХ рд╕рдВрднрд╛рд╡реНрдп рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реВрдЪреА рдХреА рдПрдХ рд╕реВрдЪреА, рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд░ рдКрдВрдЪрд╛рдИ рдХреЗ рд╕рд╛рдеред рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрдВрдЯреЗрдирд░ рд╣рдЬрд╛рд░реНрдб рдкреЙрдЗрдВрдЯрд░ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ libcds рдореЗрдВ рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХрд┐рдк-рд╕реВрдЪреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред
рдЦрддрд░рд╛ рд╕реВрдЪрдХ рдЫрджреНрдо рдХреЛрдб [Mic02]:
рдЬрдм
pNode
рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░ рддрддреНрд╡ рдХреЗ
RetireNode(pNode)
рдХреЛ рд╣рдЯрд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ
j
dlist
рд▓рдВрдмрд┐рдд (рдЖрд╡рд╢реНрдпрдХ рдирд┐рд╖реНрдХрд╛рд╕рди) рддрддреНрд╡реЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП
dlist
рдХреЛ рд╕реНрдерд╛рдиреАрдп (рд╕реНрдЯреНрд░реАрдо
j
) рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реЗрдВред рдЬреИрд╕реЗ рд╣реА
dlist
рдХрд╛ рдЖрдХрд╛рд░
R рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ (
R, N = P*K
рдмрд░рд╛рдмрд░ рд╣реИ, рд▓реЗрдХрд┐рди
dlist
рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ; рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
R = 2N
),
Scan()
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд▓рдВрдмрд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдореЗрдВ рд▓рдЧреА рд╣реБрдИ рд╣реИред рд╢рд░реНрдд
R > P*K
рдЖрд╡рд╢реНрдпрдХ рд╣реИ: рдХреЗрд╡рд▓ рдЕрдЧрд░ рдпрд╣ рд╢рд░реНрдд рдкреВрд░реА рд╣реЛрддреА рд╣реИ, рддреЛ рдпрд╣ рдЧрд╛рд░рдВрдЯреА рд╣реИ рдХрд┐
Scan()
рд▓рдВрдмрд┐рдд рдбреЗрдЯрд╛ рд╕рд░рдгреА рд╕реЗ рдХреБрдЫ рднреА рдирд┐рдХрд╛рд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ
Scan()
рд╕рд░рдгреА рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣рдЯрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рддреНрд░реБрдЯрд┐ рдорд┐рд▓реЗрдЧреА - рд╕рд░рдгреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рднрд░реА рд╣реБрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рдХрдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
Scan()
рдореЗрдВ рдЪрд╛рд░ рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВред
- рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд░реНрддрдорд╛рди рдЦрддрд░рд╛
plist
рдХрд╛ plist
рд╕рд░рдгреА рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕рднреА рдЧреИрд░- null
рдЦрддрд░рдирд╛рдХ рдмрд┐рдВрджреБ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдкрд╣рд▓рд╛ рдЪрд░рдг рд╕рд╛рдЭрд╛ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ - HP
рдзрд╛рд░рд╛рдУрдВ рдХреА рд╕рд░рдгрд┐рдпрд╛рдБ - рд╢реЗрд╖ рдЪрд░рдг рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред - рд╕реНрдЯреЗрдЬ 2 рдмрд╛рдж рдХреА рдЦреЛрдЬреЛрдВ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
plist
рд╕рд░рдгреА рдХреЛ plist
; рдпрд╣рд╛рдБ рдЖрдк plist
рддрддреНрд╡реЛрдВ рдХреЛ рднреА рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред - рд╕реНрдЯреЗрдЬ 3 - рд╕реНрд╡рдпрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрдирд╛: рд╡рд░реНрддрдорд╛рди рдзрд╛рд░рд╛ рдХреЗ рд╕реВрдЪреА рдХреЗ рд╕рднреА рддрддреНрд╡ рджреЗрдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдпрджрд┐
dlist[i]
рддрддреНрд╡ plist
(рдЕрд░реНрдерд╛рдд, рдХреБрдЫ рдереНрд░реЗрдб рдЗрд╕ рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ dlist
рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЖрдк рдЗрд╕реЗ рд╣рдЯрд╛ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ dlist
рдореЗрдВ рд░рд╣рддрд╛ рд╣реИ (рдЗрд╕реЗ dlist
рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдЕрдиреНрдпрдерд╛, dlist[i]
рддрддреНрд╡ рдХреЛ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЗрд╕рдХреЗ рд╕рд╛рде рдПрдХ рднреА рдзрд╛рдЧрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред - рдЪрд░рдг 4
new_dlist
рд╕реЗ new_dlist
рдЧрдП dlist
рдХреЛ dlist
ред R > N
, Scan()
dlist
, - .
Hazard Pointer, , :
std::atomic<T *> atomicPtr ; тАж T * localPtr ; do { localPtr = atomicPtr.load(std::memory_order_relaxed); HP[i] = localPtr ; } while ( localPtr != atomicPtr.load(std::memory_order_acquire));
atomicPtr
localPtr
( )
HP[i]
HP
hazard- . , ,
atomicPtr
, ,
atomicPtr
localPtr
. ,
HP
( hazard)
atomicPtr
. Hazard Pointer' ( hazard), , .
Hazard Pointer (HP-) C++11 memory ordering [Tor08].
MSQueue Hazard PointerLock-free - [MS98] Hazard Pointer. тАЬтАЭ , libcds:
template <typename T> class MSQueue { struct node { std::atomic<node *> next ; T data; node(): next(nullptr) {} node( T const& v): next(nullptr), data(v) {} }; std::atomic<node *> m_Head; std::atomic<node *> m_Tail; public: MSQueue() { node * p = new node; m_Head.store( p, std::memory_order_release ); m_Tail.store( p, std::memory_order_release ); } void enqueue( T const& data ) { node * pNew = new node( data ); while (true) { node * t = m_Tail.load(std::memory_order_relaxed);
Hazard Pointer ?
? , , тАФ . : hazard pointer'
K . тАУ hazard pointer тАУ , , , hazard- . , hazard-. тАУ [Har01]. , HP- .
, HP-
hazard-. , . libcds , , , HP-. , тАФ
Pass the Buck , тАФ Hazard Pointer, hazard-. .
Hazard Pointer libcds
hazard pointer libcds. тАУ
Hazard Pointer Manager тАФ , libcds.dll/.so. тАФ
Thread HP Manager , тАФ HP hazard pointer'
K ()
Retired R .
Thread HP Manager .
P . libcds:
- hazard-
K = 8
P = 100
- ( )
R = 2 * K * P = 1600
.
libcds HP- :
- тАУ (
cds::gc::hzp
). ( T
), . , ( , ┬л┬╗ тАУ . , тАУ -, тАУ ┬л ┬╗. , , тАУ ). - тАУ ,
cds::gc::hzp
. (template) - , (- type erasure). - (API) тАУ
cds::gc::HP
. , ( ) lock-free libcds, , ( , ) GC
. cds::gc::HP
тАУ .
┬л┬╗ , , , ? : (, retired) :
struct retired_ptr { typedef void (* fnDisposer )( void * ); void * ptr ;
(
retired ) .
Scan()
HP-
pDisposer(ptr)
┬л┬╗ .
pDisposer
. . , :
template <typename T> struct make_disposer { static void dispose( void * p ) { delete reinterpret_cast<T *>(p); } }; template <typename T> void retire_ptr( T * p ) {
, , , .
HP- libcds,
main()
cds::gc::HP
, , HP-,
. , ,
cds::gc::HP
. API HP-.
API cds::gc::HPcds::gc::HP
тАУ , , .
- рдбрд┐рдЬрд╛рдЗрдирд░
HP(size_t nHazardPtrCount = 0, size_t nMaxThreadCount = 0, size_t nMaxRetiredPtrCount = 0, cds::gc::hzp::scan_type nScanType = cds::gc::hzp::inplace);
nHazardPtrCount
тАУ hazard pointer' ( K )
nMaxThreadCount
тАУ ( P )
nMaxRetiredPtrCount
тАУ retired- ( R = 2KP
)
nScanType
тАУ : cds::gc::hzp::classic
, Scan
; cds::gc::hzp::inplace
Scan()
new_dlist
dlist
( ).
, cds::gc::HP
. , cds::gc::HP
Hazard Pointer, , , .
- retired ( )
template <class Disposer, typename T> static void retire( T * p ) ; template <typename T> static void retire( T * p, void (* pFunc)(T *) )
Disposer
( pFunc
) (). :
struct Foo { тАж }; struct fooDisposer { void operator()( Foo * p ) const { delete p; } };
static void force_dispose();
Scan()
Hazard Pointer. , , libcds .
,
cds::gc::HP
:
thread_gc
тАУ (thread data), Hazard Pointer. , HP- , ,Guard
тАУ hazard pointertemplate <size_t Count> GuardArray
тАУ hazard pointer'. HP- hazard- . , Guard
Guard
GuardArray<N>
Hazard Pointer, . .
Guard
hazard- API:
template <typename T> T protect( CDS_ATOMIC::atomic<T> const& toGuard ); template <typename T, class Func> T protect( CDS_ATOMIC::atomic<T> const& toGuard, Func f );
( T
тАУ ) hazard. , : toGuard
, hazard pointer' , .
( Func
) , hazard T *
, . , (node), (, node
). Func
:
struct functor { value_type * operator()( T * p ) ; };
, hazard.
template <typename T> T * assign( T * p ); template <typename T, int Bitmask> T * assign( cds::details::marked_ptr<T, Bitmask> p );
p hazard. , protect
, , тАФ p
hazard-.
cds::details::marked_ptr
. marked- 2-3 ( 0 ) , тАФ lock-free . hazard- ( Bitmask
).
, hazard.
template <typename T> T * get() const;
hazard-. .
void copy( Guard const& src );
hazard- src
this
. hazard- .
void clear();
hazard-. Guard
.
GuardArray
API, :
template <typename T> T protect(size_t nIndex, CDS_ATOMIC::atomic<T> const& toGuard ); template <typename T, class Func> T protect(size_t nIndex, CDS_ATOMIC::atomic<T> const& toGuard, Func f ) template <typename T> T * assign( size_t nIndex, T * p ); template <typename T, int Bitmask> T * assign( size_t nIndex, cds::details::marked_ptr<T, Bitmask> p ); void copy( size_t nDestIndex, size_t nSrcIndex ); void copy( size_t nIndex, Guard const& src ); template <typename T> T * get( size_t nIndex) const; void clear( size_t nIndex);
CDS_ATOMIC
тАУ ?
,
std::atomic
. ( ) C++11
atomic
,
CDS_ATOMIC
std
. тАУ
cds::cxx11_atomics
, , libcds- atomic. libcds
boost.atomic
,
CDS_ATOMIC
boost
.
Hazard Pointer with Reference Counter
Hazard Pointer , lock-free . , , , , : hazard-.
, HP- . - HP-, . , (, hazard- ). , hazard-, , HP- .
тАФ ┬л, , ┬╗. , тАФ , . , .
, , (reference counting, RefCount). Valois тАУ lock-free тАФ . RefCount- , тАУ , . , RefCount-, lock-free fetch-and-add (,
, тАУ ).
2005 [GPST05], Hazard Pointer RefCount : Hazard Pointers lock-free , RefCount тАУ . HRC (Hazard pointer RefCounting).
Hazard Pointers / , RefCounting- . , (- , . [GPST05]). Hazard Pointers
lock-free , HRC :
void CleanUpNode( Node * pNode); void TerminateNode( Node * pNode);
TerminateNode
pNode
.
CleanUpNode
, ,
pNode
┬л┬╗ ( ) , () ; RefCount- , ,
CleanUpNode
:
void CleanUpNode(Node * pNode) { for (all x where pNode->link[x] of node is reference-counted) { retry: node1 = DeRefLink(&pNode->link[x]);
lock-free ( C++) HRC lock-free . , ,
CleanUpNode
,
, . lock-free , , MultiCAS .
, Hazard Pointers , .
Scan
Hazar Pointers ( ,
CleanUpNode
). : Hazard Pointers (
R > N = P * K
),
Scan
- ( , hazard-), HRC
Scan
- ( тАУ ). ,
Scan
,
CleanUpAll
:
CleanUpNode
,
Scan
.
HRC- libcdsUPD (2016 ): libcds 2.0.0 HRC- ( , ), - , Hazard Pointer.
libcds HRC- HP-. тАУ cds::gc::HRC
. API API cds::gc::HP
. namespace cds::gc::hrc
.
HRC- тАУ тАУ libcds. , lock-free . , , . тАУ тАУ lock-free : -, , . , , HP- , , тАФ lock-free .
, HRC- libcds HP-. , ( ) HP-: HRC- 2-3 , HP-. ┬л┬╗, : - Scan
(, - ) CleanUpAll
, retired-.
HRC- libcds HP-like , . HRC- HRC-based HP-based .
Pass the Buck
lock-free , Herlihy & al
Pass-the-Buck (PTB, тАЬ тАЭ) [HLM02, HLM05], HP- ., .
, HP-, PTB- (guarded, hazard pointer HP-). PTB- ( hazard pointer'). (retired)
Liberate
тАФ
Scan
HP-.
Liberate
, . HP-, retired- , PTB- .
guard' (hazard pointer'): , retired-,
hand-off (тАЬ тАЭ).
Liberate
, retired- guard', retired- hand-off guard'.
Liberate
hand-off , guard, , , .
[HLM05]
Liberate
: wait-free lock-free. Wait-free dwCAS (CAS ), dwCAS . Lock-free , . (guard' retired-) lock-free
Liberate
, (, retired-, ). , PTB- ,
Liberate
.
,
Liberate
PTB-, HP-. PTB libcds HP- hazard- retired-. : ┬л┬╗ HP- , PTB, PTB guard'.
libcdsUPD (2016 ): libcds 2.0.0
cds::gc::DHP
тАФ HP, тАФ pass-the-buck , тАФ Hazard Pointer .
libcds PTB-
cds::gc::PTB
, namespace
cds::gc::ptb
. API
cds::gc::PTB
cds::gc:::HP
, . :
PTB( size_t nLiberateThreshold = 1024, size_t nInitialThreadGuardCount = 8 );
nLiberateThreshold
тАФ Liberate
. retired- , Liberate
nInitialThreadGuardCount
тАФ quard' (, libcds). guard'
рдирд┐рд╖реНрдХрд░реНрд╖
safe memory reclamation, Hazard Pointer. HP- lock-free .
lock-free . libcds, , (attach)
GC
libcds. ,
Scan()
/
Liberate()
. тАФ .
тАФ RCU, HP-like , тАФ .
UPD 2016:
Errandir , Hazard Pointer ( HP).
[Fra03] Keir Fraser
Practical Lock Freedom , 2004; technical report is based on a dissertation submitted September 2003 by K.Fraser for the degree of Doctor of Philosophy to the University of Cambridge, King's College
[GPST05] Anders Gidenstam, Marina Papatriantafilou, Hakan Sundell, Philippas Tsigas
Practical and Efficient Lock-Free Garbage Collection Based on Reference Counting , Technical Report no. 2005-04 in Computer Science and Engineering at Chalmers University of Technology and Goteborg University, 2005
[Har01] Timothy Harris
A pragmatic implementation of Non-Blocking Linked List , 2001
[HLM02] M. Herlihy, V. Luchangco, and M. Moir
The repeat offender problem: A mechanism for supporting
dynamic-sized lockfree data structures Technical Report TR-2002-112, Sun Microsystems
Laboratories, 2002.
[HLM05] M.Herlihy, V.Luchangco, P.Martin, and M.Moir
Nonblocing Memory Management Support for Dynamic-Sized Data Structure , ACM Transactions on Computer Systems, Vol. 23, No. 2, May 2005, Pages 146тАУ196.
[Mic02] Maged Michael
Safe Memory Reclamation for Dynamic Lock-Free Objects Using Atomic Reads and Writes , 2002
[Mic03] Maged Michael
Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects , 2003
[MS98] Maged Michael, Michael Scott
Simple, Fast and Practical Non-Bloking and Blocking Concurrent Queue Algorithms , 1998
[Tor08] Johan Torp
The parallelism shift and C++'s memory model , chapter 13, 2008
рд▓реЙрдХ-рдлреНрд░реА рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕рд╢реБрд░реБрдЖрддрдореВрд▓ рдмрд╛рддреЗрдВ:
рдЕрдВрджрд░:
рдмрд╛рд╣рд░ рд╕реЗ: