Hi, We have been trying to compile qpid on AIX without success. We have tried both the gcc and xlc compilers. We first attempted the qpid compile on AIX 6.1 with xlc 13.1.0 and Boost 1.57. The error generated during the make all step was:
The wrong number of arguments has been specified for "qpid::InlineAllocator<std::allocator<qpid::Range<qpid::framing::SequenceNumber> >,3>::allocate(size_type)". We subsequently set up an AIX 7.1 server, installed all of the myriad prerequisites and attempted to compile qpid using xlc with Boost 1.53. Unfortunately, we observed the same error in the new environment. I have attached the relevant files. We have spent a lot of time on this issue between gcc and xlc, setting up multiple environments, trying different versions of boost, etc. and unfortunately have nothing to show for it. We have our qpid test code running successfully on Linux and Windows, but AIX is proving to be a big and costly hurdle for us. Any assistance that can be offered that may help us to resolve this issue would be greatly appreciated. Thanks, Chris Whelan -----Original Message----- From: Steve Huston [mailto:[email protected]] Sent: Wednesday, December 17, 2014 3:08 PM To: [email protected] Subject: RE: Compiling qpid on aix 6.1 with xlc 13.1.0 I don't think the boost warnings are pertinent in this case, and boost is tough to get built with xlC, so for the time being, I'd let that dog lie. It smells like a mismatch between std::vector arguments between xlC and what the code expects. I'd chase that one down first. If I get done with customer commitments today I will check into it later. -Steve > -----Original Message----- > From: Chuck Rolke [mailto:[email protected]] > Sent: Wednesday, December 17, 2014 3:00 PM > To: [email protected] > Subject: Re: Compiling qpid on aix 6.1 with xlc 13.1.0 > > Hi Chris, > > In your makeAllOutput.txt file you are getting boost (1_57) warnings > right off the bat. I've never used any boost beyond 1_53 on linux or > windows but > 1_53 works on both of those platforms. > > Could you try downgrading your boost to 1_53, a "known good on Windows > and Linux" version? > > -Chuck > > ----- Original Message ----- > > From: "Chris Whelan" <[email protected]> > > To: [email protected] > > Sent: Wednesday, December 17, 2014 9:31:35 AM > > Subject: Compiling qpid on aix 6.1 with xlc 13.1.0 > > > > Hi, > > > > We have abandoned using gcc on aix to compile qpid and have now > > moved on to our next problem child, xlc. Boost compiled > > successfully, but when we try to compile qpid, an argument mismatch > > apparently occurs. > > The environment description and details are below. The associated > > files are attached. If anyone can offer any insight into what is > > wrong or has any suggestions on what we should try to resolve this, > > your assistance will be gratefully accepted. > > > > Regards, > > > > Chris Whelan > > > > # environment > > export CC=/opt/IBM/xlC/13.1.0/bin/xlc export > > CXX=/opt/IBM/xlC/13.1.0/bin/xlc++ export > > BOOST_ROOT=/home/dbapi/enquesta_5_0/boost_1_57_0 > > # for xlC: > > export PATH=/opt/IBM/xlC/13.1.0/bin:$PATH > > # for other dependencies built locally export > > PATH=/home/dbapi/enquesta_5_0/usr/local/bin:$PATH > > > > Email attachments: > > cmakeOutput.txt is the output from running cmake makeAllOutput.txt > > is the output from the compile (make all) vector.t is an IBM source > > file, /opt/IBM/xlC/13.1.0/include/vector.t > > InlineVector.h is from qpid source, > > $QPID_HOME/src/qpid/InlineVector.h > > > > The error from makeAllOutput.txt ("make all" command) > > /opt/IBM/xlC/13.1.0/include/vector.t", line 41.55: 1540-0215 (S) The > > wrong numb er of arguments has been specified for > > "qpid::InlineAllocator<std::allocator<qpi > > d::Range<qpid::framing::SequenceNumber> >,3>::allocate(size_type)". > > "/opt/IBM/xlC/13.1.0/include/vector.t", line 37.6: 1540-0700 (I) The > > previous me ssage was produced while processing > > "std::vector<qpid::Range<qpid::framing::Sequ > > enceNumber>,qpid::InlineAllocator<std::allocator<qpid::Range<qpid::f > > enceNumber>ra > > enceNumber>ming::Sequ > > enceNumber> >,3> >::reserve(size_type)". > > "/home/dbapi/enquesta_5_0/qpid-cpp-0.30/src/qpid/InlineVector.h", > > line > 50.13: > > 15 > > 40-0700 (I) The previous message was produced while processing > > "qpid::InlineVect > > > or<qpid::Range<qpid::framing::SequenceNumber>,3,std::allocator<qpid::R > a > nge<qpid: > > :framing::SequenceNumber> > >::InlineVector(const allocator_type &)". > > > > > > -------------------------------------------------------------------- > > - To unsubscribe, e-mail: [email protected] For > > additional commands, e-mail: [email protected] > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] For > additional commands, e-mail: [email protected] B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB [ X ܚX KK[XZ[ \ \ ][ X ܚX P\Y \X K ܙ B ܈Y][ۘ[ [X[ K[XZ[ \ \ Z[\Y \X K ܙ B B
#ifndef QPID_RANGESET_H #define QPID_RANGESET_H /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ #include "qpid/InlineVector.h" #include <boost/iterator/iterator_facade.hpp> #include <boost/operators.hpp> #include <boost/bind.hpp> #include <algorithm> #include <iostream> #include <numeric> namespace qpid { /** A range of values, used in RangeSet. * Range(begin, end) includes begin but excludes end. * Range::makeClosed(first,last) includes both first and last. */ template <class T> class Range { public: static Range makeClosed(const T& first, T last) { return Range(first, ++last); } Range() : begin_(), end_() {} explicit Range(const T& t) : begin_(t), end_(t) { ++end_; } Range(const T& b, const T& e) : begin_(b), end_(e) { assert(b <= e); } T begin() const { return begin_; } /** End of _open_ range, i.e. !contains(end()) */ T end() const { return end_; } T first() const { assert(!empty()); return begin_; } /** Last in closed range, i.e. contains(end()) */ T last() const { assert(!empty()); T ret=end_; return --ret; } void begin(const T& t) { begin_ = t; } void end(const T& t) { end_ = t; } size_t size() const { return end_ - begin_; } bool empty() const { return begin_ == end_; } bool contains(const T& x) const { return begin_ <= x && x < end_; } bool contains(const Range& r) const { return begin_ <= r.begin_ && r.end_ <= end_; } bool strictContains(const Range& r) const { return begin_ < r.begin_ && r.end_ < end_; } bool operator==(const Range& x) { return begin_ == x.begin_ && end_== x.end_; } bool operator<(const T& t) const { return end_ < t; } bool operator<(const Range<T>& r) const { return end_ < r.begin_; } /** touching ranges can be merged into a single range. */ bool touching(const Range& r) const { return std::max(begin_, r.begin_) <= std::min(end_, r.end_); } /** @pre touching */ void merge(const Range& r) { assert(touching(r)); begin_ = std::min(begin_, r.begin_); end_ = std::max(end_, r.end_); } operator bool() const { return !empty(); } template <class S> void serialize(S& s) { s(begin_)(end_); } private: T begin_, end_; }; /** * A set implemented as a list of [begin, end) ranges. * T must be LessThanComparable and Incrementable. * RangeSet only provides const iterators. */ template <class T> class RangeSet : boost::additive1<RangeSet<T>, boost::additive2<RangeSet<T>, Range<T>, boost::additive2<RangeSet<T>, T> > > { typedef InlineVector<Range<T>, 3> Ranges; // TODO aconway 2008-04-21: what's the optimial inlined value? public: class iterator : public boost::iterator_facade< iterator, const T, boost::forward_traversal_tag> { public: iterator() : ranges(), iter(), value() {} private: typedef typename Ranges::const_iterator RangesIter; iterator(const Ranges& r, const RangesIter& i, const T& t) : ranges(&r), iter(i), value(t) {} void increment(); bool equal(const iterator& i) const; const T& dereference() const { return value; } const Ranges* ranges; RangesIter iter; T value; friend class RangeSet<T>; friend class boost::iterator_core_access; }; typedef iterator const_iterator; RangeSet() {} explicit RangeSet(const Range<T>& r) { *this += r; } RangeSet(const T& a, const T& b) { *this += Range<T>(a,b); } bool contiguous() const { return ranges.size() <= 1; } bool contains(const T& t) const; bool contains(const Range<T>&) const; /**@pre contiguous() */ Range<T> toRange() const; bool operator==(const RangeSet<T>&) const; void addRange (const Range<T>&); void addSet (const RangeSet<T>&); RangeSet<T>& operator+=(const T& t) { return *this += Range<T>(t); } RangeSet<T>& operator+=(const Range<T>& r) { addRange(r); return *this; } RangeSet<T>& operator+=(const RangeSet<T>& s) { addSet(s); return *this; } void removeRange (const Range<T>&); void removeSet (const RangeSet<T>&); RangeSet<T>& operator-=(const T& t) { return *this -= Range<T>(t); } RangeSet<T>& operator-=(const Range<T>& r) { removeRange(r); return *this; } RangeSet<T>& operator-=(const RangeSet<T>& s) { removeSet(s); return *this; } T front() const { return ranges.front().begin(); } T back() const { return ranges.back().end(); } // Iterate over elements in the set. iterator begin() const; iterator end() const; // Iterate over ranges in the set. typedef typename Ranges::const_iterator RangeIterator; RangeIterator rangesBegin() const { return ranges.begin(); } RangeIterator rangesEnd() const { return ranges.end(); } size_t rangesSize() const { return ranges.size(); } // The difference between the start and end of this range set uint32_t span() const; size_t size() const; bool empty() const { return ranges.empty(); } void clear() { ranges.clear(); } /** Return the largest contiguous range containing x. * Returns the empty range [x,x) if x is not in the set. */ Range<T> rangeContaining(const T&) const; template <class S> void serialize(S& s) { s.split(*this); s(ranges.begin(), ranges.end()); } template <class S> void encode(S& s) const { s(uint16_t(ranges.size()*sizeof(Range<T>))); } template <class S> void decode(S& s) { uint16_t sz; s(sz); ranges.resize(sz/sizeof(Range<T>)); } private: static size_t accumulateSize(size_t s, const Range<T>& r) { return s+r.size(); } Ranges ranges; template <class U> friend std::ostream& operator<<(std::ostream& o, const RangeSet<U>& r); friend class iterator; }; template <class T> std::ostream& operator<<(std::ostream& o, const Range<T>& r) { return o << "[" << r.begin() << "," << r.end() << ")"; } template <class T> std::ostream& operator<<(std::ostream& o, const RangeSet<T>& rs) { std::ostream_iterator<Range<T> > i(o, " "); o << "{ "; std::copy(rs.ranges.begin(), rs.ranges.end(), i); return o << "}"; } template <class T> bool RangeSet<T>::contains(const T& t) const { typename Ranges::const_iterator i = std::lower_bound(ranges.begin(), ranges.end(), Range<T>(t)); return i != ranges.end() && i->contains(t); } template <class T> bool RangeSet<T>::contains(const Range<T>& r) const { typename Ranges::const_iterator i = std::lower_bound(ranges.begin(), ranges.end(), r); return i != ranges.end() && i->contains(r); } template <class T> void RangeSet<T>::addRange(const Range<T>& r) { if (r.empty()) return; typename Ranges::iterator i = std::lower_bound(ranges.begin(), ranges.end(), r); if (i == ranges.end() || !i->touching(r)) ranges.insert(i, r); // No overlap else { i->merge(r); typename Ranges::iterator j = i; while (++j != ranges.end() && i->touching(*j)) i->merge(*j); ranges.erase(i+1,j); } } template <class T> void RangeSet<T>::addSet(const RangeSet<T>& s) { typedef RangeSet<T>& (RangeSet<T>::*RangeSetRangeOp)(const Range<T>&); std::for_each(s.ranges.begin(), s.ranges.end(), boost::bind((RangeSetRangeOp)&RangeSet<T>::operator+=, this, _1)); } template <class T> void RangeSet<T>::removeRange(const Range<T>& r) { if (r.empty()) return; typename Ranges::iterator i,j; i = std::lower_bound(ranges.begin(), ranges.end(), r); if (i == ranges.end() || i->begin() >= r.end()) return; // Outside of set if (*i == r) // Erase i ranges.erase(i); else if (i->strictContains(r)) { // Split i Range<T> i1(i->begin(), r.begin()); Range<T> i2(r.end(), i->end()); *i = i2; ranges.insert(i, i1); } else { if (i->begin() < r.begin()) { // Truncate i i->end(r.begin()); ++i; } for (j = i; j != ranges.end() && r.contains(*j); ++j) ; // Ranges to erase. if (j != ranges.end() && r.end() > j->begin()) j->begin(r.end()); // Truncate j ranges.erase(i,j); } } template <class T> void RangeSet<T>::removeSet(const RangeSet<T>& r) { std::for_each( r.ranges.begin(), r.ranges.end(), boost::bind(&RangeSet<T>::removeRange, this, _1)); } template <class T> Range<T> RangeSet<T>::toRange() const { assert(contiguous()); return empty() ? Range<T>() : ranges.front(); } template <class T> void RangeSet<T>::iterator::increment() { assert(ranges && iter != ranges->end()); if (!iter->contains(++value)) { ++iter; if (iter == ranges->end()) *this=iterator(); // end() iterator else value=iter->begin(); } } template <class T> bool RangeSet<T>::operator==(const RangeSet<T>& r) const { return ranges.size() == r.ranges.size() && std::equal(ranges.begin(), ranges.end(), r.ranges.begin()); } template <class T> typename RangeSet<T>::iterator RangeSet<T>::begin() const { return empty() ? end() : iterator(ranges, ranges.begin(), front()); } template <class T> typename RangeSet<T>::iterator RangeSet<T>::end() const { return iterator(); } template <class T> bool RangeSet<T>::iterator::equal(const iterator& i) const { return ranges==i.ranges && (ranges==0 || value==i.value); } template <class T> Range<T> RangeSet<T>::rangeContaining(const T& t) const { typename Ranges::const_iterator i = std::lower_bound(ranges.begin(), ranges.end(), Range<T>(t)); return (i != ranges.end() && i->contains(t)) ? *i : Range<T>(t,t); } template <class T> uint32_t RangeSet<T>::span() const { if (ranges.empty()) return 0; return ranges.back().last() - ranges.front().first(); } template <class T> size_t RangeSet<T>::size() const { return std::accumulate(rangesBegin(), rangesEnd(), 0, &RangeSet<T>::accumulateSize); } } // namespace qpid #endif /*!QPID_RANGESET_H*/
#ifndef QPID_INLINEALLOCATOR_H #define QPID_INLINEALLOCATOR_H /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ #include <memory> #include <assert.h> #include <boost/type_traits/type_with_alignment.hpp> #include <boost/type_traits/alignment_of.hpp> namespace qpid { template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max> struct InlineRebind; /** * An allocator that has inline storage for up to Max objects * of type BaseAllocator::value_type. */ template <class BaseAllocator, size_t Max> class InlineAllocator : public BaseAllocator { public: typedef typename BaseAllocator::pointer pointer; typedef typename BaseAllocator::size_type size_type; typedef typename BaseAllocator::value_type value_type; InlineAllocator() : allocated(false) {} InlineAllocator(const InlineAllocator& x) : BaseAllocator(x), allocated(false) {} pointer allocate(size_type n) { if (n <= Max && !allocated) { allocated=true; return reinterpret_cast<value_type*>(address()); } else return BaseAllocator::allocate(n, 0); } void deallocate(pointer p, size_type n) { if (p == address()) { assert(allocated); allocated=false; } else BaseAllocator::deallocate(p, n); } template<typename T1> struct rebind { typedef typename InlineRebind<T1, value_type, BaseAllocator, Max>::other other; }; private: // POD object with alignment and size to hold Max value_types. static const size_t ALIGNMENT=boost::alignment_of<value_type>::value; typedef typename boost::type_with_alignment<ALIGNMENT>::type Aligner; union Store { Aligner aligner_; char sizer_[sizeof(value_type)*Max]; } store; value_type* address() { return reinterpret_cast<value_type*>(&store); } bool allocated; }; // Rebind: if RequestedType == InlineType, use the InlineAllocator, // otherwise, use the BaseAllocator without any inlining. template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max> struct InlineRebind { typedef typename BaseAllocator::template rebind<RequestedType>::other other; }; template <typename T, typename BaseAllocator, size_t Max> struct InlineRebind<T, T, BaseAllocator, Max> { typedef typename qpid::InlineAllocator<BaseAllocator, Max> other; }; } // namespace qpid #endif /*!QPID_INLINEALLOCATOR_H*/
#ifndef QPID_INLINEVECTOR_H #define QPID_INLINEVECTOR_H /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ #include "qpid/InlineAllocator.h" #include <vector> namespace qpid { /** * A vector that stores up to Max elements in inline storage, * otherwise uses normal vector allocation. * * NOTE: depends on some non-standard but highly probably assumptions * about how std::vector uses its allocator, they are true for g++. * - default constructor does not allocate. * - reserve(N) does not allocate more than N elements. * - vector never re-allocates when size() < capacity() */ template <class T, size_t Max, class Alloc=std::allocator<T> > class InlineVector : public std::vector<T, InlineAllocator<Alloc, Max> > { typedef std::vector<T, InlineAllocator<Alloc, Max> > Base; public: typedef typename Base::allocator_type allocator_type; typedef typename Base::value_type value_type; typedef typename Base::size_type size_type; explicit InlineVector(const allocator_type& a=allocator_type()) : Base(a) { this->reserve(Max); } explicit InlineVector(size_type n, const value_type& x = value_type(), const allocator_type& a=allocator_type()) : Base(a) { this->reserve(std::max(n, Max)); this->insert(this->end(), n, x); } InlineVector(const InlineVector& x) : Base() { this->reserve(std::max(x.size(), Max)); *this = x; } }; } // namespace qpid #endif /*!QPID_INLINEVECTOR_H*/
/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ #ifndef _framing_SequenceSet_h #define _framing_SequenceSet_h #include "qpid/framing/SequenceNumber.h" #include "qpid/RangeSet.h" #include "qpid/CommonImportExport.h" namespace qpid { namespace framing { class Buffer; class QPID_COMMON_CLASS_EXTERN SequenceSet : public RangeSet<SequenceNumber> { public: SequenceSet() {} SequenceSet(const RangeSet<SequenceNumber>& r) : RangeSet<SequenceNumber>(r) {} SequenceSet(const SequenceNumber& s) { add(s); } SequenceSet(const SequenceNumber& start, const SequenceNumber finish) { add(start,finish); } QPID_COMMON_EXTERN void encode(Buffer& buffer) const; QPID_COMMON_EXTERN void decode(Buffer& buffer); QPID_COMMON_EXTERN uint32_t encodedSize() const; QPID_COMMON_EXTERN bool contains(const SequenceNumber& s) const; QPID_COMMON_EXTERN void add(const SequenceNumber& s); QPID_COMMON_EXTERN void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range QPID_COMMON_EXTERN void add(const SequenceSet& set); QPID_COMMON_EXTERN void remove(const SequenceNumber& s); QPID_COMMON_EXTERN void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range QPID_COMMON_EXTERN void remove(const SequenceSet& set); template <class T> void for_each(T& t) const { for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++) t(i->first(), i->last()); } template <class T> void for_each(const T& t) const { for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++) t(i->first(), i->last()); } friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceSet&); }; }} // namespace qpid::framing #endif
--------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
