agora inbox for [email protected]
help / color / mirror / Atom feed[PATCH v1] WIP: Evaluate arguments of correlated SubPlans in the referencing ExprState
377+ 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; 377+ 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] 377+ 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; 377+ 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] 377+ messages in thread
* [PATCH v1 1/3] Remove unnecessary volatile qualifiers.
@ 2026-02-18 16:31 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v21 2/3] Lock referenced objects before permission checks in DDL commands
@ 2026-04-27 14:19 Bertrand Drouvot <[email protected]>
0 siblings, 0 replies; 377+ messages in thread
From: Bertrand Drouvot @ 2026-04-27 14:19 UTC (permalink / raw)
Add LockNotPinnedObjectById() calls before object_aclcheck() at all caller
sites where a permission check on a referenced object occurs before the
dependency on that object is recorded. This converts permission check before
lock to lock before permission check. It closes the TOCTOU window that could
allow a REVOKE to succeed between the permission check and the dependency
recording.
Author: Bertrand Drouvot <[email protected]>
Reviewed-by:
Discussion: https://postgr.es/m/[email protected]
---
src/backend/catalog/dependency.c | 22 ++++++++++++++++++++++
src/backend/catalog/namespace.c | 1 +
src/backend/catalog/pg_aggregate.c | 5 +++++
src/backend/catalog/pg_cast.c | 1 +
src/backend/catalog/pg_operator.c | 2 ++
src/backend/commands/aggregatecmds.c | 2 ++
src/backend/commands/alter.c | 3 +++
src/backend/commands/collationcmds.c | 2 ++
src/backend/commands/conversioncmds.c | 3 +++
src/backend/commands/extension.c | 1 +
src/backend/commands/foreigncmds.c | 5 +++++
src/backend/commands/functioncmds.c | 11 +++++++++++
src/backend/commands/indexcmds.c | 2 ++
src/backend/commands/opclasscmds.c | 2 ++
src/backend/commands/operatorcmds.c | 8 ++++++++
src/backend/commands/statscmds.c | 1 +
src/backend/commands/subscriptioncmds.c | 4 ++++
src/backend/commands/tablecmds.c | 7 +++++++
src/backend/commands/trigger.c | 2 ++
src/backend/commands/tsearchcmds.c | 2 ++
src/backend/commands/typecmds.c | 9 +++++++++
src/include/catalog/dependency.h | 1 +
22 files changed, 96 insertions(+)
22.5% src/backend/catalog/
76.2% src/backend/commands/
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 7e26691393d..a41e6ee2175 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1678,6 +1678,24 @@ LockNotPinnedObject(const ObjectAddress *object)
}
}
+/*
+ * LockNotPinnedObjectById
+ *
+ * Lock the object if it is not pinned. This is a convenience wrapper
+ * for callers that need to lock a referenced object before a permission
+ * check, converting permission check before lock to lock before permission
+ * check.
+ */
+void
+LockNotPinnedObjectById(Oid classid, Oid objid)
+{
+ ObjectAddress object;
+
+ ObjectAddressSet(object, classid, objid);
+
+ LockNotPinnedObject(&object);
+}
+
/*
* recordDependencyOnExpr - find expression dependencies
*
@@ -1960,8 +1978,11 @@ find_expr_references_walker(Node *node,
objoid = DatumGetObjectId(con->constvalue);
if (SearchSysCacheExists1(PROCOID,
ObjectIdGetDatum(objoid)))
+ {
+ LockNotPinnedObjectById(ProcedureRelationId, objoid);
add_object_address(ProcedureRelationId, objoid, 0,
context->addrs);
+ }
break;
case REGOPEROID:
case REGOPERATOROID:
@@ -2057,6 +2078,7 @@ find_expr_references_walker(Node *node,
{
FuncExpr *funcexpr = (FuncExpr *) node;
+ LockNotPinnedObjectById(ProcedureRelationId, funcexpr->funcid);
add_object_address(ProcedureRelationId, funcexpr->funcid, 0,
context->addrs);
/* fall through to examine arguments */
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 56b87d878e8..7dec076e111 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3512,6 +3512,7 @@ LookupCreationNamespace(const char *nspname)
namespaceId = get_namespace_oid(nspname, false);
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 243b952b9cc..41b390e8d96 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -586,22 +586,26 @@ AggregateCreate(const char *aggName,
*/
for (i = 0; i < numArgs; i++)
{
+ LockNotPinnedObjectById(TypeRelationId, aggArgTypes[i]);
aclresult = object_aclcheck(TypeRelationId, aggArgTypes[i], GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggArgTypes[i]);
}
+ LockNotPinnedObjectById(TypeRelationId, aggTransType);
aclresult = object_aclcheck(TypeRelationId, aggTransType, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggTransType);
if (OidIsValid(aggmTransType))
{
+ LockNotPinnedObjectById(TypeRelationId, aggmTransType);
aclresult = object_aclcheck(TypeRelationId, aggmTransType, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, aggmTransType);
}
+ LockNotPinnedObjectById(TypeRelationId, finaltype);
aclresult = object_aclcheck(TypeRelationId, finaltype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, finaltype);
@@ -909,6 +913,7 @@ lookup_agg_function(List *fnName,
}
/* Check aggregate creator has permission to call the function */
+ LockNotPinnedObjectById(ProcedureRelationId, fnOid);
aclresult = object_aclcheck(ProcedureRelationId, fnOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(fnOid));
diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c
index 5119c2acda2..bb48e686f83 100644
--- a/src/backend/catalog/pg_cast.c
+++ b/src/backend/catalog/pg_cast.c
@@ -105,6 +105,7 @@ CastCreate(Oid sourcetypeid, Oid targettypeid,
/* dependency on function */
if (OidIsValid(funcid))
{
+ LockNotPinnedObjectById(ProcedureRelationId, funcid);
ObjectAddressSet(referenced, ProcedureRelationId, funcid);
add_exact_object_address(&referenced, addrs);
}
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 6b90c774c18..a222358d081 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -654,6 +654,7 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
/* not in catalogs, different from operator, so make shell */
+ LockNotPinnedObjectById(NamespaceRelationId, otherNamespace);
aclresult = object_aclcheck(NamespaceRelationId, otherNamespace, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -876,6 +877,7 @@ makeOperatorDependencies(HeapTuple tuple,
/* Dependency on namespace */
if (OidIsValid(oper->oprnamespace))
{
+ LockNotPinnedObjectById(NamespaceRelationId, oper->oprnamespace);
ObjectAddressSet(referenced, NamespaceRelationId, oper->oprnamespace);
add_exact_object_address(&referenced, addrs);
}
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 41b45dc6402..c2fb111daf3 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -22,6 +22,7 @@
*/
#include "postgres.h"
+#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_namespace.h"
@@ -101,6 +102,7 @@ DefineAggregate(ParseState *pstate,
aggNamespace = QualifiedNameGetCreationNamespace(name, &aggName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, aggNamespace);
aclresult = object_aclcheck(NamespaceRelationId, aggNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 74ceb5fe20d..03516cb0d2e 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -221,6 +221,7 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
/* User must have CREATE privilege on the namespace */
if (OidIsValid(namespaceId))
{
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -752,6 +753,7 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
NameStr(*(DatumGetName(name))));
/* User must have CREATE privilege on new namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, nspOid);
aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -1014,6 +1016,7 @@ AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
{
AclResult aclresult;
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, new_ownerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c
index 0bc31ec2b6f..fa5dad1aa1f 100644
--- a/src/backend/commands/collationcmds.c
+++ b/src/backend/commands/collationcmds.c
@@ -21,6 +21,7 @@
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
@@ -82,6 +83,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e
collNamespace = QualifiedNameGetCreationNamespace(names, &collName);
+ LockNotPinnedObjectById(NamespaceRelationId, collNamespace);
aclresult = object_aclcheck(NamespaceRelationId, collNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 5f2022d3072..d60ecdb711a 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -14,6 +14,7 @@
*/
#include "postgres.h"
+#include "catalog/dependency.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
@@ -50,6 +51,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
&conversion_name);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -97,6 +99,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
NameListToString(func_name), "integer")));
/* Check we have EXECUTE rights for the function */
+ LockNotPinnedObjectById(ProcedureRelationId, funcoid);
aclresult = object_aclcheck(ProcedureRelationId, funcoid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index a330b5fd6ce..4e82a010788 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -3283,6 +3283,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o
extensionName);
/* Permission check: must have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, nspOid);
aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA, newschema);
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index c4852be2eb2..dd31e260739 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -377,6 +377,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
check_can_set_role(GetUserId(), newOwnerId);
/* New owner must have USAGE privilege on foreign-data wrapper */
+ LockNotPinnedObjectById(ForeignDataWrapperRelationId, form->srvfdw);
aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
{
@@ -997,6 +998,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
*/
fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
+ LockNotPinnedObjectById(ForeignDataWrapperRelationId, fdw->fdwid);
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdw->fdwid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FDW, fdw->fdwname);
@@ -1188,6 +1190,7 @@ user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
{
AclResult aclresult;
+ LockNotPinnedObjectById(ForeignServerRelationId, serverid);
aclresult = object_aclcheck(ForeignServerRelationId, serverid, curuserid, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, servername);
@@ -1539,6 +1542,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
* get the actual FDW for option validation etc.
*/
server = GetForeignServerByName(stmt->servername, false);
+ LockNotPinnedObjectById(ForeignServerRelationId, server->serverid);
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, ownerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
@@ -1598,6 +1602,7 @@ ImportForeignSchema(ImportForeignSchemaStmt *stmt)
/* Check that the foreign server exists and that we have USAGE on it */
server = GetForeignServerByName(stmt->server_name, false);
+ LockNotPinnedObjectById(ForeignServerRelationId, server->serverid);
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3afd762e9dc..9aec534c390 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -146,6 +146,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
errdetail("Creating a shell type definition.")));
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
&typname);
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -158,6 +159,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
CommandCounterIncrement();
}
+ LockNotPinnedObjectById(TypeRelationId, rettype);
aclresult = object_aclcheck(TypeRelationId, rettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, rettype);
@@ -274,6 +276,7 @@ interpret_function_parameter_list(ParseState *pstate,
toid = InvalidOid; /* keep compiler quiet */
}
+ LockNotPinnedObjectById(TypeRelationId, toid);
aclresult = object_aclcheck(TypeRelationId, toid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, toid);
@@ -1071,6 +1074,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
&funcname);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -1125,6 +1129,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
if (languageStruct->lanpltrusted)
{
/* if trusted language, need USAGE privilege */
+ LockNotPinnedObjectById(LanguageRelationId, languageOid);
aclresult = object_aclcheck(LanguageRelationId, languageOid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE,
@@ -1582,10 +1587,12 @@ CreateCast(CreateCastStmt *stmt)
format_type_be(sourcetypeid),
format_type_be(targettypeid))));
+ LockNotPinnedObjectById(TypeRelationId, sourcetypeid);
aclresult = object_aclcheck(TypeRelationId, sourcetypeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, sourcetypeid);
+ LockNotPinnedObjectById(TypeRelationId, targettypeid);
aclresult = object_aclcheck(TypeRelationId, targettypeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, targettypeid);
@@ -1874,6 +1881,7 @@ CreateTransform(CreateTransformStmt *stmt)
if (!object_ownercheck(TypeRelationId, typeid, GetUserId()))
aclcheck_error_type(ACLCHECK_NOT_OWNER, typeid);
+ LockNotPinnedObjectById(TypeRelationId, typeid);
aclresult = object_aclcheck(TypeRelationId, typeid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeid);
@@ -1883,6 +1891,7 @@ CreateTransform(CreateTransformStmt *stmt)
*/
langid = get_language_oid(stmt->lang, false);
+ LockNotPinnedObjectById(LanguageRelationId, langid);
aclresult = object_aclcheck(LanguageRelationId, langid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_LANGUAGE, stmt->lang);
@@ -1897,6 +1906,7 @@ CreateTransform(CreateTransformStmt *stmt)
if (!object_ownercheck(ProcedureRelationId, fromsqlfuncid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->fromsql->objname));
+ LockNotPinnedObjectById(ProcedureRelationId, fromsqlfuncid);
aclresult = object_aclcheck(ProcedureRelationId, fromsqlfuncid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, NameListToString(stmt->fromsql->objname));
@@ -1923,6 +1933,7 @@ CreateTransform(CreateTransformStmt *stmt)
if (!object_ownercheck(ProcedureRelationId, tosqlfuncid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(stmt->tosql->objname));
+ LockNotPinnedObjectById(ProcedureRelationId, tosqlfuncid);
aclresult = object_aclcheck(ProcedureRelationId, tosqlfuncid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, NameListToString(stmt->tosql->objname));
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9ab74c8df0a..6216ab2a5f5 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -25,6 +25,7 @@
#include "access/tableam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
@@ -770,6 +771,7 @@ DefineIndex(ParseState *pstate,
{
AclResult aclresult;
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId, root_save_userid,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 7493a9ccc06..ad71ee53cb2 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -363,6 +363,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
&opcname);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceoid);
aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -801,6 +802,7 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
&opfname);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceoid);
aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 3e7b09b3494..bb2ce833bdd 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -33,6 +33,7 @@
#include "access/htup_details.h"
#include "access/table.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
@@ -92,6 +93,7 @@ DefineOperator(List *names, List *parameters)
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, oprNamespace);
aclresult = object_aclcheck(NamespaceRelationId, oprNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -189,6 +191,7 @@ DefineOperator(List *names, List *parameters)
if (typeName1)
{
+ LockNotPinnedObjectById(TypeRelationId, typeId1);
aclresult = object_aclcheck(TypeRelationId, typeId1, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeId1);
@@ -196,6 +199,7 @@ DefineOperator(List *names, List *parameters)
if (typeName2)
{
+ LockNotPinnedObjectById(TypeRelationId, typeId2);
aclresult = object_aclcheck(TypeRelationId, typeId2, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, typeId2);
@@ -227,12 +231,14 @@ DefineOperator(List *names, List *parameters)
* necessary, since EXECUTE will be checked at any attempted use of the
* operator, but it seems like a good idea anyway.
*/
+ LockNotPinnedObjectById(ProcedureRelationId, functionOid);
aclresult = object_aclcheck(ProcedureRelationId, functionOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
NameListToString(functionName));
rettype = get_func_rettype(functionOid);
+ LockNotPinnedObjectById(TypeRelationId, rettype);
aclresult = object_aclcheck(TypeRelationId, rettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, rettype);
@@ -312,6 +318,7 @@ ValidateRestrictionEstimator(List *restrictionName)
{
AclResult aclresult;
+ LockNotPinnedObjectById(ProcedureRelationId, restrictionOid);
aclresult = object_aclcheck(ProcedureRelationId, restrictionOid,
GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
@@ -382,6 +389,7 @@ ValidateJoinEstimator(List *joinName)
{
AclResult aclresult;
+ LockNotPinnedObjectById(ProcedureRelationId, joinOid);
aclresult = object_aclcheck(ProcedureRelationId, joinOid,
GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index b354723be44..6afef0f55c4 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -185,6 +185,7 @@ CreateStatistics(CreateStatsStmt *stmt, bool check_rights)
{
AclResult aclresult;
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceId);
aclresult = object_aclcheck(NamespaceRelationId, namespaceId,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 523959ba0ce..08dea4b67b3 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -745,6 +745,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
conninfo = NULL;
server = GetForeignServerByName(stmt->servername, false);
+ LockNotPinnedObjectById(ForeignServerRelationId, server->serverid);
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, owner, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
@@ -1833,6 +1834,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt,
* the server.
*/
new_server = GetForeignServerByName(stmt->servername, false);
+ LockNotPinnedObjectById(ForeignServerRelationId, new_server->serverid);
aclresult = object_aclcheck(ForeignServerRelationId,
new_server->serverid,
form->subowner, ACL_USAGE);
@@ -2262,6 +2264,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
ForeignServer *server;
server = GetForeignServer(form->subserver);
+ LockNotPinnedObjectById(ForeignServerRelationId, form->subserver);
aclresult = object_aclcheck(ForeignServerRelationId, form->subserver,
form->subowner, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
@@ -2606,6 +2609,7 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
{
ForeignServer *server = GetForeignServer(form->subserver);
+ LockNotPinnedObjectById(ForeignServerRelationId, server->serverid);
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, newOwnerId, ACL_USAGE);
if (aclresult != ACLCHECK_OK)
ereport(ERROR,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 92b0f38c353..d95ef23a53f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -30,6 +30,7 @@
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
@@ -997,6 +998,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
ofTypeId = typenameTypeId(NULL, stmt->ofTypename);
+ LockNotPinnedObjectById(TypeRelationId, ofTypeId);
aclresult = object_aclcheck(TypeRelationId, ofTypeId, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, ofTypeId);
@@ -1462,6 +1464,7 @@ BuildDescForRelation(const List *columns)
attname = entry->colname;
typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
+ LockNotPinnedObjectById(TypeRelationId, atttypid);
aclresult = object_aclcheck(TypeRelationId, atttypid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, atttypid);
@@ -13941,6 +13944,7 @@ checkFkeyPermissions(Relation rel, int16 *attnums, int natts)
int i;
/* Okay if we have relation-level REFERENCES permission */
+ LockNotPinnedObjectById(RelationRelationId, RelationGetRelid(rel));
aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid,
ACL_REFERENCES);
if (aclresult == ACLCHECK_OK)
@@ -14724,6 +14728,7 @@ ATPrepAlterColumnType(List **wqueue,
/* Look up the target type */
typenameTypeIdAndMod(pstate, typeName, &targettype, &targettypmod);
+ LockNotPinnedObjectById(TypeRelationId, targettype);
aclresult = object_aclcheck(TypeRelationId, targettype, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, targettype);
@@ -16476,6 +16481,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
check_can_set_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceOid);
aclresult = object_aclcheck(NamespaceRelationId, namespaceOid, newOwnerId,
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -19882,6 +19888,7 @@ RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid,
*/
if (IsA(stmt, RenameStmt))
{
+ LockNotPinnedObjectById(NamespaceRelationId, classform->relnamespace);
aclresult = object_aclcheck(NamespaceRelationId, classform->relnamespace,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index b87b4b40d07..3c5ca8fe7e3 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -350,6 +350,7 @@ CreateTriggerFiringOn(const CreateTrigStmt *stmt, const char *queryString,
if (OidIsValid(constrrelid))
{
+ LockNotPinnedObjectById(RelationRelationId, constrrelid);
aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
ACL_TRIGGER);
if (aclresult != ACLCHECK_OK)
@@ -695,6 +696,7 @@ CreateTriggerFiringOn(const CreateTrigStmt *stmt, const char *queryString,
funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
if (!isInternal)
{
+ LockNotPinnedObjectById(ProcedureRelationId, funcoid);
aclresult = object_aclcheck(ProcedureRelationId, funcoid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION,
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index a12ce33bae4..eb9e68bbb91 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -414,6 +414,7 @@ DefineTSDictionary(List *names, List *parameters)
namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceoid);
aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -917,6 +918,7 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, namespaceoid);
aclresult = object_aclcheck(NamespaceRelationId, namespaceoid, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index c4c3cdb5461..0e01dda90ba 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -39,6 +39,7 @@
#include "access/xact.h"
#include "catalog/binary_upgrade.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_am.h"
@@ -739,6 +740,7 @@ DefineDomain(ParseState *pstate, CreateDomainStmt *stmt)
&domainName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, domainNamespace);
aclresult = object_aclcheck(NamespaceRelationId, domainNamespace, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -788,6 +790,7 @@ DefineDomain(ParseState *pstate, CreateDomainStmt *stmt)
TypeNameToString(stmt->typeName)),
parser_errposition(pstate, stmt->typeName->location)));
+ LockNotPinnedObjectById(TypeRelationId, basetypeoid);
aclresult = object_aclcheck(TypeRelationId, basetypeoid, GetUserId(), ACL_USAGE);
if (aclresult != ACLCHECK_OK)
aclcheck_error_type(aclresult, basetypeoid);
@@ -1195,6 +1198,7 @@ DefineEnum(CreateEnumStmt *stmt)
&enumName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, enumNamespace);
aclresult = object_aclcheck(NamespaceRelationId, enumNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -1420,6 +1424,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
&typeName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, typeNamespace);
aclresult = object_aclcheck(NamespaceRelationId, typeNamespace, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
@@ -1496,6 +1501,7 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt)
&multirangeTypeName);
/* Check we have creation rights in target namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, multirangeNamespace);
aclresult = object_aclcheck(NamespaceRelationId, multirangeNamespace,
GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
@@ -2421,6 +2427,7 @@ findRangeCanonicalFunction(List *procname, Oid typeOid)
func_signature_string(procname, 1, NIL, argList))));
/* Also, range type's creator must have permission to call function */
+ LockNotPinnedObjectById(ProcedureRelationId, procOid);
aclresult = object_aclcheck(ProcedureRelationId, procOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(procOid));
@@ -2464,6 +2471,7 @@ findRangeSubtypeDiffFunction(List *procname, Oid subtype)
func_signature_string(procname, 2, NIL, argList))));
/* Also, range type's creator must have permission to call function */
+ LockNotPinnedObjectById(ProcedureRelationId, procOid);
aclresult = object_aclcheck(ProcedureRelationId, procOid, GetUserId(), ACL_EXECUTE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(procOid));
@@ -3963,6 +3971,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
check_can_set_role(GetUserId(), newOwnerId);
/* New owner must have CREATE privilege on namespace */
+ LockNotPinnedObjectById(NamespaceRelationId, typTup->typnamespace);
aclresult = object_aclcheck(NamespaceRelationId, typTup->typnamespace,
newOwnerId,
ACL_CREATE);
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index fa508ea70c6..ac1d902e912 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -102,6 +102,7 @@ typedef struct ObjectAddresses ObjectAddresses;
extern void AcquireDeletionLock(const ObjectAddress *object, int flags);
extern void LockNotPinnedObject(const ObjectAddress *object);
+extern void LockNotPinnedObjectById(Oid classid, Oid objid);
extern bool isObjectPinned(const ObjectAddress *object);
extern void ReleaseDeletionLock(const ObjectAddress *object);
--
2.34.1
--FjYZKkuBdH+F20sI
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment;
filename="v21-0003-Add-Assert-guard-to-detect-permission-check-befo.patch"
Content-Transfer-Encoding: 8bit
^ permalink raw reply [nested|flat] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v1 1/1] Remove unnecessary volatile qualifiers.
@ 2026-06-30 21:41 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* remove unnecessary volatile qualifiers
@ 2026-06-30 21:47 Nathan Bossart <[email protected]>
0 siblings, 1 reply; 377+ 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] 377+ 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; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ messages in thread
* [PATCH v2 1/1] Remove unnecessary volatile qualifiers.
@ 2026-07-06 15:24 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 377+ 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] 377+ 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; 377+ 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] 377+ 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; 377+ 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] 377+ messages in thread
end of thread, other threads:[~2026-07-07 16:03 UTC | newest]
Thread overview: 377+ 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-04-27 14:19 [PATCH v21 2/3] Lock referenced objects before permission checks in DDL commands Bertrand Drouvot <[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: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: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: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: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]>
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]>
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]>
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]>
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