1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3# helpers for dealing with atomics.tbl 4 5#meta_in(meta, match) 6meta_in() 7{ 8 case "$1" in 9 [$2]) return 0;; 10 esac 11 12 return 1 13} 14 15#meta_has_ret(meta) 16meta_has_ret() 17{ 18 meta_in "$1" "bBiIfFlR" 19} 20 21#meta_has_acquire(meta) 22meta_has_acquire() 23{ 24 meta_in "$1" "BFIlR" 25} 26 27#meta_has_release(meta) 28meta_has_release() 29{ 30 meta_in "$1" "BFIRs" 31} 32 33#meta_has_relaxed(meta) 34meta_has_relaxed() 35{ 36 meta_in "$1" "BFIR" 37} 38 39#meta_is_implicitly_relaxed(meta) 40meta_is_implicitly_relaxed() 41{ 42 meta_in "$1" "vls" 43} 44 45#find_template(tmpltype, pfx, name, sfx, order) 46find_template() 47{ 48 local tmpltype="$1"; shift 49 local pfx="$1"; shift 50 local name="$1"; shift 51 local sfx="$1"; shift 52 local order="$1"; shift 53 54 local base="" 55 local file="" 56 57 # We may have fallbacks for a specific case (e.g. read_acquire()), or 58 # an entire class, e.g. *inc*(). 59 # 60 # Start at the most specific, and fall back to the most general. Once 61 # we find a specific fallback, don't bother looking for more. 62 for base in "${pfx}${name}${sfx}${order}" "${pfx}${name}${sfx}" "${name}"; do 63 file="${ATOMICDIR}/${tmpltype}/${base}" 64 65 if [ -f "${file}" ]; then 66 printf "${file}" 67 break 68 fi 69 done 70} 71 72#find_fallback_template(pfx, name, sfx, order) 73find_fallback_template() 74{ 75 find_template "fallbacks" "$@" 76} 77 78#find_kerneldoc_template(pfx, name, sfx, order) 79find_kerneldoc_template() 80{ 81 find_template "kerneldoc" "$@" 82} 83 84#gen_ret_type(meta, int) 85gen_ret_type() { 86 local meta="$1"; shift 87 local int="$1"; shift 88 89 case "${meta}" in 90 [sv]) printf "void";; 91 [bB]) printf "bool";; 92 [aiIfFlR]) printf "${int}";; 93 esac 94} 95 96#gen_ret_stmt(meta) 97gen_ret_stmt() 98{ 99 if meta_has_ret "${meta}"; then 100 printf "return "; 101 fi 102} 103 104# gen_param_name(arg) 105gen_param_name() 106{ 107 # strip off the leading 'c' for 'cv' 108 local name="${1#c}" 109 printf "${name#*:}" 110} 111 112# gen_param_type(arg, int, atomic) 113gen_param_type() 114{ 115 local type="${1%%:*}"; shift 116 local int="$1"; shift 117 local atomic="$1"; shift 118 119 case "${type}" in 120 i) type="${int} ";; 121 p) type="${int} *";; 122 v) type="${atomic}_t *";; 123 cv) type="const ${atomic}_t *";; 124 esac 125 126 printf "${type}" 127} 128 129#gen_param(arg, int, atomic) 130gen_param() 131{ 132 local arg="$1"; shift 133 local int="$1"; shift 134 local atomic="$1"; shift 135 local name="$(gen_param_name "${arg}")" 136 local type="$(gen_param_type "${arg}" "${int}" "${atomic}")" 137 138 printf "${type}${name}" 139} 140 141#gen_params(int, atomic, arg...) 142gen_params() 143{ 144 local int="$1"; shift 145 local atomic="$1"; shift 146 147 while [ "$#" -gt 0 ]; do 148 gen_param "$1" "${int}" "${atomic}" 149 [ "$#" -gt 1 ] && printf ", " 150 shift; 151 done 152} 153 154#gen_args(arg...) 155gen_args() 156{ 157 while [ "$#" -gt 0 ]; do 158 printf "$(gen_param_name "$1")" 159 [ "$#" -gt 1 ] && printf ", " 160 shift; 161 done 162} 163 164#gen_desc_return(meta) 165gen_desc_return() 166{ 167 local meta="$1"; shift 168 169 case "${meta}" in 170 [v]) 171 printf "Return: Nothing." 172 ;; 173 [Ff]) 174 printf "Return: The original value of @v." 175 ;; 176 [R]) 177 printf "Return: The updated value of @v." 178 ;; 179 [l]) 180 printf "Return: The value of @v." 181 ;; 182 esac 183} 184 185#gen_template_kerneldoc(template, class, meta, pfx, name, sfx, order, atomic, int, args...) 186gen_template_kerneldoc() 187{ 188 local template="$1"; shift 189 local class="$1"; shift 190 local meta="$1"; shift 191 local pfx="$1"; shift 192 local name="$1"; shift 193 local sfx="$1"; shift 194 local order="$1"; shift 195 local atomic="$1"; shift 196 local int="$1"; shift 197 198 local atomicname="${atomic}_${pfx}${name}${sfx}${order}" 199 200 local ret="$(gen_ret_type "${meta}" "${int}")" 201 local retstmt="$(gen_ret_stmt "${meta}")" 202 local params="$(gen_params "${int}" "${atomic}" "$@")" 203 local args="$(gen_args "$@")" 204 local desc_order="" 205 local desc_instrumentation="" 206 local desc_return="" 207 208 if [ ! -z "${order}" ]; then 209 desc_order="${order##_}" 210 elif meta_is_implicitly_relaxed "${meta}"; then 211 desc_order="relaxed" 212 else 213 desc_order="full" 214 fi 215 216 if [ -z "${class}" ]; then 217 desc_noinstr="Unsafe to use in noinstr code; use raw_${atomicname}() there." 218 else 219 desc_noinstr="Safe to use in noinstr code; prefer ${atomicname}() elsewhere." 220 fi 221 222 desc_return="$(gen_desc_return "${meta}")" 223 224 . ${template} 225} 226 227#gen_kerneldoc(class, meta, pfx, name, sfx, order, atomic, int, args...) 228gen_kerneldoc() 229{ 230 local class="$1"; shift 231 local meta="$1"; shift 232 local pfx="$1"; shift 233 local name="$1"; shift 234 local sfx="$1"; shift 235 local order="$1"; shift 236 237 local atomicname="${atomic}_${pfx}${name}${sfx}${order}" 238 239 local tmpl="$(find_kerneldoc_template "${pfx}" "${name}" "${sfx}" "${order}")" 240 if [ -z "${tmpl}" ]; then 241 printf "/*\n" 242 printf " * No kerneldoc available for ${class}${atomicname}\n" 243 printf " */\n" 244 else 245 gen_template_kerneldoc "${tmpl}" "${class}" "${meta}" "${pfx}" "${name}" "${sfx}" "${order}" "$@" 246 fi 247} 248 249#gen_proto_order_variants(meta, pfx, name, sfx, ...) 250gen_proto_order_variants() 251{ 252 local meta="$1"; shift 253 local pfx="$1"; shift 254 local name="$1"; shift 255 local sfx="$1"; shift 256 257 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@" 258 259 if meta_has_acquire "${meta}"; then 260 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@" 261 fi 262 if meta_has_release "${meta}"; then 263 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@" 264 fi 265 if meta_has_relaxed "${meta}"; then 266 gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@" 267 fi 268} 269 270#gen_proto_variants(meta, name, ...) 271gen_proto_variants() 272{ 273 local meta="$1"; shift 274 local name="$1"; shift 275 local pfx="" 276 local sfx="" 277 278 meta_in "${meta}" "fF" && pfx="fetch_" 279 meta_in "${meta}" "R" && sfx="_return" 280 281 gen_proto_order_variants "${meta}" "${pfx}" "${name}" "${sfx}" "$@" 282} 283 284#gen_proto(meta, ...) 285gen_proto() { 286 local meta="$1"; shift 287 for m in $(echo "${meta}" | grep -o .); do 288 gen_proto_variants "${m}" "$@" 289 done 290} 291