(file) Return to ArrayRep.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.9 //%2005////////////////////////////////////////////////////////////////////////
  2 kumpf 1.1 //
  3 karl  1.8 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.6 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 kumpf 1.1 //
 12           // Permission is hereby granted, free of charge, to any person obtaining a copy
 13 kumpf 1.2 // of this software and associated documentation files (the "Software"), to
 14           // deal in the Software without restriction, including without limitation the
 15           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16 kumpf 1.1 // sell copies of the Software, and to permit persons to whom the Software is
 17           // furnished to do so, subject to the following conditions:
 18           // 
 19 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20 kumpf 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22 kumpf 1.2 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25 kumpf 1.1 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27           //
 28           //==============================================================================
 29           //
 30           // Author: Mike Brasher (mbrasher@bmc.com)
 31           //
 32           // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 33 mike  1.11 //              Mike Brasher, Inova Europe (mike-brasher@austin.rr.com)
 34 kumpf 1.1  //
 35            //%/////////////////////////////////////////////////////////////////////////////
 36            
 37            #ifndef Pegasus_ArrayRep_h
 38            #define Pegasus_ArrayRep_h
 39            
 40 humberto 1.7  #ifdef PEGASUS_OS_OS400
 41               #include <stdlib.h>
 42               #endif
 43               
 44 kumpf    1.1  #include <new>
 45               #include <Pegasus/Common/Config.h>
 46               #include <Pegasus/Common/Memory.h>
 47 mike     1.11 #include <Pegasus/Common/AtomicInt.h>
 48               #include <Pegasus/Common/Linkage.h>
 49               
 50               #define Array_rep (static_cast<ArrayRep<PEGASUS_ARRAY_T>*>(_rep))
 51               #define Array_size (Array_rep)->size
 52               #define Array_data (Array_rep)->data()
 53               #define Array_capacity (Array_rep)->capacity
 54               #define Array_refs (Array_rep)->refs
 55 kumpf    1.1  
 56 mike     1.13 // The OS400 platform uses this aligment directive to ensure that 
 57               // ArrayRepBase is aligned an a 16 byte boundary.
 58               #ifdef PEGASUS_OS_OS400
 59               # define PEGASUS_ALIGN16 __align(16)
 60               #else
 61               # define PEGASUS_ALIGN16 /* not necessary on other platforms */
 62               #endif
 63               
 64 kumpf    1.1  PEGASUS_NAMESPACE_BEGIN
 65               
 66 mike     1.13 PEGASUS_ALIGN16 
 67 mike     1.11 struct PEGASUS_COMMON_LINKAGE ArrayRepBase
 68               {
 69                   // We put this first to avoid gaps in this structure. Some compilers may
 70                   // align it on a large boundary.
 71                   AtomicInt refs;
 72               
 73                   Uint32 size;
 74               
 75                   union
 76                   {
 77               	Uint32 capacity;
 78               	Uint64 alignment;
 79                   };
 80               
 81                   // Called only only _empty_rep object. We set the reference count to
 82                   // two and it will remain two for the lifetime of the process. Anything
 83                   // other than one will do. If the _empty_rep.refs were one, an Array
 84                   // object may think it is the sole owner and attempt to modify it.
 85               
 86                   ArrayRepBase() : refs(2), size(0), capacity(0) { }
 87               
 88 mike     1.11     static ArrayRepBase _empty_rep;
 89               };
 90               
 91 kumpf    1.1  /*  ArrayRep<T>
 92                   The ArrayRep object represents the array size, capacity,
 93                   and elements in one contiguous chunk of memory. The elements
 94                   follow immediately after the end of the ArrayRep structure in memory.
 95                   The union is used to force 64 bit alignment of these elements. This is
 96                   a private class and should not be accessed directly by the user.
 97               */
 98               template<class T>
 99 mike     1.11 struct ArrayRep : public ArrayRepBase
