|
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