agora inbox for [email protected]
help / color / mirror / Atom feed[PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState
95+ messages / 5 participants
[nested] [flat]
* [PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState
@ 2023-02-25 21:39 Andres Freund <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Andres Freund @ 2023-02-25 21:39 UTC (permalink / raw)
---
src/include/nodes/execnodes.h | 1 -
src/backend/executor/execExpr.c | 81 +++++++++++++++++------------
src/backend/executor/execProcnode.c | 5 ++
src/backend/executor/nodeSubplan.c | 30 +++++------
4 files changed, 66 insertions(+), 51 deletions(-)
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 20f4c8b35f3..437cf8b5a02 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -947,7 +947,6 @@ typedef struct SubPlanState
struct PlanState *planstate; /* subselect plan's state tree */
struct PlanState *parent; /* parent plan node's state tree */
ExprState *testexpr; /* state of combining expression */
- List *args; /* states of argument expression(s) */
HeapTuple curTuple; /* copy of most recent tuple from subplan */
Datum curArray; /* most recent array from ARRAY() subplan */
/* these are used when hashing the subselect's output: */
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index c61f23c6c18..7a9d5729b4b 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -87,6 +87,9 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
int transno, int setno, int setoff, bool ishash,
bool nullcheck);
+static void ExecInitSubPlanExpr(SubPlan *subplan,
+ ExprState *state,
+ Datum *resv, bool *resnull);
/*
@@ -1388,7 +1391,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
case T_SubPlan:
{
SubPlan *subplan = (SubPlan *) node;
- SubPlanState *sstate;
/*
* Real execution of a MULTIEXPR SubPlan has already been
@@ -1405,19 +1407,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
break;
}
- if (!state->parent)
- elog(ERROR, "SubPlan found with no parent plan");
-
- sstate = ExecInitSubPlan(subplan, state->parent);
-
- /* add SubPlanState nodes to state->parent->subPlan */
- state->parent->subPlan = lappend(state->parent->subPlan,
- sstate);
-
- scratch.opcode = EEOP_SUBPLAN;
- scratch.d.subplan.sstate = sstate;
-
- ExprEvalPushStep(state, &scratch);
+ ExecInitSubPlanExpr(subplan, state, resv, resnull);
break;
}
@@ -2618,29 +2608,12 @@ ExecPushExprSetupSteps(ExprState *state, ExprSetupInfo *info)
foreach(lc, info->multiexpr_subplans)
{
SubPlan *subplan = (SubPlan *) lfirst(lc);
- SubPlanState *sstate;
Assert(subplan->subLinkType == MULTIEXPR_SUBLINK);
- /* This should match what ExecInitExprRec does for other SubPlans: */
-
- if (!state->parent)
- elog(ERROR, "SubPlan found with no parent plan");
-
- sstate = ExecInitSubPlan(subplan, state->parent);
-
- /* add SubPlanState nodes to state->parent->subPlan */
- state->parent->subPlan = lappend(state->parent->subPlan,
- sstate);
-
- scratch.opcode = EEOP_SUBPLAN;
- scratch.d.subplan.sstate = sstate;
-
/* The result can be ignored, but we better put it somewhere */
- scratch.resvalue = &state->resvalue;
- scratch.resnull = &state->resnull;
-
- ExprEvalPushStep(state, &scratch);
+ ExecInitSubPlanExpr(subplan, state,
+ &state->resvalue, &state->resnull);
}
}
@@ -4040,3 +4013,45 @@ ExecBuildParamSetEqual(TupleDesc desc,
return state;
}
+
+static void
+ExecInitSubPlanExpr(SubPlan *subplan,
+ ExprState *state,
+ Datum *resv, bool *resnull)
+{
+ ExprEvalStep scratch = {0};
+ SubPlanState *sstate;
+ ListCell *pvar;
+ ListCell *l;
+ EState *estate = state->parent->state;
+
+ if (!state->parent)
+ elog(ERROR, "SubPlan found with no parent plan");
+
+ /*
+ * Generate steps to evaluate input arguments for the subplan.
+ *
+ * Any calculation we have to do can be done in the parent econtext, since
+ * the Param values don't need to have per-query lifetime.
+ */
+ forboth(l, subplan->parParam, pvar, subplan->args)
+ {
+ int paramid = lfirst_int(l);
+ ParamExecData *prm = &estate->es_param_exec_vals[paramid];
+
+ ExecInitExprRec(lfirst(pvar), state, &prm->value, &prm->isnull);
+ }
+
+ sstate = ExecInitSubPlan(subplan, state->parent);
+
+ /* add SubPlanState nodes to state->parent->subPlan */
+ state->parent->subPlan = lappend(state->parent->subPlan,
+ sstate);
+
+ scratch.opcode = EEOP_SUBPLAN;
+ scratch.resvalue = resv;
+ scratch.resnull = resnull;
+ scratch.d.subplan.sstate = sstate;
+
+ ExprEvalPushStep(state, &scratch);
+}
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 4d288bc8d41..f62bb28140f 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -393,6 +393,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
/*
* Initialize any initPlans present in this node. The planner put them in
* a separate list for us.
+ *
+ * The defining characteristic of initplans is that they don't have
+ * arguments, so we don't need to evaluate them (in contrast to
+ * ExecInitSubPlanExpr()).
*/
subps = NIL;
foreach(l, node->initPlan)
@@ -401,6 +405,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
SubPlanState *sstate;
Assert(IsA(subplan, SubPlan));
+ Assert(subplan->args == NIL);
sstate = ExecInitSubPlan(subplan, result);
subps = lappend(subps, sstate);
}
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index c136f75ac24..3458ac007cd 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -107,7 +107,7 @@ ExecHashSubPlan(SubPlanState *node,
TupleTableSlot *slot;
/* Shouldn't have any direct correlation Vars */
- if (subplan->parParam != NIL || node->args != NIL)
+ if (subplan->parParam != NIL || subplan->args != NIL)
elog(ERROR, "hashed subplan with direct correlation not supported");
/*
@@ -231,7 +231,6 @@ ExecScanSubPlan(SubPlanState *node,
TupleTableSlot *slot;
Datum result;
bool found = false; /* true if got at least one subplan tuple */
- ListCell *pvar;
ListCell *l;
ArrayBuildStateAny *astate = NULL;
@@ -248,26 +247,20 @@ ExecScanSubPlan(SubPlanState *node,
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
/*
- * Set Params of this plan from parent plan correlation values. (Any
- * calculation we have to do is done in the parent econtext, since the
- * Param values don't need to have per-query lifetime.)
+ * We rely on the caller to evaluate plan correlation values, if
+ * necessary. However we still need to record the fact that the values
+ * (might have) changed, otherwise the ExecReScan() below won't know that
+ * nodes need to be rescanned.
*/
- Assert(list_length(subplan->parParam) == list_length(node->args));
-
- forboth(l, subplan->parParam, pvar, node->args)
+ Assert(list_length(subplan->parParam) == list_length(subplan->args));
+ foreach(l, subplan->parParam)
{
int paramid = lfirst_int(l);
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
- prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
- econtext,
- &(prm->isnull));
planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
}
- /*
- * Now that we've set up its parameters, we can reset the subplan.
- */
+ /* with that done, we can reset the subplan */
ExecReScan(planstate);
/*
@@ -817,6 +810,10 @@ slotNoNulls(TupleTableSlot *slot)
* as well as regular SubPlans. Note that we don't link the SubPlan into
* the parent's subPlan list, because that shouldn't happen for InitPlans.
* Instead, ExecInitExpr() does that one part.
+ *
+ * We also rely on ExecInitExpr(), more precisely ExecInitSubPlanExpr(), to
+ * evaluate input parameters, as that allows them to be evaluated as part of
+ * the expression referencing the SubPlan.
* ----------------------------------------------------------------
*/
SubPlanState *
@@ -844,7 +841,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
/* Initialize subexpressions */
sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent);
- sstate->args = ExecInitExprList(subplan->args, parent);
/*
* initialize my state
@@ -1107,7 +1103,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
elog(ERROR, "ANY/ALL subselect unsupported as initplan");
if (subLinkType == CTE_SUBLINK)
elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan");
- if (subplan->parParam || node->args)
+ if (subplan->parParam || subplan->args)
elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan");
/*
--
2.38.0
--6ir4gcdcv6d4j3qy--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState
@ 2023-02-25 21:39 Andres Freund <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Andres Freund @ 2023-02-25 21:39 UTC (permalink / raw)
---
src/include/executor/execExpr.h | 6 +-
src/include/nodes/execnodes.h | 1 -
src/backend/executor/execExpr.c | 93 +++++++++++++++++----------
src/backend/executor/execExprInterp.c | 22 +++++++
src/backend/executor/execProcnode.c | 5 ++
src/backend/executor/nodeSubplan.c | 30 ++++-----
src/backend/jit/llvm/llvmjit_expr.c | 6 ++
src/backend/jit/llvm/llvmjit_types.c | 1 +
8 files changed, 112 insertions(+), 52 deletions(-)
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 06c3adc0a19..ca2b7306cd0 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -158,6 +158,8 @@ typedef enum ExprEvalOp
EEOP_PARAM_EXEC,
EEOP_PARAM_EXTERN,
EEOP_PARAM_CALLBACK,
+ /* set PARAM_EXEC value */
+ EEOP_PARAM_SET,
/* return CaseTestExpr value */
EEOP_CASE_TESTVAL,
@@ -374,7 +376,7 @@ typedef struct ExprEvalStep
ExprEvalRowtypeCache rowcache;
} nulltest_row;
- /* for EEOP_PARAM_EXEC/EXTERN */
+ /* for EEOP_PARAM_EXEC/EXTERN and EEOP_PARAM_SET */
struct
{
int paramid; /* numeric ID for parameter */
@@ -738,6 +740,8 @@ extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
+extern void ExecEvalParamSet(ExprState *state, ExprEvalStep *op,
+ ExprContext *econtext);
extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index e7eb1e666ff..16e95e4cb48 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -947,7 +947,6 @@ typedef struct SubPlanState
struct PlanState *planstate; /* subselect plan's state tree */
struct PlanState *parent; /* parent plan node's state tree */
ExprState *testexpr; /* state of combining expression */
- List *args; /* states of argument expression(s) */
HeapTuple curTuple; /* copy of most recent tuple from subplan */
Datum curArray; /* most recent array from ARRAY() subplan */
/* these are used when hashing the subselect's output: */
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index c61f23c6c18..002f2a0091f 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -87,6 +87,9 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
FunctionCallInfo fcinfo, AggStatePerTrans pertrans,
int transno, int setno, int setoff, bool ishash,
bool nullcheck);
+static void ExecInitSubPlanExpr(SubPlan *subplan,
+ ExprState *state,
+ Datum *resv, bool *resnull);
/*
@@ -1388,7 +1391,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
case T_SubPlan:
{
SubPlan *subplan = (SubPlan *) node;
- SubPlanState *sstate;
/*
* Real execution of a MULTIEXPR SubPlan has already been
@@ -1405,19 +1407,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
break;
}
- if (!state->parent)
- elog(ERROR, "SubPlan found with no parent plan");
-
- sstate = ExecInitSubPlan(subplan, state->parent);
-
- /* add SubPlanState nodes to state->parent->subPlan */
- state->parent->subPlan = lappend(state->parent->subPlan,
- sstate);
-
- scratch.opcode = EEOP_SUBPLAN;
- scratch.d.subplan.sstate = sstate;
-
- ExprEvalPushStep(state, &scratch);
+ ExecInitSubPlanExpr(subplan, state, resv, resnull);
break;
}
@@ -2618,29 +2608,12 @@ ExecPushExprSetupSteps(ExprState *state, ExprSetupInfo *info)
foreach(lc, info->multiexpr_subplans)
{
SubPlan *subplan = (SubPlan *) lfirst(lc);
- SubPlanState *sstate;
Assert(subplan->subLinkType == MULTIEXPR_SUBLINK);
- /* This should match what ExecInitExprRec does for other SubPlans: */
-
- if (!state->parent)
- elog(ERROR, "SubPlan found with no parent plan");
-
- sstate = ExecInitSubPlan(subplan, state->parent);
-
- /* add SubPlanState nodes to state->parent->subPlan */
- state->parent->subPlan = lappend(state->parent->subPlan,
- sstate);
-
- scratch.opcode = EEOP_SUBPLAN;
- scratch.d.subplan.sstate = sstate;
-
/* The result can be ignored, but we better put it somewhere */
- scratch.resvalue = &state->resvalue;
- scratch.resnull = &state->resnull;
-
- ExprEvalPushStep(state, &scratch);
+ ExecInitSubPlanExpr(subplan, state,
+ &state->resvalue, &state->resnull);
}
}
@@ -4040,3 +4013,57 @@ ExecBuildParamSetEqual(TupleDesc desc,
return state;
}
+
+static void
+ExecInitSubPlanExpr(SubPlan *subplan,
+ ExprState *state,
+ Datum *resv, bool *resnull)
+{
+ ExprEvalStep scratch = {0};
+ SubPlanState *sstate;
+ ListCell *pvar;
+ ListCell *l;
+
+ if (!state->parent)
+ elog(ERROR, "SubPlan found with no parent plan");
+
+ /*
+ * Generate steps to evaluate input arguments for the subplan.
+ *
+ * We evaluate the argument expressions into ExprState's resvalue/resnull,
+ * and then use PARAM_SET to update the parameter. We do that, instead of
+ * evaluating directly into the param, to avoid depending on the pointer
+ * value remaining stable / being included in the generated expression. No
+ * danger of conflicts with other uses of resvalue/resnull as storing and
+ * using the value always is in subsequent steps.
+ *
+ * Any calculation we have to do can be done in the parent econtext, since
+ * the Param values don't need to have per-query lifetime.
+ */
+ forboth(l, subplan->parParam, pvar, subplan->args)
+ {
+ int paramid = lfirst_int(l);
+
+ ExecInitExprRec(lfirst(pvar), state,
+ &state->resvalue, &state->resnull);
+
+ scratch.opcode = EEOP_PARAM_SET;
+ scratch.d.param.paramid = paramid;
+ /* type isn't needed, but an old value could be confusing */
+ scratch.d.param.paramtype = InvalidOid;
+ ExprEvalPushStep(state, &scratch);
+ }
+
+ sstate = ExecInitSubPlan(subplan, state->parent);
+
+ /* add SubPlanState nodes to state->parent->subPlan */
+ state->parent->subPlan = lappend(state->parent->subPlan,
+ sstate);
+
+ scratch.opcode = EEOP_SUBPLAN;
+ scratch.resvalue = resv;
+ scratch.resnull = resnull;
+ scratch.d.subplan.sstate = sstate;
+
+ ExprEvalPushStep(state, &scratch);
+}
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 19351fe34bf..3cab8a5cdae 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -446,6 +446,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
&&CASE_EEOP_PARAM_EXEC,
&&CASE_EEOP_PARAM_EXTERN,
&&CASE_EEOP_PARAM_CALLBACK,
+ &&CASE_EEOP_PARAM_SET,
&&CASE_EEOP_CASE_TESTVAL,
&&CASE_EEOP_MAKE_READONLY,
&&CASE_EEOP_IOCOERCE,
@@ -1081,6 +1082,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_NEXT();
}
+ EEO_CASE(EEOP_PARAM_SET)
+ {
+ /* out of line, unlikely to matter performancewise */
+ ExecEvalParamSet(state, op, econtext);
+ EEO_NEXT();
+ }
+
EEO_CASE(EEOP_CASE_TESTVAL)
{
/*
@@ -2477,6 +2485,20 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
errmsg("no value found for parameter %d", paramId)));
}
+/*
+ * Set value of a param (currently always PARAM_EXEC) from
+ * state->res{value,null}.
+ */
+void
+ExecEvalParamSet(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
+{
+ ParamExecData *prm;
+
+ prm = &(econtext->ecxt_param_exec_vals[op->d.param.paramid]);
+ prm->value = state->resvalue;
+ prm->isnull = state->resnull;
+}
+
/*
* Raise error if a CURRENT OF expression is evaluated.
*
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 4d288bc8d41..f62bb28140f 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -393,6 +393,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
/*
* Initialize any initPlans present in this node. The planner put them in
* a separate list for us.
+ *
+ * The defining characteristic of initplans is that they don't have
+ * arguments, so we don't need to evaluate them (in contrast to
+ * ExecInitSubPlanExpr()).
*/
subps = NIL;
foreach(l, node->initPlan)
@@ -401,6 +405,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
SubPlanState *sstate;
Assert(IsA(subplan, SubPlan));
+ Assert(subplan->args == NIL);
sstate = ExecInitSubPlan(subplan, result);
subps = lappend(subps, sstate);
}
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index c136f75ac24..3458ac007cd 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -107,7 +107,7 @@ ExecHashSubPlan(SubPlanState *node,
TupleTableSlot *slot;
/* Shouldn't have any direct correlation Vars */
- if (subplan->parParam != NIL || node->args != NIL)
+ if (subplan->parParam != NIL || subplan->args != NIL)
elog(ERROR, "hashed subplan with direct correlation not supported");
/*
@@ -231,7 +231,6 @@ ExecScanSubPlan(SubPlanState *node,
TupleTableSlot *slot;
Datum result;
bool found = false; /* true if got at least one subplan tuple */
- ListCell *pvar;
ListCell *l;
ArrayBuildStateAny *astate = NULL;
@@ -248,26 +247,20 @@ ExecScanSubPlan(SubPlanState *node,
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
/*
- * Set Params of this plan from parent plan correlation values. (Any
- * calculation we have to do is done in the parent econtext, since the
- * Param values don't need to have per-query lifetime.)
+ * We rely on the caller to evaluate plan correlation values, if
+ * necessary. However we still need to record the fact that the values
+ * (might have) changed, otherwise the ExecReScan() below won't know that
+ * nodes need to be rescanned.
*/
- Assert(list_length(subplan->parParam) == list_length(node->args));
-
- forboth(l, subplan->parParam, pvar, node->args)
+ Assert(list_length(subplan->parParam) == list_length(subplan->args));
+ foreach(l, subplan->parParam)
{
int paramid = lfirst_int(l);
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
- prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
- econtext,
- &(prm->isnull));
planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
}
- /*
- * Now that we've set up its parameters, we can reset the subplan.
- */
+ /* with that done, we can reset the subplan */
ExecReScan(planstate);
/*
@@ -817,6 +810,10 @@ slotNoNulls(TupleTableSlot *slot)
* as well as regular SubPlans. Note that we don't link the SubPlan into
* the parent's subPlan list, because that shouldn't happen for InitPlans.
* Instead, ExecInitExpr() does that one part.
+ *
+ * We also rely on ExecInitExpr(), more precisely ExecInitSubPlanExpr(), to
+ * evaluate input parameters, as that allows them to be evaluated as part of
+ * the expression referencing the SubPlan.
* ----------------------------------------------------------------
*/
SubPlanState *
@@ -844,7 +841,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
/* Initialize subexpressions */
sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent);
- sstate->args = ExecInitExprList(subplan->args, parent);
/*
* initialize my state
@@ -1107,7 +1103,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
elog(ERROR, "ANY/ALL subselect unsupported as initplan");
if (subLinkType == CTE_SUBLINK)
elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan");
- if (subplan->parParam || node->args)
+ if (subplan->parParam || subplan->args)
elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan");
/*
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 1c722c79552..812f8758743 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -1094,6 +1094,12 @@ llvm_compile_expr(ExprState *state)
break;
}
+ case EEOP_PARAM_SET:
+ build_EvalXFunc(b, mod, "ExecEvalParamSet",
+ v_state, op, v_econtext);
+ LLVMBuildBr(b, opblocks[opno + 1]);
+ break;
+
case EEOP_SBSREF_SUBSCRIPTS:
{
int jumpdone = op->d.sbsref_subscript.jumpdone;
diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c
index 876fb640294..0b1df3afe00 100644
--- a/src/backend/jit/llvm/llvmjit_types.c
+++ b/src/backend/jit/llvm/llvmjit_types.c
@@ -123,6 +123,7 @@ void *referenced_functions[] =
ExecEvalNextValueExpr,
ExecEvalParamExec,
ExecEvalParamExtern,
+ ExecEvalParamSet,
ExecEvalRow,
ExecEvalRowNotNull,
ExecEvalRowNull,
--
2.37.1.188.g71a8fab31b
--2fo66m5ddj2bowyf--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/3] Remove unnecessary volatile qualifiers.
@ 2026-02-18 16:31 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-02-18 16:31 UTC (permalink / raw)
---
src/backend/replication/syncrep.c | 19 ++++++++-----------
src/backend/storage/ipc/procsignal.c | 4 ++--
src/backend/storage/lmgr/lock.c | 2 +-
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
5 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 7ea6001e9ad..045fd35786a 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -473,7 +473,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -548,19 +547,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -767,8 +766,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -905,7 +903,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -920,7 +917,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 5d33559926a..97791f979ef 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -283,7 +283,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -394,7 +394,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index e1168ad3837..718de1b5e98 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -309,7 +309,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
/*
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 579e5933d28..a1ec13d66b9 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -36,7 +36,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -256,7 +256,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index 368e4f3f234..14972f7e7cd 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -50,7 +50,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--J5cpktPts8HkLShw
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0002-Remove-SpinLockFree-and-S_LOCK_FREE.patch
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v43 4/7] Use BulkInsertState when copying data to the new heap.
@ 2026-03-11 14:20 Antonin Houska <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Antonin Houska @ 2026-03-11 14:20 UTC (permalink / raw)
It should make the copying more efficient. Besides that, buffer access
strategy is involved this way.
This diff reverts the changes done in previous parts of the series to
reform_and_rewrite_tuple() and introduces a separate function
heap_insert_for_repack().
---
src/backend/access/heap/heapam_handler.c | 110 +++++++++++++++--------
1 file changed, 72 insertions(+), 38 deletions(-)
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 618b831e8eb..065bb233fe2 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -50,6 +50,11 @@
static void reform_and_rewrite_tuple(HeapTuple tuple,
Relation OldHeap, Relation NewHeap,
Datum *values, bool *isnull, RewriteState rwstate);
+static void heap_insert_for_repack(HeapTuple tuple, Relation OldHeap,
+ Relation NewHeap, Datum *values, bool *isnull,
+ BulkInsertState bistate);
+static HeapTuple reform_tuple(HeapTuple tuple, Relation OldHeap,
+ Relation NewHeap, Datum *values, bool *isnull);
static bool SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
HeapTuple tuple,
@@ -702,6 +707,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
double *tups_recently_dead)
{
RewriteState rwstate = NULL;
+ BulkInsertState bistate = NULL;
IndexScanDesc indexScan;
TableScanDesc tableScan;
HeapScanDesc heapScan;
@@ -737,6 +743,8 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
if (!concurrent)
rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin,
*xid_cutoff, *multi_cutoff);
+ else
+ bistate = GetBulkInsertState();
/* Set up sorting if wanted */
@@ -966,8 +974,12 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
};
int64 ct_val[2];
- reform_and_rewrite_tuple(tuple, OldHeap, NewHeap,
- values, isnull, rwstate);
+ if (!concurrent)
+ reform_and_rewrite_tuple(tuple, OldHeap, NewHeap,
+ values, isnull, rwstate);
+ else
+ heap_insert_for_repack(tuple, OldHeap, NewHeap,
+ values, isnull, bistate);
/*
* In indexscan mode and also VACUUM FULL, report increase in
@@ -1015,10 +1027,15 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
break;
n_tuples += 1;
- reform_and_rewrite_tuple(tuple,
- OldHeap, NewHeap,
- values, isnull,
- rwstate);
+ if (!concurrent)
+ reform_and_rewrite_tuple(tuple,
+ OldHeap, NewHeap,
+ values, isnull,
+ rwstate);
+ else
+ heap_insert_for_repack(tuple, OldHeap, NewHeap,
+ values, isnull, bistate);
+
/* Report n_tuples */
pgstat_progress_update_param(PROGRESS_REPACK_HEAP_TUPLES_INSERTED,
n_tuples);
@@ -1030,6 +1047,8 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
/* Write out any remaining tuples, and fsync if needed */
if (rwstate)
end_heap_rewrite(rwstate);
+ if (bistate)
+ FreeBulkInsertState(bistate);
/* Clean up */
pfree(values);
@@ -2422,56 +2441,71 @@ heapam_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate,
* SET WITHOUT OIDS.
*
* So, we must reconstruct the tuple from component Datums.
- *
- * If rwstate=NULL, use simple_heap_insert() instead of rewriting - in that
- * case we still need to deform/form the tuple. TODO Shouldn't we rename the
- * function, as might not do any rewrite?
*/
static void
reform_and_rewrite_tuple(HeapTuple tuple,
Relation OldHeap, Relation NewHeap,
Datum *values, bool *isnull, RewriteState rwstate)
+{
+ HeapTuple copiedTuple;
+
+ copiedTuple = reform_tuple(tuple, OldHeap, NewHeap, values, isnull);
+
+ /* The heap rewrite module does the rest */
+ rewrite_heap_tuple(rwstate, tuple, copiedTuple);
+
+ heap_freetuple(copiedTuple);
+}
+
+/*
+ * Insert tuple when processing REPACK CONCURRENTLY.
+ *
+ * rewriteheap.c is not used in the CONCURRENTLY case because it'd be
+ * difficult to do the same in the catch-up phase (as the logical
+ * decoding does not provide us with sufficient visibility
+ * information). Thus we must use heap_insert() both during the
+ * catch-up and here.
+ *
+ * We pass the NO_LOGICAL flag to heap_insert() in order to skip logical
+ * decoding: as soon as REPACK CONCURRENTLY swaps the relation files, it drops
+ * this relation, so no logical replication subscription should need the data.
+ *
+ * BulkInsertState is used because many tuples are inserted in the typical
+ * case.
+ */
+static void
+heap_insert_for_repack(HeapTuple tuple, Relation OldHeap, Relation NewHeap,
+ Datum *values, bool *isnull, BulkInsertState bistate)
+{
+ tuple = reform_tuple(tuple, OldHeap, NewHeap, values, isnull);
+
+ heap_insert(NewHeap, tuple, GetCurrentCommandId(true),
+ HEAP_INSERT_NO_LOGICAL, bistate);
+
+ heap_freetuple(tuple);
+}
+
+/*
+ * Deform tuple, set values of dropped columns to NULL, form a new tuple and
+ * return it.
+ */
+static HeapTuple
+reform_tuple(HeapTuple tuple, Relation OldHeap, Relation NewHeap,
+ Datum *values, bool *isnull)
{
TupleDesc oldTupDesc = RelationGetDescr(OldHeap);
TupleDesc newTupDesc = RelationGetDescr(NewHeap);
- HeapTuple copiedTuple;
int i;
heap_deform_tuple(tuple, oldTupDesc, values, isnull);
- /* Be sure to null out any dropped columns */
for (i = 0; i < newTupDesc->natts; i++)
{
if (TupleDescCompactAttr(newTupDesc, i)->attisdropped)
isnull[i] = true;
}
- copiedTuple = heap_form_tuple(newTupDesc, values, isnull);
-
- if (rwstate)
- /* The heap rewrite module does the rest */
- rewrite_heap_tuple(rwstate, tuple, copiedTuple);
- else
- {
- /*
- * Insert tuple when processing REPACK CONCURRENTLY.
- *
- * rewriteheap.c is not used in the CONCURRENTLY case because it'd be
- * difficult to do the same in the catch-up phase (as the logical
- * decoding does not provide us with sufficient visibility
- * information). Thus we must use heap_insert() both during the
- * catch-up and here.
- *
- * The following is like simple_heap_insert() except that we pass the
- * flag to skip logical decoding: as soon as REPACK CONCURRENTLY swaps
- * the relation files, it drops this relation, so no logical
- * replication subscription should need the data.
- */
- heap_insert(NewHeap, copiedTuple, GetCurrentCommandId(true),
- HEAP_INSERT_NO_LOGICAL, NULL);
- }
-
- heap_freetuple(copiedTuple);
+ return heap_form_tuple(newTupDesc, values, isnull);
}
/*
--
2.47.3
--nzintiedl6o4kcyp
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment;
filename="v43-0005-Fix-crash-caused-by-involuntary-decoding-of-unre.patch"
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:41 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers to pg_atomic_* variables or local variables that hold a
value returned by a pg_atomic_* function. The pointer arguments
for the pg_atomic_* functions are volatile-qualified, so there's no
need to mark the pointer volatile. Likewise, a local variable that
just holds the result of a pg_atomic_* function gains nothing from
volatile.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
when they were modified inside a PG_TRY block and used afterward,
but the PG_TRY was later removed.
---
src/backend/access/transam/clog.c | 2 +-
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 10 ++++-----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 36 insertions(+), 43 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..47975ba892f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,7 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
+ PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..4acef19e563 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
{
uint64 local_gen;
uint64 shared_gen;
- volatile uint32 flags;
+ uint32 flags;
Assert(MyProcSignalSlot);
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--hE8tq9meMVMcgUcn--
^ permalink raw reply [nested|flat] 95+ messages in thread
* remove unnecessary volatile qualifiers
@ 2026-06-30 21:47 Nathan Bossart <[email protected]>
0 siblings, 1 reply; 95+ messages in thread
From: Nathan Bossart @ 2026-06-30 21:47 UTC (permalink / raw)
To: pgsql-hackers
I looked into some of these earlier [0], but ended up leaving them alone at
the time. Here is a new patch that removes all of the volatile markers in
the tree that seemed obviously unnecessary to me.
[0] https://postgr.es/m/aZX2oUcKf7IzHnnK%40nathan
--
nathan
^ permalink raw reply [nested|flat] 95+ messages in thread
* Re: remove unnecessary volatile qualifiers
@ 2026-07-06 11:58 Heikki Linnakangas <[email protected]>
parent: Nathan Bossart <[email protected]>
0 siblings, 1 reply; 95+ messages in thread
From: Heikki Linnakangas @ 2026-07-06 11:58 UTC (permalink / raw)
To: Nathan Bossart <[email protected]>; pgsql-hackers
On 01/07/2026 00:47, Nathan Bossart wrote:
> I looked into some of these earlier [0], but ended up leaving them alone at
> the time. Here is a new patch that removes all of the volatile markers in
> the tree that seemed obviously unnecessary to me.
Thanks!
> --- a/src/backend/access/transam/clog.c
> +++ b/src/backend/access/transam/clog.c
> @@ -450,7 +450,7 @@ static bool
> TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
> XLogRecPtr lsn, int64 pageno)
> {
> - volatile PROC_HDR *procglobal = ProcGlobal;
> + PROC_HDR *procglobal = ProcGlobal;
> PGPROC *proc = MyProc;
> uint32 nextidx;
> uint32 wakeidx;
You might want to get rid of the local variable altogether and just
refer to ProcGlobal directly..
> @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
> {
> uint64 local_gen;
> uint64 shared_gen;
> - volatile uint32 flags;
> + uint32 flags;
>
> Assert(MyProcSignalSlot);
>
Are you sure about this one? 'flags' is used in the PG_TRY/CATCH block
that follows. It is modified in the PG_TRY(), here:
>
> /*
> * To avoid an infinite loop, we must always unset the bit in
> * flags.
> */
> BARRIER_CLEAR_BIT(flags, type);
and read later in the PG_CATCH() block.
The rest looks OK to me.
- Heikki
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:24 UTC (permalink / raw)
This commit cleans up volatile qualifiers that fit the below
criteria:
* Accesses to shared memory protected by a spinlock or LWLock.
Before commit 0709b7ee72, callers had to use volatile when
accessing spinlock-protected shared memory. Since spinlock
acquire/release became compiler barriers, and because LWLocks
provide the same guarantee, that is no longer necessary. These
either predate that change or were cargo-culted from code that did.
* Pointers used only to find the address of a member. The volatile
qualifier only affects accesses made by dereferencing the pointer,
so it is unnecessary there.
* Accesses to struct members that are marked volatile in the struct
definition. There's no need to mark these pointers volatile,
either.
* Leftovers from removed PG_TRY blocks. These were marked volatile
to protect a value that is modified inside a PG_TRY block and used
afterward, but the PG_TRY has since been removed.
---
src/backend/access/transam/clog.c | 7 +++---
src/backend/catalog/index.c | 2 +-
src/backend/commands/async.c | 4 ++--
src/backend/replication/syncrep.c | 19 +++++++---------
src/backend/storage/ipc/procsignal.c | 8 +++----
src/backend/storage/ipc/shm_toc.c | 31 ++++++++++++---------------
src/backend/storage/lmgr/lock.c | 2 +-
src/backend/storage/lmgr/proc.c | 3 +--
src/test/modules/test_shm_mq/setup.c | 4 ++--
src/test/modules/test_shm_mq/worker.c | 2 +-
10 files changed, 37 insertions(+), 45 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 75012d4b8f0..6f7f6b86eb6 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -450,7 +450,6 @@ static bool
TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
XLogRecPtr lsn, int64 pageno)
{
- volatile PROC_HDR *procglobal = ProcGlobal;
PGPROC *proc = MyProc;
uint32 nextidx;
uint32 wakeidx;
@@ -493,7 +492,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* different from ours. If another group starts to update a page in the
* same bank as ours, they wait until we release the lock.
*/
- nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
+ nextidx = pg_atomic_read_u32(&ProcGlobal->clogGroupFirst);
while (true)
{
@@ -524,7 +523,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
- if (pg_atomic_compare_exchange_u32(&procglobal->clogGroupFirst,
+ if (pg_atomic_compare_exchange_u32(&ProcGlobal->clogGroupFirst,
&nextidx,
(uint32) MyProcNumber))
break;
@@ -576,7 +575,7 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
* At this point, any processes trying to do this would create a separate
* group.
*/
- nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
+ nextidx = pg_atomic_exchange_u32(&ProcGlobal->clogGroupFirst,
INVALID_PROC_NUMBER);
/* Remember head of list so we can perform wakeups after dropping lock. */
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..81bba4beac7 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3637,7 +3637,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
int save_sec_context;
int save_nestlevel;
IndexInfo *indexInfo;
- volatile bool skipped_constraint = false;
+ bool skipped_constraint = false;
PGRUsage ru0;
bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
bool set_tablespace = false;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index eee8bc29f38..2799f989b96 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -605,7 +605,7 @@ static void CleanupListenersOnExit(void);
static bool IsListeningOn(const char *channel);
static void asyncQueueUnregister(void);
static bool asyncQueueIsFull(void);
-static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
+static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
static double asyncQueueUsage(void);
@@ -1968,7 +1968,7 @@ asyncQueueIsFull(void)
* returns true, else false.
*/
static bool
-asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
+asyncQueueAdvance(QueuePosition *position, int entryLength)
{
int64 pageno = QUEUE_POS_PAGE(*position);
int offset = QUEUE_POS_OFFSET(*position);
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index e0e30579c59..d870f09e0a0 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -483,7 +483,6 @@ SyncRepInitConfig(void)
void
SyncRepReleaseWaiters(void)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
XLogRecPtr writePtr;
XLogRecPtr flushPtr;
XLogRecPtr applyPtr;
@@ -558,19 +557,19 @@ SyncRepReleaseWaiters(void)
* Set the lsn first so that when we wake backends they will release up to
* this location.
*/
- if (walsndctl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] < writePtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_WRITE] = writePtr;
numwrite = SyncRepWakeQueue(false, SYNC_REP_WAIT_WRITE);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] < flushPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_FLUSH] = flushPtr;
numflush = SyncRepWakeQueue(false, SYNC_REP_WAIT_FLUSH);
}
- if (walsndctl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
+ if (WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] < applyPtr)
{
- walsndctl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
+ WalSndCtl->lsn[SYNC_REP_WAIT_APPLY] = applyPtr;
numapply = SyncRepWakeQueue(false, SYNC_REP_WAIT_APPLY);
}
@@ -777,8 +776,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
n = 0;
for (i = 0; i < max_wal_senders; i++)
{
- volatile WalSnd *walsnd; /* Use volatile pointer to prevent code
- * rearrangement */
+ WalSnd *walsnd;
SyncRepStandbyData *stby;
WalSndState state; /* not included in SyncRepStandbyData */
@@ -915,7 +913,6 @@ SyncRepGetStandbyPriority(void)
static int
SyncRepWakeQueue(bool all, int mode)
{
- volatile WalSndCtlData *walsndctl = WalSndCtl;
int numprocs = 0;
dlist_mutable_iter iter;
@@ -930,7 +927,7 @@ SyncRepWakeQueue(bool all, int mode)
/*
* Assume the queue is ordered by LSN
*/
- if (!all && walsndctl->lsn[mode] < proc->waitLSN)
+ if (!all && WalSndCtl->lsn[mode] < proc->waitLSN)
return numprocs;
/*
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 1397f65f67b..21a77f98c1d 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -295,7 +295,7 @@ CleanupProcSignalState(int status, Datum arg)
int
SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
{
- volatile ProcSignalSlot *slot;
+ ProcSignalSlot *slot;
if (procNumber != INVALID_PROC_NUMBER)
{
@@ -380,7 +380,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = 0; i < NumProcSignalSlots; i++)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pg_atomic_fetch_or_u32(&slot->pss_barrierCheckMask, flagbit);
}
@@ -406,7 +406,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
*/
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
- volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
+ ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = pg_atomic_read_u32(&slot->pss_pid);
if (pid != 0)
@@ -670,7 +670,7 @@ ResetProcSignalBarrierBits(uint32 flags)
static bool
CheckProcSignal(ProcSignalReason reason)
{
- volatile ProcSignalSlot *slot = MyProcSignalSlot;
+ ProcSignalSlot *slot = MyProcSignalSlot;
if (slot != NULL)
{
diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c
index 2f9fbb0a519..2217d48c3d9 100644
--- a/src/backend/storage/ipc/shm_toc.c
+++ b/src/backend/storage/ipc/shm_toc.c
@@ -87,7 +87,6 @@ shm_toc_attach(uint64 magic, void *address)
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -103,9 +102,9 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
+ allocated_bytes;
@@ -117,7 +116,7 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
}
- vtoc->toc_allocated_bytes += nbytes;
+ toc->toc_allocated_bytes += nbytes;
SpinLockRelease(&toc->toc_mutex);
@@ -130,16 +129,15 @@ shm_toc_allocate(shm_toc *toc, Size nbytes)
Size
shm_toc_freespace(shm_toc *toc)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
Size toc_bytes;
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
SpinLockRelease(&toc->toc_mutex);
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry);
@@ -170,7 +168,6 @@ shm_toc_freespace(shm_toc *toc)
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
{
- volatile shm_toc *vtoc = toc;
Size total_bytes;
Size allocated_bytes;
Size nentry;
@@ -183,14 +180,14 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
SpinLockAcquire(&toc->toc_mutex);
- total_bytes = vtoc->toc_total_bytes;
- allocated_bytes = vtoc->toc_allocated_bytes;
- nentry = vtoc->toc_nentry;
+ total_bytes = toc->toc_total_bytes;
+ allocated_bytes = toc->toc_allocated_bytes;
+ nentry = toc->toc_nentry;
#ifdef USE_ASSERT_CHECKING
/* Verify no duplicate keys */
for (Size i = 0; i < nentry; i++)
- Assert(vtoc->toc_entry[i].key != key);
+ Assert(toc->toc_entry[i].key != key);
#endif
toc_bytes = offsetof(shm_toc, toc_entry) + nentry * sizeof(shm_toc_entry)
@@ -208,8 +205,8 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
}
Assert(offset < total_bytes);
- vtoc->toc_entry[nentry].key = key;
- vtoc->toc_entry[nentry].offset = offset;
+ toc->toc_entry[nentry].key = key;
+ toc->toc_entry[nentry].offset = offset;
/*
* By placing a write barrier after filling in the entry and before
@@ -218,7 +215,7 @@ shm_toc_insert(shm_toc *toc, uint64 key, void *address)
*/
pg_write_barrier();
- vtoc->toc_nentry++;
+ toc->toc_nentry++;
SpinLockRelease(&toc->toc_mutex);
}
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 8d246ed5a4e..5ee80c7632e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -312,7 +312,7 @@ typedef struct
uint32 count[FAST_PATH_STRONG_LOCK_HASH_PARTITIONS];
} FastPathStrongRelationLockData;
-static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
+static FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 7d01c981a1f..87dd289f626 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -660,8 +660,7 @@ InitAuxiliaryProcess(void)
}
/* Mark auxiliary proc as in use by me */
- /* use volatile pointer to prevent code rearrangement */
- ((volatile PGPROC *) auxproc)->pid = MyProcPid;
+ auxproc->pid = MyProcPid;
SpinLockRelease(&ProcGlobal->freeProcsLock);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 4f40a61e3d9..991fe27a7fa 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -38,7 +38,7 @@ static worker_state *setup_background_workers(int nworkers,
dsm_segment *seg);
static void cleanup_background_workers(dsm_segment *seg, Datum arg);
static void wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr);
+ test_shm_mq_header *hdr);
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
@@ -258,7 +258,7 @@ cleanup_background_workers(dsm_segment *seg, Datum arg)
static void
wait_for_workers_to_become_ready(worker_state *wstate,
- volatile test_shm_mq_header *hdr)
+ test_shm_mq_header *hdr)
{
bool result = false;
diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c
index e13c05ae5c7..0ba1cfcac47 100644
--- a/src/test/modules/test_shm_mq/worker.c
+++ b/src/test/modules/test_shm_mq/worker.c
@@ -52,7 +52,7 @@ test_shm_mq_main(Datum main_arg)
shm_toc *toc;
shm_mq_handle *inqh;
shm_mq_handle *outqh;
- volatile test_shm_mq_header *hdr;
+ test_shm_mq_header *hdr;
int myworkernumber;
PGPROC *registrant;
--
2.50.1 (Apple Git-155)
--z39t9WErpHrlykOW--
^ permalink raw reply [nested|flat] 95+ messages in thread
* Re: remove unnecessary volatile qualifiers
@ 2026-07-06 15:47 Nathan Bossart <[email protected]>
parent: Heikki Linnakangas <[email protected]>
0 siblings, 1 reply; 95+ messages in thread
From: Nathan Bossart @ 2026-07-06 15:47 UTC (permalink / raw)
To: Heikki Linnakangas <[email protected]>; +Cc: pgsql-hackers
On Mon, Jul 06, 2026 at 02:58:12PM +0300, Heikki Linnakangas wrote:
> On 01/07/2026 00:47, Nathan Bossart wrote:
>> I looked into some of these earlier [0], but ended up leaving them alone at
>> the time. Here is a new patch that removes all of the volatile markers in
>> the tree that seemed obviously unnecessary to me.
>
> Thanks!
Thanks for reviewing.
>> --- a/src/backend/access/transam/clog.c
>> +++ b/src/backend/access/transam/clog.c
>> @@ -450,7 +450,7 @@ static bool
>> TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status,
>> XLogRecPtr lsn, int64 pageno)
>> {
>> - volatile PROC_HDR *procglobal = ProcGlobal;
>> + PROC_HDR *procglobal = ProcGlobal;
>> PGPROC *proc = MyProc;
>> uint32 nextidx;
>> uint32 wakeidx;
>
> You might want to get rid of the local variable altogether and just refer to
> ProcGlobal directly..
Done.
>> @@ -512,7 +512,7 @@ ProcessProcSignalBarrier(void)
>> {
>> uint64 local_gen;
>> uint64 shared_gen;
>> - volatile uint32 flags;
>> + uint32 flags;
>> Assert(MyProcSignalSlot);
>
> Are you sure about this one? 'flags' is used in the PG_TRY/CATCH block that
> follows. It is modified in the PG_TRY(), here:
>
>>
>> /*
>> * To avoid an infinite loop, we must always unset the bit in
>> * flags.
>> */
>> BARRIER_CLEAR_BIT(flags, type);
>
> and read later in the PG_CATCH() block.
Whoops. You are right. I reverted this part.
--
nathan
^ permalink raw reply [nested|flat] 95+ messages in thread
* Re: remove unnecessary volatile qualifiers
@ 2026-07-07 16:03 Nathan Bossart <[email protected]>
parent: Nathan Bossart <[email protected]>
0 siblings, 0 replies; 95+ messages in thread
From: Nathan Bossart @ 2026-07-07 16:03 UTC (permalink / raw)
To: Heikki Linnakangas <[email protected]>; +Cc: pgsql-hackers
Committed.
--
nathan
^ permalink raw reply [nested|flat] 95+ messages in thread
end of thread, other threads:[~2026-07-07 16:03 UTC | newest]
Thread overview: 95+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2023-02-25 21:39 [PATCH v2] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState Andres Freund <[email protected]>
2023-02-25 21:39 [PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState Andres Freund <[email protected]>
2026-02-18 16:31 [PATCH v1 1/3] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-03-11 14:20 [PATCH v43 4/7] Use BulkInsertState when copying data to the new heap. Antonin Houska <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:41 [PATCH v1 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-06-30 21:47 remove unnecessary volatile qualifiers Nathan Bossart <[email protected]>
2026-07-06 11:58 ` Re: remove unnecessary volatile qualifiers Heikki Linnakangas <[email protected]>
2026-07-06 15:47 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]>
2026-07-07 16:03 ` Re: remove unnecessary volatile qualifiers Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
2026-07-06 15:24 [PATCH v2 1/1] Remove unnecessary volatile qualifiers. Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox