9696use crate :: alloc:: alloc:: { self , Layout , LayoutError } ;
9797
9898use std:: sync:: atomic:: Ordering :: { Acquire , Relaxed , Release } ;
99- use std:: sync:: atomic:: { self , AtomicUsize } ;
99+ use std:: sync:: atomic:: { self , AtomicU32 } ;
100100use std:: { cmp, mem, num:: NonZeroUsize , ptr, ptr:: NonNull , slice} ;
101101
102102use crate :: { info:: Info , info:: Kind } ;
@@ -117,12 +117,14 @@ pub(crate) struct Storage {
117117 offset : NonZeroUsize ,
118118}
119119
120+ #[ derive( Debug ) ]
120121/// Thread-safe reference-counted container for the shared storage.
121122struct SharedVec {
122- len : u32 ,
123123 offset : u32 ,
124+ len : u32 ,
125+ capacity : u32 ,
124126 remaining : u32 ,
125- ref_count : AtomicUsize ,
127+ ref_count : AtomicU32 ,
126128}
127129
128130pub ( crate ) struct StorageVec ( NonNull < SharedVec > ) ;
@@ -138,6 +140,8 @@ const KIND_OFFSET_BITS: usize = 2;
138140pub const METADATA_SIZE : usize = mem:: size_of :: < SharedVec > ( ) ;
139141const METADATA_SIZE_U32 : u32 = METADATA_SIZE as u32 ;
140142
143+ pub ( crate ) const MIN_CAPACITY : usize = 128 - crate :: METADATA_SIZE ;
144+
141145// Bit op constants for extracting the inline length value from the `ptr` field.
142146const INLINE_LEN_MASK : usize = 0b1111_1100 ;
143147
@@ -493,7 +497,7 @@ impl Storage {
493497 // ptr points to SharedVec
494498 let shared = self . shared_vec ( ) ;
495499 let ref_cnt = ( * shared) . ref_count . fetch_add ( 1 , Relaxed ) ;
496- if ref_cnt == usize :: MAX {
500+ if ref_cnt == u32 :: MAX {
497501 abort ( ) ;
498502 }
499503
@@ -649,8 +653,7 @@ impl StorageVec {
649653 }
650654
651655 pub ( crate ) fn capacity ( & self ) -> usize {
652- let ptr = unsafe { & * self . 0 . as_ptr ( ) } ;
653- ptr. len as usize + ptr. remaining as usize
656+ unsafe { ( * self . 0 . as_ptr ( ) ) . capacity as usize }
654657 }
655658
656659 pub ( crate ) fn remaining ( & self ) -> usize {
@@ -686,7 +689,10 @@ impl StorageVec {
686689 Storage :: from_ptr_inline ( ptr, at)
687690 } else {
688691 let inner = self . as_inner ( ) ;
689- inner. ref_count . fetch_add ( 1 , Relaxed ) ;
692+ let ref_cnt = inner. ref_count . fetch_add ( 1 , Relaxed ) ;
693+ if ref_cnt == u32:: MAX {
694+ abort ( ) ;
695+ }
690696
691697 let offset = inner. offset as usize ;
692698 Storage {
@@ -710,12 +716,11 @@ impl StorageVec {
710716 if len == 0 {
711717 let inner = self . as_inner ( ) ;
712718 if inner. is_unique ( ) && inner. offset != METADATA_SIZE_U32 {
713- let cap = ( inner. offset as usize )
714- + inner. len as usize
715- + inner. remaining as usize ;
719+ let cap = ( inner. offset as usize ) + inner. capacity as usize ;
716720 inner. len = 0 ;
717721 inner. offset = METADATA_SIZE_U32 ;
718- inner. remaining = ( cap - METADATA_SIZE ) as u32 ;
722+ inner. capacity = ( cap - METADATA_SIZE ) as u32 ;
723+ inner. remaining = inner. capacity ;
719724 return ;
720725 }
721726 }
@@ -768,16 +773,15 @@ impl StorageVec {
768773 let new_cap = len + additional;
769774
770775 if inner. is_unique ( ) {
771- let capacity = ( inner. offset as usize )
772- + ( inner. len as usize )
773- + ( inner. remaining as usize ) ;
776+ let capacity = ( inner. offset as usize ) + ( inner. capacity as usize ) ;
774777
775778 // try to reclaim the buffer. This is possible if the current
776779 // handle is the only outstanding handle pointing to the buffer.
777780 if capacity >= ( new_cap + METADATA_SIZE ) {
778781 let offset = inner. offset ;
779782 inner. offset = METADATA_SIZE_U32 ;
780783 inner. remaining = ( capacity - len - METADATA_SIZE ) as u32 ;
784+ inner. capacity = inner. len + inner. remaining ;
781785
782786 // The capacity is sufficient, reclaim the buffer
783787 if len != 0 {
@@ -794,24 +798,23 @@ impl StorageVec {
794798
795799 #[ inline]
796800 pub ( crate ) unsafe fn set_len ( & mut self , len : usize ) {
797- let cap = self . capacity ( ) ;
798- assert ! ( len <= cap ) ;
801+ let inner = self . 0 . as_mut ( ) ;
802+ assert ! ( len as u32 <= inner . capacity ) ;
799803
800- let vec = self . 0 . as_mut ( ) ;
801- vec. len = len as u32 ;
802- vec. remaining = ( cap - len) as u32 ;
804+ inner. len = len as u32 ;
805+ inner. remaining = inner. capacity - ( len as u32 ) ;
803806 }
804807
805808 pub ( crate ) unsafe fn set_start ( & mut self , start : u32 ) {
806809 if start != 0 {
807- let cap = self . capacity ( ) ;
808810 let inner = self . as_inner ( ) ;
809811
810812 assert ! (
811- start <= cap as u32 ,
812- "Cannot set start position offset:{} len:{} remaining:{}, new-len:{start}" ,
813+ start <= inner . capacity ,
814+ "Cannot set start position offset:{} len:{} cap:{} remaining:{} new-len:{start}" ,
813815 inner. offset,
814816 inner. len,
817+ inner. capacity,
815818 inner. remaining,
816819 ) ;
817820
@@ -825,7 +828,8 @@ impl StorageVec {
825828 } else {
826829 inner. len = 0 ;
827830 }
828- inner. remaining = cap as u32 - inner. len - start;
831+ inner. remaining = inner. capacity - inner. len - start;
832+ inner. capacity = inner. remaining + inner. len ;
829833 }
830834 }
831835}
@@ -861,14 +865,16 @@ impl SharedVec {
861865 if ptr. is_null ( ) {
862866 alloc:: handle_alloc_error ( layout) ;
863867 }
868+ let capacity = ( layout. size ( ) - METADATA_SIZE ) as u32 ;
864869
865870 ptr:: write (
866871 ptr as * mut SharedVec ,
867872 SharedVec {
868873 len,
874+ capacity,
875+ remaining : capacity - len,
869876 offset : METADATA_SIZE_U32 ,
870- remaining : ( layout. size ( ) - METADATA_SIZE - len as usize ) as u32 ,
871- ref_count : AtomicUsize :: new ( 1 ) ,
877+ ref_count : AtomicU32 :: new ( 1 ) ,
872878 } ,
873879 ) ;
874880 ptr
@@ -881,7 +887,7 @@ impl SharedVec {
881887 }
882888
883889 fn capacity ( & self ) -> usize {
884- self . len as usize + self . remaining as usize
890+ self . capacity as usize
885891 }
886892}
887893
@@ -912,7 +918,7 @@ fn release_shared_vec(ptr: *mut SharedVec) {
912918 atomic:: fence ( Acquire ) ;
913919
914920 // Drop the data
915- let cap = ( * ptr) . offset as usize + ( * ptr) . remaining as usize + ( * ptr ) . len as usize ;
921+ let cap = ( * ptr) . offset as usize + ( * ptr) . capacity as usize ;
916922 ptr:: drop_in_place ( ptr) ;
917923 let layout = shared_vec_layout ( cap - METADATA_SIZE ) . unwrap ( ) ;
918924 alloc:: dealloc ( ptr as * mut _ , layout) ;
0 commit comments