Home > Software engineering >  Discuss: MFC source code of _afxThreadData AllocSlot () function in the distribution of a tank may c
Discuss: MFC source code of _afxThreadData AllocSlot () function in the distribution of a tank may c

Time:10-09

MFC realize thread-local variables, introduced a kind of CThreadSlotData, define _afxThreadData is class CThreadSlotData pointer, its members m_pSlotData is a dynamic array, the groove of the global distribution of the dynamic array by AllocSlot query, modify, update, I carefully followed AllocSlot () function algorithm, find a slot in the using process of the current release, continue to allocate slots, could put a redistribution are using slot,

AllocSlot () code is as follows:
Int CThreadSlotData: : AllocSlot ()
{//this function for global array m_pSlotData m_nAlloc and m_nMax these three data members operate

Int nAlloc=m_nAlloc; The length of the array//m_pSlotData
Int nSlot=m_nRover; Under the current assigned slot//a slot has not been used (in most cases)

1) if (nSlot & gt;=nAlloc)/* | | m_pSlotData [nSlot] dwFlags & amp; SLOT_USED) */
{//when nSlot achieve value of 32, said slot allocation from 1 to 31 groove, the if condition to limit
(2) for (nSlot=1; NSlot//when nSlot reached 32, between May 1 to 31 slots are likely to be released, so use a for loop search again, if there is no empty slot, apply more space
(3) if (nSlot>=nAlloc)//if nSlot still a value greater than 32 after the for loop, explains the 31 in front of the tank full fill, really need to apply for space
{
Int nNewAlloc=nAlloc + 32;
HGLOBAL hSlotData;

If (m_pSlotData=NULL https://bbs.csdn.net/topics/=
{
HSlotData=https://bbs.csdn.net/topics/::GlobalAlloc (GMEM_MOVEABLE, nNewAlloc * sizeof (CSlotData));
}
The else
{
HSlotData=https://bbs.csdn.net/topics/::GlobalHandle (m_pSlotData);
: : GlobalUnlock (hSlotData);
HSlotData=https://bbs.csdn.net/topics/::GlobalReAlloc (hSlotData, nNewAlloc * sizeof (CSlotData), GMEM_MOVEABLE);
}
CSlotData * pSlotData=https://bbs.csdn.net/topics/(CSlotData *) : : GlobalLock (hSlotData);
Memset (pSlotData + m_nAlloc, 0, (nNewAlloc - nAlloc) * sizeof (CSlotData));
M_nAlloc=nNewAlloc;
M_pSlotData=https://bbs.csdn.net/topics/pSlotData;

}


}
(4) if (nSlot>=nAlloc) if (nSlot & gt;=m_nMax)//if the search to the slot number is greater than the slot takes up the maximum value, increase the slot takes up the maximum, whereas the maximum remains unchanged
M_nMax=nSlot + 1;
M_pSlotData [nSlot] dwFlags |=SLOT_USED;
(5) m_nRover=nSlot + 1;
Return nSlot;
}


When 0 - all 31 slot allocation, all those 32 slot in the occupied state, if the fifth slot is released (FreeSlot (5)), and then continue to allocate slots, AllocSlot () function call process will be like this:
A, AllocSlot () call, as shown in the code where won the bid for (1)
1) if (nSlot & gt;=nAlloc) nSlot=32, m_nAlloc 32, this condition was established, to enter the if statement inside the
Second, processes in the code where labeled (2)
(2) for (nSlot=1; NSlotTraverse the for loop from 1 to 32, are free to find the groove, because 5 slot has been released, the end of the for loop, nSlot value will be 5
Three process came to code the bidding for (3) local
(3) if (nSlot>=nAlloc) nSlot=5, nAlloc=32, condition is false if statement block,
Four, process to the code (4) location
M_pSlotData [nSlot] dwFlags |=SLOT_USED; Statement will put 5 slots for the use of state,
Then the next statement of m_nRover=nSlot + 1 (4) location of the (code), will put m_nRover for 6
Analysis: this means that the next time distribution trough, will be allocated slot 6, note: use this slot 6, for a slot in the using state, is can't allocated to it,
In order to verify my guess, I like CThreadSlotData class implementation, simulated redistribution after the release of a slot, the results really appeared this problem I say
The working process of the source code:
Executed first 32 AllocSlot (), let all 0-31 slots in the occupied state
Release 5 slot, and then call AllocSlot () slot allocation, the m_nRover has a value of 5 + 1=6; 6 slot in the occupied state,
Then call AllocSlot () distribution trough, the question arises, in the occupied state of 6 slot be redistributed, namely covers,

The solution,
The problem is the cause of AllocSlot () function m_nRover value didn't get the right to update, the update m_nRover value, should use a loop through the dynamic array, find next free slot, under a free slot number is assigned to m_nRover, this problem can be solved,
Namely the m_nRover=nSlot + 1 use a for loop instead of
For (int SlotNum=1; SlotNumM_nRover=SlotNum;


_afxtsl. H code is as follows:
H # include "Windows."
# # ifndef __AFXTLS_H__
# define __AFXTLS_H__



Struct CSlotData
{
DWORD dwFlags;
HINSTANCE hInst,
};


The class CThreadSlotData
{
Public:
CThreadSlotData ();

Int AllocSlot ();
Void FreeSlot (int nSlot);

Int m_nAlloc;
Int m_nRover;
Int m_nMax;
CSlotData * m_pSlotData;
~ CThreadSlotData ();

};
# endif
Afxtls. CPP source code is as follows:
# include "_afxtls. H"
# define SLOT_USED 0 x01
CThreadSlotData: : CThreadSlotData ()
{

M_nMax=0;
M_nRover=1;
M_nAlloc=0;
M_pSlotData=https://bbs.csdn.net/topics/NULL;

}

Int CThreadSlotData: : AllocSlot ()
{//this function for global array m_pSlotData m_nAlloc and m_nMax these three data members operate


Int nAlloc=m_nAlloc; The length of the array//m_pSlotData
Int nSlot=m_nRover; Under the current assigned slot//a slot has not been used (in most cases)

If (nSlot & gt;=nAlloc)/* | | m_pSlotData [nSlot] dwFlags & amp; SLOT_USED) */
{//when nSlot achieve value of 32, said slot allocation from 1 to 31 groove, the if condition to limit
For (nSlot=1; NSlot//when nSlot reached 32, between May 1 to 31 slots are likely to be released, so use a for loop search again, if there is no empty slot, apply more space
If (nSlot>=nAlloc)//if nSlot still a value greater than 32 after the for loop, explains the 31 in front of the tank full fill, really need to apply for space
{
Int nNewAlloc=nAlloc + 32;
HGLOBAL hSlotData;

If (m_pSlotData=NULL https://bbs.csdn.net/topics/=
{
HSlotData=https://bbs.csdn.net/topics/::GlobalAlloc (GMEM_MOVEABLE, nNewAlloc * sizeof (CSlotData));
}
The else
{
HSlotData=https://bbs.csdn.net/topics/::GlobalHandle (m_pSlotData);
: : GlobalUnlock (hSlotData);
HSlotData=https://bbs.csdn.net/topics/::GlobalReAlloc (hSlotData, nNewAlloc * sizeof (CSlotData), GMEM_MOVEABLE);
}
CSlotData * pSlotData=https://bbs.csdn.net/topics/(CSlotData *) : : GlobalLock (hSlotData);
Memset (pSlotData + m_nAlloc, 0, (nNewAlloc - nAlloc) * sizeof (CSlotData));
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related