Since we require every process to map the shared memory region to the same
address, we don't need the MAKE_PTR/OFFSET code that was needed when that
was not the case. This patch makes shared memory pointers just like
regular pointers.
http://archives.postgresql.org/pgsql-general/2007-08/msg01510.php
Kris Jurka*** a/src/backend/access/transam/twophase.c
--- b/src/backend/access/transam/twophase.c
***
*** 122,128 typedef struct GlobalTransactionData
typedef struct TwoPhaseStateData
{
/* Head of linked list of free GlobalTransactionData structs */
! SHMEM_OFFSET freeGXacts;
/* Number of valid prepXacts entries. */
int numPrepXacts;
--- 122,128
typedef struct TwoPhaseStateData
{
/* Head of linked list of free GlobalTransactionData structs */
! void * freeGXacts;
/* Number of valid prepXacts entries. */
int numPrepXacts;
***
*** 184,190 TwoPhaseShmemInit(void)
int i;
Assert(!found);
! TwoPhaseState->freeGXacts = INVALID_OFFSET;
TwoPhaseState->numPrepXacts = 0;
/*
--- 184,190
int i;
Assert(!found);
! TwoPhaseState->freeGXacts = NULL;
TwoPhaseState->numPrepXacts = 0;
/*
***
*** 197,203 TwoPhaseShmemInit(void)
for (i = 0; i < max_prepared_xacts; i++)
{
gxacts[i].proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = MAKE_OFFSET(&gxacts[i]);
}
}
else
--- 197,203
for (i = 0; i < max_prepared_xacts; i++)
{
gxacts[i].proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = &gxacts[i];
}
}
else
***
*** 243,249 MarkAsPreparing(TransactionId xid, const char *gid,
TwoPhaseState->prepXacts[i] =
TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
/* Back up index count too, so we don't miss scanning
one */
i--;
}
--- 243,249
TwoPhaseState->prepXacts[i] =
TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = gxact;
/* Back up index count too, so we don't miss scanning
one */
i--;
}
***
*** 263,275 MarkAsPreparing(TransactionId xid, const char *gid,
}
/* Get a free gxact from the freelist */
! if (TwoPhaseState->freeGXacts == INVALID_OFFSET)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("maximum number of prepared
transactions reached"),
errhint("Increase max_prepared_transactions
(currently %d).",
max_prepared_xacts)));
! gxact = (GlobalTransaction) MAKE_PTR(TwoPhaseState->freeGXacts);
TwoPhaseState->freeGXacts = gxact->proc.links.next;
/* Initialize it */
--- 263,275
}
/* Get a free gxact from the freelist */
! if (TwoPhaseState->freeGXacts == NULL)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("maximum number of prepared
transactions reached"),
errhint("Increase max_prepared_transactions
(currently %d).",
max_prepared_xacts)));
! gxact = (GlobalTransaction)TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = gxact->proc.links.next;
/* Initialize it */
***
*** 452,458 RemoveGXact(GlobalTransaction gxact)
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
LWLockRelease(TwoPhaseStateLock);
--- 452,458
/* and put it back in the freelist */
gxact->proc.links.next = TwoPhaseState->freeGXacts;
! TwoPhaseState->freeGXacts = gxact;