Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Paavo Helde Newsgroups: comp.lang.c++ Subject: Re: Futex Stack Test... Date: Tue, 18 Feb 2025 09:01:55 +0200 Organization: A noiseless patient Spider Lines: 418 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Tue, 18 Feb 2025 08:01:55 +0100 (CET) Injection-Info: dont-email.me; posting-host="7c7f81cd3765b13fb23960de88d9bec9"; logging-data="1681526"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+b5V8Jz5toAu1P/R3D7aJ+w2c3DUME1WE=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:115pX1ueMeP4BSaBVn1PzPGRg98= In-Reply-To: Content-Language: en-US Bytes: 13272 On 18.02.2025 01:17, Chris M. Thomasson wrote: > This is a little C++20 test using a futex to allow one to wait on a > lock-free stack. The main stack logic is in struct ct_stack. Well, can > you get to compile and run? Thanks... Seamed to work fine, but compilation produced some warnings about the CT_WAIT macro. Build started at 08:55... 1>------ Build started: Project: ConsoleTest2022, Configuration: Release x64 ------ 1>futex-stack-test.cpp 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(55,25): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(71,21): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(87,38): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(90,40): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(92,39): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(94,33): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>C:\Test\ConsoleTestVS2022\ConsoleTest2022\futex-stack-test.cpp(185,38): warning C4312: 'type cast': conversion from 'unsigned int' to 'ct_node *' of greater size 1>Generating code 1>77 of 78 functions (98.7%) were compiled, the rest were copied from previous compilation. 1> 66 functions were new in current compilation 1> 0 functions had inline decision re-evaluated but remain unchanged 1>Finished generating code 1>ConsoleTest2022.vcxproj -> C:\Test\ConsoleTestVS2022\ConsoleTest2022\x64\Release\ConsoleTest2022.exe 1>Done building project "ConsoleTest2022.vcxproj". ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== Futex Stack Test by: Chris M. Thomasson version: (0.0.1) _________________________________ CT_THREAD_N = 42 CT_WORK_N = 10000000 CT_WAIT = 00000000DEADBEEF ct_shared::ct_shared() Launching threads... Generate work... Completed all work! Sending shutdown state... Threads joined... Dump shutdown state... Shutdown complete! ct_shared::~ct_shared() g_ct_work_alloations = 10000042 g_ct_work_dealloations = 10000042 Fin! > I still need to check my algorithm out in Relacy. I think it might be > able to model futex. > > > My code: > ______________________________________ > #include > #include > #include > #include > #include > > > #define CT_THREAD_N (42) > #define CT_WORK_N (10000000) > #define CT_WAIT ((ct_node*)0xDEADBEEF) > > > struct ct_node > { >     ct_node* m_next = { nullptr }; > >     ct_node() >     { >         //std::cout << "(" << this << ")::ct_node::ct_node()\n"; >     } > >     ~ct_node() >     { >         //std::cout << "(" << this << ")::ct_node::~ct_node()\n"; >     } > }; > > > struct ct_stack > { >     std::atomic m_head = { nullptr }; > >     void >     push( >         ct_node* node >     ) { >         ct_node* head = m_head.load(std::memory_order_relaxed); > >         do >         { >             if (head == CT_WAIT) >             { >                 node->m_next = nullptr; >             } > >             else >             { >                 node->m_next = head; >             } > >         } while (! m_head.compare_exchange_weak( >             head, >             node, >             std::memory_order_release) >           ); > >         if (head == CT_WAIT) >         { >             // slow path... >             m_head.notify_one(); >         } >     } > >     ct_node* >     flush_wait() >     { >         ct_node* head = nullptr; > >         for (;;) >         { >             head = m_head.exchange(nullptr, std::memory_order_acquire); > >             while (! head || head == CT_WAIT) >             { >                 // slow path... >                 head = m_head.exchange(CT_WAIT, > std::memory_order_acquire); > >                 if (! head || head == CT_WAIT) >                 { >                     m_head.wait(CT_WAIT, std::memory_order_relaxed); >                     continue; >                 } >             } > >             break; >         } > >         assert(head && head != CT_WAIT); ========== REMAINDER OF ARTICLE TRUNCATED ==========