@@ -56,56 +56,42 @@ HazardDelayedDelete* HazardBase::getHazardDelayed(Attachment* att)
5656 return &att->att_delayed_delete ;
5757}
5858
59- HazardDelayedDelete::HazardPointers* HazardDelayedDelete::HazardPointers::create (MemoryPool& p, unsigned size )
59+ void HazardDelayedDelete::add ( const void * ptr )
6060{
61- return FB_NEW_RPT (p, size) HazardPointers (size);
62- }
63-
64- void HazardDelayedDelete::add (Ptr ptr)
65- {
66- // as long as we access our own hazard pointers single relaxed load is OK
67- HazardPointers *hp = hazardPointers.load (std::memory_order_relaxed);
61+ // as long as we access our own hazard pointers use of write accessor is always OK
62+ auto hp = hazardPointers.writeAccessor ();
6863
6964 // 1. Search for holes
70- for (unsigned n = 0 ; n < hp->hpCount ; ++n)
65+ for (unsigned n = 0 ; n < hp->getCount () ; ++n)
7166 {
72- if (! hp->hp [n] )
67+ if (hp->value (n) == nullptr )
7368 {
74- hp->hp [n] = ptr;
69+ // store
70+ hp->value (n) = ptr;
7571 return ;
7672 }
7773 }
7874
7975 // 2. Grow if needed
80- if (hp->hpCount >= hp->hpSize )
81- {
82- HazardPointers* newHp = HazardPointers::create (getPool (), hp->hpSize * 2 );
83- memcpy (newHp->hp , hp->hp , hp->hpCount * sizeof (hp->hp [0 ]));
84- newHp->hpCount = hp->hpCount ;
85-
86- HazardPointers* oldHp = hp;
87- hazardPointers.store ((hp = newHp));
88- delayedDelete (oldHp); // delay delete for a case when someone else is accessing it now
89- }
76+ if (!hp->hasSpace ())
77+ hazardPointers.grow (this );
9078
9179 // 3. Append
92- hp-> hp [hp-> hpCount ] = ptr ;
93- hp->hpCount ++ ;
80+ hp = hazardPointers. writeAccessor () ;
81+ *( hp->add ()) = ptr ;
9482}
9583
96- void HazardDelayedDelete::remove (Ptr ptr)
84+ void HazardDelayedDelete::remove (const void * ptr)
9785{
98- // as long as we access our own hazard pointers single relaxed load is OK
99- HazardPointers * hp = hazardPointers.load (std::memory_order_relaxed );
86+ // as long as we access our own hazard pointers use of write accessor is always OK
87+ auto hp = hazardPointers.writeAccessor ( );
10088
101- for (unsigned n = 0 ; n < hp->hpCount ; ++n)
89+ for (unsigned n = 0 ; n < hp->getCount () ; ++n)
10290 {
103- if (hp->hp [n] == ptr)
91+ if (hp->value (n) == ptr)
10492 {
105- hp->hp [n] = nullptr ;
106-
107- while (hp->hpCount && !hp->hp [hp->hpCount - 1 ])
108- hp->hpCount --;
93+ hp->value (n) = nullptr ;
94+ hp->truncate (nullptr );
10995 return ;
11096 }
11197 }
@@ -122,29 +108,29 @@ void HazardDelayedDelete::delayedDelete(HazardObject* mem, bool gc)
122108 garbageCollect (GarbageCollectMethod::GC_NORMAL);
123109}
124110
125- void HazardDelayedDelete::copyHazardPointers (LocalHP& local, Ptr* from, unsigned count )
111+ void HazardDelayedDelete::copyHazardPointers (LocalHP& local, HazardPtr<HazardPointers>& from)
126112{
127- for (unsigned n = 0 ; n < count ; ++n)
113+ for (unsigned n = 0 ; n < from-> getCount () ; ++n)
128114 {
129- if (from[n])
130- local.push (from[n]);
115+ const void * ptr = from->value (n);
116+ if (ptr)
117+ local.push (ptr);
131118 }
132119}
133120
134121void HazardDelayedDelete::copyHazardPointers (thread_db* tdbb, LocalHP& local, Attachment* from)
135122{
136123 for (Attachment* attachment = from; attachment; attachment = attachment->att_next )
137124 {
138- HazardPtr<HazardPointers> hp (tdbb, attachment->att_delayed_delete .hazardPointers );
139- copyHazardPointers (local, hp-> hp , hp-> hpCount );
125+ HazardPtr<HazardPointers> hp = attachment->att_delayed_delete .hazardPointers . readAccessor (tdbb );
126+ copyHazardPointers (local, hp);
140127 }
141128}
142129
143130
144131void HazardDelayedDelete::garbageCollect (GarbageCollectMethod gcMethod)
145132{
146- HazardPointers *myHp = hazardPointers.load (std::memory_order_relaxed);
147- if (gcMethod == GarbageCollectMethod::GC_NORMAL && myHp->hpCount < DELETED_LIST_SIZE)
133+ if (gcMethod == GarbageCollectMethod::GC_NORMAL && toDelete.getCount () < DELETED_LIST_SIZE)
148134 return ;
149135
150136 thread_db* tdbb = JRD_get_thread_data ();
@@ -161,8 +147,8 @@ void HazardDelayedDelete::garbageCollect(GarbageCollectMethod gcMethod)
161147 copyHazardPointers (tdbb, localCopy, database->dbb_attachments );
162148 copyHazardPointers (tdbb, localCopy, database->dbb_sys_attachments );
163149
164- HazardPtr<HazardPointers> hp (tdbb, database->dbb_delayed_delete .hazardPointers );
165- copyHazardPointers (localCopy, hp-> hp , hp-> hpCount );
150+ HazardPtr<HazardPointers> hp = database->dbb_delayed_delete .hazardPointers . readAccessor (tdbb );
151+ copyHazardPointers (localCopy, hp);
166152 }
167153 localCopy.sort ();
168154
@@ -175,7 +161,7 @@ void HazardDelayedDelete::garbageCollect(GarbageCollectMethod gcMethod)
175161 else
176162 delete toDelete[i];
177163
178- if (i != keep)
164+ if (i + 1 > keep)
179165 toDelete[i] = nullptr ;
180166 }
181167 toDelete.shrink (keep);
@@ -198,5 +184,5 @@ void HazardDelayedDelete::garbageCollect(GarbageCollectMethod gcMethod)
198184HazardDelayedDelete::HazardPointers* HazardDelayedDelete::getHazardPointers ()
199185{
200186 // as long as we access our own hazard pointers single relaxed load is OK
201- return hazardPointers.load (std::memory_order_relaxed );
187+ return hazardPointers.writeAccessor ( );
202188}
0 commit comments