On Jul 8, 2014, at 1:02 PM, Sergey Isakov <[email protected]> wrote:
>
> On 08 июля 2014 г., at 23:56, Andrew Fish <[email protected]> wrote:
>
>> ASSERT(Buffer != NULL);
>> //
>> // Get the head & tail of the pool entry
>> //
>> Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
>> ASSERT(Head != NULL);
>>
> CR macro will not find POOL_HEAD structure. It assumes buffer contain it.
Buffer is the pointer returned by gBS->AllocatePool() and that same pointer
must be passed into gBS->FreePool().
The BASE_CR() macro does the pointer magic in the CR() macro:
https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Include/Base.h
/**
Macro that returns a pointer to the data structure that contains a specified
field of
that data structure. This is a lightweight method to hide information by
placing a
public data structure inside a larger private data structure and using a
pointer to
the public data structure to retrieve a pointer to the private data structure.
This function computes the offset, in bytes, of field specified by Field from
the beginning
of the data structure specified by TYPE. This offset is subtracted from
Record, and is
used to return a pointer to a data structure of the type specified by TYPE.
If the data type
specified by TYPE does not contain the field specified by Field, then the
module will not compile.
@param Record Pointer to the field specified by Field within a data
structure of type TYPE.
@param TYPE The name of the data structure type to return. This data
structure must
contain the field specified by Field.
@param Field The name of the field in the data structure specified by
TYPE to which Record points.
@return A pointer to the structure from one of it's elements.
**/
#define BASE_CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *)
&(((TYPE *) 0)->Field))
So in our case:
Record == Buffer
TYPE == POOL_HEAD
Field == Data
So basically “&(((TYPE *) 0)->Field)” figures out the offset of Data in the
POOL_HEAD struct. This offset is subtracted from Buffer, so that a pointer to
POOL_HEAD is returned.
The CR() macro is used in a lot of protocol implementations to get the drivers
private data back from the pointer to the protocol instance. The memory for the
protocol data structure is part of the drivers larger private data.
Thanks,
Andrew Fish
> ------------------------------------------------------------------------------
> Open source business process management suite built on Java and Eclipse
> Turn processes into business applications with Bonita BPM Community Edition
> Quickly connect people, data, and systems into organized workflows
> Winner of BOSSIE, CODIE, OW2 and Gartner awards
> http://p.sf.net/sfu/Bonitasoft_______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/edk2-devel
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel