diff options
author | kitty <kitty@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-09-10 19:12:37 +0000 |
---|---|---|
committer | kitty <kitty@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-09-10 19:12:37 +0000 |
commit | a219563acd6e2720f19519c2b8e5902fde3f0832 (patch) | |
tree | 06ed6c584d049775cbcffaaf09425038ed33ff64 | |
parent | f0729202a0b24c98d3782059773e7f9763223600 (diff) | |
download | ATCD-a219563acd6e2720f19519c2b8e5902fde3f0832.tar.gz |
ChangeLogTag: Tue Sep 10 14:06:02 2002 Krishnakumar B <kitty@cs.wustl.edu>
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 21 | ||||
-rw-r--r-- | ace/Obstack_T.cpp | 50 | ||||
-rw-r--r-- | ace/Obstack_T.h | 21 | ||||
-rw-r--r-- | tests/Obstack_Test.cpp | 84 |
5 files changed, 169 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog index 47822ae4169..ee239cc187f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Tue Sep 10 14:06:02 2002 Krishnakumar B <kitty@cs.wustl.edu> + + * ace/Obstack_T.cpp: + * ace/Obstack_T.h: + + Obstack is no longer restricted to fixed-size chunks. Chunk size + is increased by a power of two if we run out of memory in a + chunk. Added implementation of unwind operations. Stack can be + unwound by giving the address of an object on the stack. Fixed a + couple of bugs in the existing implementation when used with + WCHAR. We were incrementing the pointers by sizeof (CHAR) as + well as multiplying by sizeof (CHAR) to get the number of bytes + to be copied. This improvement doesn't deal with the alignment + issues as it requires a change in Obchunk which is postponed + till ACE 5.2.3 is released. + + * tests/Obstack_Test.cpp: + + New, improved test which exercises all the code paths in the + implementation unlike the previous test. + Tue Sep 10 12:32:33 2002 Carlos O'Ryan <coryan@atdesk.com> * ace/Connector.cpp: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index 47822ae4169..ee239cc187f 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,24 @@ +Tue Sep 10 14:06:02 2002 Krishnakumar B <kitty@cs.wustl.edu> + + * ace/Obstack_T.cpp: + * ace/Obstack_T.h: + + Obstack is no longer restricted to fixed-size chunks. Chunk size + is increased by a power of two if we run out of memory in a + chunk. Added implementation of unwind operations. Stack can be + unwound by giving the address of an object on the stack. Fixed a + couple of bugs in the existing implementation when used with + WCHAR. We were incrementing the pointers by sizeof (CHAR) as + well as multiplying by sizeof (CHAR) to get the number of bytes + to be copied. This improvement doesn't deal with the alignment + issues as it requires a change in Obchunk which is postponed + till ACE 5.2.3 is released. + + * tests/Obstack_Test.cpp: + + New, improved test which exercises all the code paths in the + implementation unlike the previous test. + Tue Sep 10 12:32:33 2002 Carlos O'Ryan <coryan@atdesk.com> * ace/Connector.cpp: diff --git a/ace/Obstack_T.cpp b/ace/Obstack_T.cpp index 4d342c33506..cb96dd40a13 100644 --- a/ace/Obstack_T.cpp +++ b/ace/Obstack_T.cpp @@ -39,14 +39,12 @@ ACE_Obstack_T<CHAR>::request (size_t len) // Check to see if there's room for the requested length, including // any part of an existing string, if any. - size_t resulting_len = - ((this->curr_->cur_ - this->curr_->block_) * sizeof (CHAR)) + len; + size_t resulting_len = (this->curr_->cur_ - this->curr_->block_) + len; - // We will always have enough room for null terminating char - // unless sizeof (char) > 4. - // There's no way we can handle more than this->size_ of strings. + // Increase the length of the underlying chunks if the request made is + // for bigger sized chunks. if (this->size_ < resulting_len) - return -1; + this->size_ = this->size_ << 1; // We now know the request will fit; see if it can fit in the current // chunk or will need a new one. @@ -58,7 +56,10 @@ ACE_Obstack_T<CHAR>::request (size_t len) if (this->curr_->next_ == 0) { // We must allocate new memory. - this->curr_->next_ = this->new_chunk (); + ACE_Obchunk* tmp = this->new_chunk(); + if (!tmp) + return -1; + this->curr_->next_ = tmp; this->curr_ = this->curr_->next_; } else @@ -71,11 +72,13 @@ ACE_Obstack_T<CHAR>::request (size_t len) // Copy any initial characters to the new chunk. if (temp->cur_ != temp->block_) { - size_t datasize = (temp->cur_ - temp->block_) * sizeof (CHAR); + size_t datasize = temp->cur_ - temp->block_; ACE_OS::memcpy (this->curr_->block_, temp->block_, datasize); this->curr_->cur_ = this->curr_->block_ + datasize; + // Reset the old chunk. + temp->cur_ = temp->block_; } } @@ -142,7 +145,7 @@ ACE_Obstack_T<CHAR>::~ACE_Obstack_T (void) { ACE_Obchunk *next = temp->next_; temp->next_ = 0; - this->allocator_strategy_->free ((void *) temp); + this->allocator_strategy_->free (temp); temp = next; } } @@ -163,6 +166,35 @@ ACE_Obstack_T<CHAR>::copy (const CHAR *s, } template <class CHAR> void +ACE_Obstack_T<CHAR>::unwind (void* obj) +{ + if (obj >= this->curr_->contents_ && obj < this->curr_->end_) + this->curr_->block_ = this->curr_->cur_ = ACE_reinterpret_cast (char*, + obj); + else + this->unwind_i (obj); +} + +template <class CHAR> void +ACE_Obstack_T<CHAR>::unwind_i (void* obj) +{ + ACE_Obchunk* curr; + + curr = this->head_; + while (curr != 0 && (curr->contents_ > obj || curr->end_ < obj)) + curr = curr->next_; + if (curr) + { + this->curr_ = curr; + this->curr_->block_ = this->curr_->cur_ = ACE_reinterpret_cast (char*, + obj); + } + else if (obj != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("Deletion of non-existent object.\n%a"))); +} + +template <class CHAR> void ACE_Obstack_T<CHAR>::release (void) { ACE_TRACE ("ACE_Obstack_T<CHAR>::release"); diff --git a/ace/Obstack_T.h b/ace/Obstack_T.h index 098dd5b29a4..9f4dd1f06aa 100644 --- a/ace/Obstack_T.h +++ b/ace/Obstack_T.h @@ -65,13 +65,22 @@ public: CHAR *copy (const CHAR *data, size_t len); - /// Return the maximum @a length or @a size of a string that can be put into - /// this Obstack. @a size = @a length * sizeof (CHAR). + /// Return the maximum @a length or @a size of a string that can be put + /// into this Obstack. @a size = @a length * sizeof (CHAR). + /// + /// Deprecated : No need to use this function as you can put objects of + /// arbitrary lengths into the obstack now. size_t length (void) const; size_t size (void) const; - /// "Release" the entire stack of Obchunks, putting it back on the - /// free list. + /// "Unwind" the stack. If @a obj is a null pointer, everything allocated + /// in the stack is released. Otherwise, @a obj must be an address of an + /// object allocated in the stack. In this case, @a obj is released along + /// with everthing allocated in the Obstack since @a obj. + void unwind (void* obj); + + /// "Release" the entire stack of Obchunks, putting it back on the free + /// list. void release (void); /// Dump the state of an object. @@ -83,6 +92,10 @@ public: protected: class ACE_Obchunk *new_chunk (void); + /// Search through the list of Obchunks and release them. Helper funtion + /// used by unwind. + void unwind_i (void* obj); + /// Pointer to the allocator used by this Obstack. ACE_Allocator *allocator_strategy_; diff --git a/tests/Obstack_Test.cpp b/tests/Obstack_Test.cpp index 33db8816ae2..110fea4eba9 100644 --- a/tests/Obstack_Test.cpp +++ b/tests/Obstack_Test.cpp @@ -31,30 +31,84 @@ int ACE_TMAIN (int, ACE_TCHAR *[]) int errors = 0; // For this test, the length of the ACE_Obstack must be larger than // both of these strings, but less than their sum. - const ACE_TCHAR *str1 = ACE_TEXT ("Mary had a little lamb."); - const ACE_TCHAR *str2 = ACE_TEXT ("It's fleece was white as snow."); - ACE_Obstack_T<ACE_TCHAR> stack (ACE_OS_String::strlen (str2) + 5); + const ACE_TCHAR str1[] = ACE_TEXT ("Mary had a little lamb."); + const ACE_TCHAR str2[] = ACE_TEXT ("It's fleece was white as snow; but...."); + ACE_Obstack_T<ACE_TCHAR> stack (sizeof (str1) + 1); - // This test checks to see that if a request can't be lengthened, - // the first part of it doesn't get lost. for (size_t i = 0; i < ACE_OS_String::strlen (str1); i++) stack.grow_fast (str1[i]); - if (stack.request (ACE_OS_String::strlen (str2)) == 0) { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("Request allowed but it should overflow\n"))); - ++errors; - } + ACE_TCHAR *str = stack.freeze (); - if (str == 0) { + + if (str == 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("freeze failed!\n"))); + ++errors; + } + else if (ACE_OS_String::strcmp (str, str1) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("Lost first string; expected: %s, have: %s\n"), + str1, str)); + ++errors; + } + + for (size_t j = 0; j < ACE_OS_String::strlen (str2); ++j) + stack.grow (str2[j]); + + ACE_TCHAR* temp = stack.freeze(); + + if (temp == 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("freeze failed!\n"))); + ++errors; + } + else if (ACE_OS::strcmp (temp, str2) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("Lost second string; expected: %s, have: %s\n"), + str2, temp)); + ++errors; + } + + for (size_t k = 0; k < ACE_OS_String::strlen (str1); ++k) + stack.grow (str1[k]); + + ACE_TCHAR* tmp = stack.freeze (); + if (tmp == 0) + { ACE_ERROR ((LM_ERROR, ACE_TEXT ("freeze failed!\n"))); ++errors; } - else if (ACE_OS_String::strcmp (str, str1) != 0) { - ACE_ERROR ((LM_ERROR, ACE_TEXT ("Lost a string; expected: %s, have: %s\n"), - str1, str)); + else if (ACE_OS_String::strcmp (tmp, str1) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Lost third string; expected: %s, have: %s\n"), + str1, tmp)); + ++errors; + } + + stack.unwind (temp); + + for (size_t l = 0; l < ACE_OS_String::strlen (str2); ++l) + stack.grow (str2[l]); + + temp = stack.freeze(); + + if (temp == 0) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("freeze failed!\n"))); + ++errors; + } + else if (ACE_OS::strcmp (temp, str2) != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Lost fourth string; expected: %s, have: %s\n"), + str2, temp)); ++errors; } - else + + if (!errors) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Test ok\n"))); ACE_END_TEST; |