$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2003-02-14 08:29:12
Alexander Terekhov wrote:
> 
> Pavel Vasiliev wrote:
> [...]
> > > pthread_refcount_decrement()         // with msync for proper mut.obj-cleanup
> 
> Basically [in terms of proposed/revised Java MM], it's VOLATILE-RELEASE
> when count > 1 'prior to decrement' and VOLATILE-ACQUIRE when the count
> drops to 0. I think that one might even try to optimize-away VOLATILE-
> RELEASE msync [and interlocked instruction(s)] for the'count == 1'-case;
> on some platforms, perhaps.
> 
> > > pthread_refcount_decrement_nomsync() // without any msync whatsoever
> >
> > "nomsync" here stands for "no memory view update even when counter drops
> > to 0"?
> 
> Yes, it's a variant without [VOLATILE-RELEASE/VOLATILE-ACQUIRE] msync.
  [ ..."release_weak() calls destruct_self() on expired memory view"... ]
Here's "SKETCHv4" together with "class refs" illustration.
PTHREAD_REFCOUNT_MAX                  // upper bound
PTHREAD_REFCOUNT_INITIALIZER(N)       // macro for statics INIT
pthread_refcount_init()               // mutex like but with initial value
pthread_refcount_destroy()            // also mutex like
pthread_refcount_getvalue()           // see "COW_AtomicInt3" string example
pthread_refcount_setvalue()           // see "COW_AtomicInt3" string example
pthread_refcount_increment()          // without any msync whatsoever
pthread_refcount_add()                // without any msync but with r.checking
pthread_refcount_increment_positive() // without any msync but with 0-checking
pthread_refcount_add_to_positive()    // without any msync but with 0&r.checking
pthread_refcount_decrement()          // with msync for proper mut.obj-cleanup
pthread_refcount_subtract()           // with msync and with r.checking
pthread_refcount_decrement_nomsync()  // without any msync whatsoever
pthread_refcount_subtract_nomsync()   // without any msync but with r.checking
pthread_refcount_decrement_rel()      // with RELEASE msync-if-'count > 1'
pthread_refcount_subtract_rel()       // with RELEASE msync-... and r.checking
pthread_refcount_decrement_acq()      // with ACQUIRE msync-if-dropped-to-zero
pthread_refcount_subtract_acq()       // with ACQUIRE msync-... and r.checking
pthread_refcount_attr_*()             // PROCESS_SHARED and etc. attr-stuff
std::size_t as "value type"           // for get/set/add/... "value" param
PTHREAD_REFCOUNT_DROPPED_TO_ZERO      // for pthread_refcount_decrement*() 
                                      // and pthread_refcount_sub() to 
                                      // indicate "dropped to zero" condition
                                      // that MAY be used to safely destroy
                                      // associated ref.counted object or 
                                      // simply continue -- increment/setval
                                      // it's also used for "strong_from_weak"
                                      // by pthread_refcount_increment_positive
                                      // and pthread_refcount_add_to_positive
//*** ES and error checking aside...
class refs { 
public:
  refs() {
    pthread_refcount_init(&strong_count, 1);
    pthread_refcount_init(&weak_count, 1); 
  }
 ~refs() {
    pthread_refcount_destroy(&weak_count);
    pthread_refcount_destroy(&strong_count);
  }
  //*** Called by existing "strong_ptr".
  void acquire_strong() {
    pthread_refcount_increment(&strong_count);
  }
  void release_strong() {
    int status = pthread_refcount_decrement(&strong_count);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) {
      destruct_object();
      status = pthread_refcount_decrement_rel(&weak_count);
      if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) 
        destruct_self();
    }
  }
  void acquire_weak_from_strong() {
    acquire_weak();
  }
  //*** Called by existing "weak_ref".
  void acquire_weak() {
    pthread_refcount_increment( &weak_count );
  }
  void release_weak() {
    int status = pthread_refcount_decrement_acq(&weak_count);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) 
      destruct_self();
  }
  bool acquire_strong_from_weak() {
    int status = pthread_refcount_increment_positive(&strong_count); // _add_to_positive(&refcount, 1);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) // Ouch, did not work [too late].
      return false;
    return true;
  }
private:
  void destruct_object(); // "delete p_object".
  void destruct_self();   // "delete this".
  pthread_refcount_t strong_count;  
  pthread_refcount_t weak_count;    
  T* p_object;
}; //*** class refs
regards,
alexander.