atomic-tbl.sh 5.6 KB

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