100 kumpf    1.1  {
101                   // Obtains a pointer to the first element in the array.
102                   T* data() { return (T*)(void*)(this + 1); }
103               
104                   // Same as method above but returns a constant pointer.
105                   const T* data() const { return (const T*)(void*)(this + 1); }
106               
107 mike     1.11     /* Make a new copy */
108                   static ArrayRep<T>* copy_on_write(ArrayRep<T>* rep);
109 kumpf    1.1  
110                   /* Create and initialize a ArrayRep instance. Note that the
111                       memory for the elements is unitialized and must be initialized by
112                       the caller.
113                   */
114 mike     1.11     static ArrayRep<T>* PEGASUS_STATIC_CDECL alloc(Uint32 size);
115               
116                   static void ref(const ArrayRep<T>* rep);
117 kumpf    1.1  
118 mike     1.11     static void unref(const ArrayRep<T>* rep);
119 kumpf    1.1  };
120               
121               template<class T>
122 mike     1.11 ArrayRep<T>* PEGASUS_STATIC_CDECL ArrayRep<T>::alloc(Uint32 size)
123 kumpf    1.1  {
124 mike     1.11     // ATTN-MEB: throw out raising to next power of two (put this
125                   // logic in reserveCapacity().
126               
127                   if (!size)
128               	return (ArrayRep<T>*)&ArrayRepBase::_empty_rep;
129 kumpf    1.1  
130                   // Calculate capacity (size rounded to the next power of two).
131               
132 keith.petley 1.4      Uint32 initialCapacity = 8;
133 kumpf        1.1  
134 kumpf        1.5      while ((initialCapacity != 0) && (initialCapacity < size))
135                       {
136 keith.petley 1.4          initialCapacity <<= 1;
137 kumpf        1.5      }
138                   
139                       // Test for Uint32 overflow in the capacity
140                       if (initialCapacity == 0)
141                       {
142                           initialCapacity = size;
143                       }
144                   
145                       // Test for Uint32 overflow in the memory allocation size
146                       if (initialCapacity > (Uint32(0xffffffff)-sizeof(ArrayRep<T>))/sizeof(T))
147                       {
148                           return 0;
149                       }
150 kumpf        1.1  
151                       // Create object:
152                   
153 kumpf        1.5      ArrayRep<T>* rep = (ArrayRep<T>*)operator new(
154                           sizeof(ArrayRep<T>) + sizeof(T) * initialCapacity);
155 david        1.10 
156 kumpf        1.1      rep->size = size;
157 keith.petley 1.4      rep->capacity = initialCapacity;
158 mike         1.11     new(&rep->refs) AtomicInt(1);
159 kumpf        1.1  
160                       return rep;
161                   }
162                   
163                   template<class T>
164 mike         1.11 inline void ArrayRep<T>::ref(const ArrayRep<T>* rep)
165 kumpf        1.1  {
166 mike         1.12     if ((void*)rep != (void*)&ArrayRepBase::_empty_rep)
167 mike         1.11 	((ArrayRep<T>*)rep)->refs.inc();
168                   }
169                   
170                   template<class T>
171                   inline void ArrayRep<T>::unref(const ArrayRep<T>* rep_)
172                   {
173                       ArrayRep<T>* rep = (ArrayRep<T>*)rep_;
174                   
175                       if (rep != &ArrayRepBase::_empty_rep && rep->refs.decAndTestIfZero())
176 kumpf        1.1      {
177                           Destroy(rep->data(), rep->size);
178 mike         1.11 	rep->refs.~AtomicInt();
179                   	::operator delete(rep);
180                       }
181                   }
182 david        1.10 
183 mike         1.11 template<class T>
184                   ArrayRep<T>* ArrayRep<T>::copy_on_write(ArrayRep<T>* rep)
185                   {
186                       ArrayRep<T>* new_rep = ArrayRep<T>::alloc(rep->size);
187                       new_rep->size = rep->size;
188                       CopyToRaw(new_rep->data(), rep->data(), rep->size);
189                       unref(rep);
190                       return new_rep;
191 kumpf        1.1  }
192                   
193                   PEGASUS_NAMESPACE_END
194                   
195                   #endif /* Pegasus_ArrayRep_h */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2