Deutsch   English   Français   Italiano  
<vcsrdh$2sh9d$4@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Newsgroups: comp.arch
Subject: Re: Is Intel exceptionally unsuccessful as an architecture designer?
Date: Mon, 23 Sep 2024 15:51:29 -0700
Organization: A noiseless patient Spider
Lines: 427
Message-ID: <vcsrdh$2sh9d$4@dont-email.me>
References: <memo.20240913205156.19028s@jgd.cix.co.uk>
 <20240918190027.00003e4e@yahoo.com> <vcfp2q$8glq$5@dont-email.me>
 <jwv34lumjz7.fsf-monnier+comp.arch@gnu.org> <vckpkg$18k7r$2@dont-email.me>
 <vckqus$18j12$2@dont-email.me>
 <920c561c4e39e91d3730b6aab103459b@www.novabbs.org>
 <vcl6i6$1ad9e$1@dont-email.me>
 <d3b9fc944f708546e4fbe5909c748ba3@www.novabbs.org>
 <%dAHO.54667$S9Vb.39628@fx45.iad> <vcna56$1nlod$2@dont-email.me>
 <a7708487530552a53732070fe08d9458@www.novabbs.org>
 <vcprkv$2asrd$1@dont-email.me>
 <e2c993172c11a221c4dcb9973f9cdb86@www.novabbs.org>
 <vcqe6f$2d8oa$1@dont-email.me>
 <4f84910a01d7db353eedadd7c471d7d3@www.novabbs.org>
 <20240923105336.0000119b@yahoo.com>
 <6577e60bd63883d1a7bd51c717531f38@www.novabbs.org>
 <vcsmvq$2s1qd$2@dont-email.me>
 <23d9473740db6c0ecc7e1d4a2179c75e@www.novabbs.org>
 <vcsphq$2sh9d$1@dont-email.me>
 <b23480c6afdce45b31fb9ae2e2397846@www.novabbs.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 24 Sep 2024 00:51:30 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="cc0aa948cfee330c0e613beeb38c6255";
	logging-data="3032365"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19li+YLiOli3jA/YgxtSIW8howZcEGA7ZU="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:fFnq4M93oj2HNws7WnQq4hc2ngs=
In-Reply-To: <b23480c6afdce45b31fb9ae2e2397846@www.novabbs.org>
Content-Language: en-US
Bytes: 11868

On 9/23/2024 3:32 PM, MitchAlsup1 wrote:
> On Mon, 23 Sep 2024 22:19:37 +0000, Chris M. Thomasson wrote:

[...]

Getting around ABA and/or DWCAS. A way, in a portable C++11 program. One 
of my proxy collectors can do it. It's not the only tool in the box for 
sure! So, well, that's that. Here is some code. Can you compile and give 
it a run?

The missing (#include <functional>) aside for a moment, does it compile 
on your end?

_____________
#include <cassert>
#include <iostream>
#include <atomic>
#include <thread>


#define CT_READERS 10
#define CT_WRITERS 5
#define CT_THREADS (CT_WRITERS + CT_READERS)
#define CT_ITERS 10000000
#define CT_COLLECT 1024


// These are for debug and some statistics only...
static std::atomic<unsigned long> g_debug_alloc(0);
static std::atomic<unsigned long> g_debug_free(0);


// Chris M. Thomassons single target proxy collector:
// https://pastebin.com/raw/f71480694

namespace ct_proxy
{
     struct node
     {
         std::atomic<node*> m_next;
         node* m_defer_next;

         node()
         {
             // debug only!
             g_debug_alloc.fetch_add(1);
         }

         ~node()
         {
             // debug only!
             g_debug_free.fetch_add(1);
         }
     };


     class proxy
     {
         static void prv_destroy(node* n)
         {
             while (n)
             {
                 node* next = n->m_defer_next;
                 delete n;
                 n = next;
             }
         }



     public:
         class collector
         {
             friend class proxy;



         private:
             std::atomic<node*> m_defer;
             std::atomic<unsigned int> m_count;



         public:
             collector()
             :   m_defer(nullptr),
                 m_count(0)
             {

             }


             ~collector()
             {
                 prv_destroy(m_defer.load(std::memory_order_relaxed));
             }
         };



     private:
         std::atomic<unsigned int> m_current;
         std::atomic<bool> m_quiesce;
         node* m_defer;
         collector m_collectors[2];



     public:
         proxy()
         :   m_current(0),
             m_quiesce(false),
             m_defer(nullptr)
         {

         }

         ~proxy()
         {
             prv_destroy(m_defer);
         }



     private:
         void prv_quiesce_begin()
         {
             // Try to begin the quiescence process.
             if (! m_quiesce.exchange(true, std::memory_order_acquire))
             {
                 // advance the current collector and grab the old one.
                 unsigned int old = 
m_current.load(std::memory_order_relaxed) & 0xFU;
                 old = m_current.exchange((old + 1) & 1, 
std::memory_order_acq_rel);
                 collector& c = m_collectors[old & 0xFU];

                 // decode reference count.
                 unsigned int refs = old & 0xFFFFFFF0U;

                 // verify reference count and previous collector index.
                 assert(! (refs & 0x10U) && (old & 0xFU) == (&c - 
m_collectors));

                 // increment and generate an odd reference count.
                 if (c.m_count.fetch_add(refs + 0x10U, 
std::memory_order_release) == -(int)refs)
                 {
                     // odd reference count and drop-to-zero condition 
detected!
                     prv_quiesce_complete(c);
                 }
             }
         }


         void prv_quiesce_complete(collector& c)
         {
             // the collector `c' is now in a quiescent state! :^)
             std::atomic_thread_fence(std::memory_order_acquire);

========== REMAINDER OF ARTICLE TRUNCATED ==========