Boost logo

Boost :

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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk