From a29994dacbbd2f7118d1f3f2f98f9f1a5028beeb Mon Sep 17 00:00:00 2001 From: sageweil Date: Fri, 30 Nov 2007 00:36:24 +0000 Subject: [PATCH] new atomic_t type factored out of buffer class git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2152 29311d96-e01e-0410-9327-a35deaab8ce9 --- trunk/ceph/config.cc | 5 +-- trunk/ceph/include/atomic.h | 74 +++++++++++++++++++++++++++++++ trunk/ceph/include/buffer.h | 83 +++++++---------------------------- trunk/ceph/mds/MDS.cc | 2 +- trunk/ceph/osd/OSD.cc | 2 +- trunk/ceph/osd/PG.cc | 2 +- trunk/ceph/osd/PG.h | 4 +- trunk/ceph/osd/ReplicatedPG.h | 2 +- trunk/ceph/osd/osd_types.h | 5 ++- 9 files changed, 100 insertions(+), 79 deletions(-) create mode 100644 trunk/ceph/include/atomic.h diff --git a/trunk/ceph/config.cc b/trunk/ceph/config.cc index 83bd456f70c15..873bb0f5c1530 100644 --- a/trunk/ceph/config.cc +++ b/trunk/ceph/config.cc @@ -29,9 +29,8 @@ // hack hack hack ugly FIXME -#include "common/Mutex.h" -long buffer_total_alloc = 0; -Mutex bufferlock; +#include "include/atomic.h" +atomic_t buffer_total_alloc; #include "osd/osd_types.h" diff --git a/trunk/ceph/include/atomic.h b/trunk/ceph/include/atomic.h new file mode 100644 index 0000000000000..f7676fc813d2b --- /dev/null +++ b/trunk/ceph/include/atomic.h @@ -0,0 +1,74 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef __CEPH_ATOMIC_H +#define __CEPH_ATOMIC_H + +#ifdef BUFFER_USE_CCPP +/* + * use commonc++ library AtomicCounter. + */ +# include "cc++/thread.h" + +class atomic_t { + mutable ost::AtomicCounter nref; // mutable for const-ness of operator<< +public: + atomic_t(int i=0) : nref(i) {} + void inc() { ++nref; } + int dec() { return --nref; } + int test() const { return nref; } + void add(int i) { nref += i; } + void sub(int i) { nref -= i; } +}; + +#else +/* + * crappy slow implementation that uses a pthreads mutex. + */ +# include "common/Mutex.h" + +class atomic_t { + Mutex lock; + long nref; +public: + atomic_t(int i=0) : lock(false), nref(i) {} + void inc() { + lock.Lock(); + ++nref; + lock.Unlock(); + } + int dec() { + lock.Lock(); + int r = --nref; + lock.Unlock(); + return r; + } + void add(int d) { + lock.Lock(); + nref += d; + lock.Unlock(); + } + void sub(int d) { + lock.Lock(); + nref -= d; + lock.Unlock(); + } + int test() const { + return nref; + } +}; + +#endif + +#endif diff --git a/trunk/ceph/include/buffer.h b/trunk/ceph/include/buffer.h index ec1f6cbe37df5..c370bba9c166f 100644 --- a/trunk/ceph/include/buffer.h +++ b/trunk/ceph/include/buffer.h @@ -20,12 +20,7 @@ #include #include -#include "common/Mutex.h" - -#ifdef BUFFER_USE_CCPP -# include "cc++/thread.h" -#endif - +#include "atomic.h" #ifndef __CYGWIN__ # include @@ -35,26 +30,19 @@ // // these are in config.o -extern Mutex bufferlock; -extern long buffer_total_alloc; +extern atomic_t buffer_total_alloc; // - - class buffer { private: /* hack for memory utilization debugging. */ static void inc_total_alloc(unsigned len) { - bufferlock.Lock(); - buffer_total_alloc += len; - bufferlock.Unlock(); + buffer_total_alloc.add(len); } static void dec_total_alloc(unsigned len) { - bufferlock.Lock(); - buffer_total_alloc -= len; - bufferlock.Unlock(); + buffer_total_alloc.sub(len); } /* @@ -64,22 +52,11 @@ private: public: char *data; unsigned len; -#ifdef BUFFER_USE_CCPP - mutable ost::AtomicCounter nref; // mutable for const-ness of operator<< -#else - int nref; - Mutex lock; // we'll make it non-recursive. -#endif + atomic_t nref; raw(unsigned l) : len(l), nref(0) -#ifndef BUFFER_USE_CCPP - , lock(false) -#endif { } raw(char *c, unsigned l) : data(c), len(l), nref(0) -#ifndef BUFFER_USE_CCPP - , lock(false) -#endif { } virtual ~raw() {}; @@ -226,48 +203,30 @@ public: public: ptr() : _raw(0), _off(0), _len(0) {} ptr(raw *r) : _raw(r), _off(0), _len(r->len) { // no lock needed; this is an unref raw. - ++r->nref; + r->nref.inc(); } ptr(unsigned l) : _off(0), _len(l) { _raw = create(l); - ++_raw->nref; + _raw->nref.inc(); } ptr(char *d, unsigned l) : _off(0), _len(l) { // ditto. _raw = copy(d, l); - ++_raw->nref; + _raw->nref.inc(); } ptr(const ptr& p) : _raw(p._raw), _off(p._off), _len(p._len) { if (_raw) { -#ifdef BUFFER_USE_CCPP - ++_raw->nref; -#else - _raw->lock.Lock(); - ++_raw->nref; - _raw->lock.Unlock(); -#endif + _raw->nref.inc(); } } ptr(const ptr& p, unsigned o, unsigned l) : _raw(p._raw), _off(p._off + o), _len(l) { assert(o+l <= p._len); assert(_raw); -#ifdef BUFFER_USE_CCPP - ++_raw->nref; -#else - _raw->lock.Lock(); - ++_raw->nref; - _raw->lock.Unlock(); -#endif + _raw->nref.inc(); } ptr& operator= (const ptr& p) { // be careful -- we need to properly handle self-assignment. if (p._raw) { -#ifdef BUFFER_USE_CCPP - ++p._raw->nref; // inc new -#else - p._raw->lock.Lock(); - ++p._raw->nref; // inc new - p._raw->lock.Unlock(); -#endif + p._raw->nref.inc(); // inc new } release(); // dec (+ dealloc) old (if any) _raw = p._raw; // change my ref @@ -286,11 +245,11 @@ public: void clone_in_place() { raw *newraw = _raw->clone(); release(); - newraw->nref++; + newraw->nref.inc(); _raw = newraw; } bool do_cow() { - if (_raw->nref > 1) { + if (_raw->nref.test() > 1) { //std::cout << "doing cow on " << _raw << " len " << _len << std::endl; clone_in_place(); return true; @@ -312,19 +271,9 @@ public: void release() { if (_raw) { -#ifndef BUFFER_USE_CCPP - _raw->lock.Lock(); -#endif - if (--_raw->nref == 0) { + if (_raw->nref.dec() == 0) { //cout << "hosing raw " << (void*)_raw << " len " << _raw->len << std::endl; -#ifndef BUFFER_USE_CCPP - _raw->lock.Unlock(); -#endif delete _raw; // dealloc old (if any) - } else { -#ifndef BUFFER_USE_CCPP - _raw->lock.Unlock(); -#endif } _raw = 0; } @@ -363,7 +312,7 @@ public: const char *raw_c_str() const { assert(_raw); return _raw->data; } unsigned raw_length() const { assert(_raw); return _raw->len; } - int raw_nref() const { assert(_raw); return _raw->nref; } + int raw_nref() const { assert(_raw); return _raw->nref.test(); } void copy_out(unsigned o, unsigned l, char *dest) const { assert(_raw); @@ -955,7 +904,7 @@ inline bool operator<=(bufferlist& l, bufferlist& r) { inline std::ostream& operator<<(std::ostream& out, const buffer::raw &r) { - return out << "buffer::raw(" << (void*)r.data << " len " << r.len << " nref " << r.nref << ")"; + return out << "buffer::raw(" << (void*)r.data << " len " << r.len << " nref " << r.nref.test() << ")"; } inline std::ostream& operator<<(std::ostream& out, const buffer::ptr& bp) { diff --git a/trunk/ceph/mds/MDS.cc b/trunk/ceph/mds/MDS.cc index 4e0ce75bf8751..87ea76ba9fb45 100644 --- a/trunk/ceph/mds/MDS.cc +++ b/trunk/ceph/mds/MDS.cc @@ -339,7 +339,7 @@ void MDS::tick() logger->fset("l", (int)load.mds_load()); logger->set("q", messenger->get_dispatch_queue_len()); - logger->set("buf", buffer_total_alloc); + logger->set("buf", buffer_total_alloc.test()); logger->set("sm", mdcache->num_subtrees()); mdcache->log_stat(logger); diff --git a/trunk/ceph/osd/OSD.cc b/trunk/ceph/osd/OSD.cc index 2aab1f2d5d56b..2b72a7039b0ad 100644 --- a/trunk/ceph/osd/OSD.cc +++ b/trunk/ceph/osd/OSD.cc @@ -2132,7 +2132,7 @@ void OSD::handle_op(MOSDOp *op) const pg_t pgid = op->get_pg(); PG *pg = _have_pg(pgid) ? _lookup_lock_pg(pgid):0; - logger->set("buf", buffer_total_alloc); + logger->set("buf", buffer_total_alloc.test()); utime_t now = g_clock.now(); diff --git a/trunk/ceph/osd/PG.cc b/trunk/ceph/osd/PG.cc index 99b81f2f0dc96..0c13971154165 100644 --- a/trunk/ceph/osd/PG.cc +++ b/trunk/ceph/osd/PG.cc @@ -846,7 +846,7 @@ void PG::activate(ObjectStore::Transaction& t, last_epoch_started_any = info.last_epoch_started = osd->osdmap->get_epoch(); if (role == 0) { // primary state - peers_complete_thru = 0; // we don't know (yet)! + peers_complete_thru = eversion_t(0,0); // we don't know (yet)! } assert(info.last_complete >= log.bottom || log.backlog); diff --git a/trunk/ceph/osd/PG.h b/trunk/ceph/osd/PG.h index cf1174dd91638..16978922f9a06 100644 --- a/trunk/ceph/osd/PG.h +++ b/trunk/ceph/osd/PG.h @@ -571,8 +571,6 @@ public: role(0), state(0), last_epoch_started_any(0), - last_complete_commit(0), - peers_complete_thru(0), have_master_log(true), stat_size(0), stat_num_blocks(0) { } @@ -619,7 +617,7 @@ public: bool is_clean() const { return state_test(STATE_CLEAN); } bool is_stray() const { return state_test(STATE_STRAY); } - bool is_empty() const { return info.last_update == 0; } + bool is_empty() const { return info.last_update == eversion_t(0,0); } int num_active_ops() const { return objects_pulling.size(); diff --git a/trunk/ceph/osd/ReplicatedPG.h b/trunk/ceph/osd/ReplicatedPG.h index 0d4066ad69c67..21753debe0922 100644 --- a/trunk/ceph/osd/ReplicatedPG.h +++ b/trunk/ceph/osd/ReplicatedPG.h @@ -84,7 +84,7 @@ protected: RepGather *new_rep_gather(MOSDOp *op); void repop_ack(RepGather *repop, int result, bool commit, - int fromosd, eversion_t pg_complete_thru=0); + int fromosd, eversion_t pg_complete_thru=eversion_t(0,0)); // push/pull int num_pulling; diff --git a/trunk/ceph/osd/osd_types.h b/trunk/ceph/osd/osd_types.h index abfc7ad7da1e5..ddbb6f0867784 100644 --- a/trunk/ceph/osd/osd_types.h +++ b/trunk/ceph/osd/osd_types.h @@ -187,7 +187,8 @@ class eversion_t { public: epoch_t epoch; version_t version; - eversion_t(epoch_t e=0, version_t v=0) : epoch(e), version(v) {} + eversion_t() : epoch(0), version(0) {} + eversion_t(epoch_t e, version_t v) : epoch(e), version(v) {} }; inline bool operator==(const eversion_t& l, const eversion_t& r) { @@ -237,7 +238,7 @@ struct pg_stat_t { int64_t num_blocks; // in 4k blocks int64_t num_objects; - pg_stat_t() : reported(0), state(0), size(0), num_blocks(0), num_objects(0) {} + pg_stat_t() : state(0), size(0), num_blocks(0), num_objects(0) {} }; -- 2.39.5