summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib9p/idl.gen80
-rw-r--r--lib9p/include/lib9p/9p.generated.h47
2 files changed, 102 insertions, 25 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index ead9bc5..bf0935c 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -224,7 +224,9 @@ class BufferSize:
exp_size: int # "expected" or max-reasonable size
max_size: int # really just here to sanity-check against typ.max_size(version)
max_copy: int
+ max_copy_extra: str
max_iov: int
+ max_iov_extra: str
_starts_with_copy: bool
_ends_with_copy: bool
@@ -233,7 +235,9 @@ class BufferSize:
self.exp_size = 0
self.max_size = 0
self.max_copy = 0
+ self.max_copy_extra = ""
self.max_iov = 0
+ self.max_iov_extra = ""
self._starts_with_copy = False
self._ends_with_copy = False
@@ -271,17 +275,36 @@ def get_buffer_size(typ: idl.Type, version: str) -> BufferSize:
sub = get_buffer_size(child.typ, version)
ret.exp_size += sub.exp_size * 16 # HEURISTIC: MAXWELEM
ret.max_size += sub.max_size * child.max_cnt
- ret.max_copy += sub.max_copy * child.max_cnt
- if sub.max_iov == 1 and sub._starts_with_copy: # is purely copy
- ret.max_iov += 1
- else: # contains zero-copy segments
- ret.max_iov += sub.max_iov * child.max_cnt
- if ret._ends_with_copy and sub._starts_with_copy:
- # we can merge this one
+ if child.name == "wname" and path.root.name in (
+ "Tsread",
+ "Tswrite",
+ ): # SPECIAL (9P2000.e)
+ assert ret._ends_with_copy
+ assert sub._starts_with_copy
+ assert not sub._ends_with_copy
+ ret.max_copy_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_copy})"
+ )
+ ret.max_iov_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_iov})"
+ )
ret.max_iov -= 1
- if sub._ends_with_copy and sub._starts_with_copy and sub.max_iov > 1:
- # we can merge these
- ret.max_iov -= child.max_cnt - 1
+ else:
+ ret.max_copy += sub.max_copy * child.max_cnt
+ if sub.max_iov == 1 and sub._starts_with_copy: # is purely copy
+ ret.max_iov += 1
+ else: # contains zero-copy segments
+ ret.max_iov += sub.max_iov * child.max_cnt
+ if ret._ends_with_copy and sub._starts_with_copy:
+ # we can merge this one
+ ret.max_iov -= 1
+ if (
+ sub._ends_with_copy
+ and sub._starts_with_copy
+ and sub.max_iov > 1
+ ):
+ # we can merge these
+ ret.max_iov -= child.max_cnt - 1
ret._ends_with_copy = sub._ends_with_copy
return WalkCmd.DONT_RECURSE
elif not isinstance(child.typ, idl.Struct):
@@ -332,6 +355,14 @@ def gen_h(versions: set[str], typs: list[idl.Type]) -> str:
ret += "\n"
ret += f"#ifndef {c_ver_ifdef({ver})}\n"
ret += f"\t#error config.h must define {c_ver_ifdef({ver})}\n"
+ if ver == "9P2000.e": # SPECIAL (9P2000.e)
+ ret += "#else\n"
+ ret += f"\t#if {c_ver_ifdef({ver})}\n"
+ ret += "\t\t#ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)\n"
+ ret += f"\t\t\t#error if {c_ver_ifdef({ver})} then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM\n"
+ ret += "\t\t#endif\n"
+ ret += "\t\tstatic_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);\n"
+ ret += "\t#endif\n"
ret += "#endif\n"
ret += f"""
@@ -404,7 +435,7 @@ enum {idprefix}version {{
ret += f"min_size = {sz.min_size:,} ; exp_size = {sz.exp_size:,} ; max_size = {sz.max_size:,}"
if sz.max_size > u32max:
ret += " (warning: >UINT32_MAX)"
- ret += f" ; max_iov = {sz.max_iov:,} ; max_copy = {sz.max_copy:,}"
+ ret += f" ; max_iov = {sz.max_iov:,}{sz.max_iov_extra} ; max_copy = {sz.max_copy:,}{sz.max_copy_extra}"
return ret
ret += per_version_comment(typ, sum_size)
@@ -478,6 +509,9 @@ enum {idprefix}version {{
ret += """
/* sizes **********************************************************************/
"""
+ ret += "\n"
+ ret += f"#define _{idprefix.upper()}MAX(a, b) ((a) > (b)) ? (a) : (b)\n"
+
tmsg_max_iov: dict[str, int] = {}
tmsg_max_copy: dict[str, int] = {}
rmsg_max_iov: dict[str, int] = {}
@@ -485,6 +519,8 @@ enum {idprefix}version {{
for typ in typs:
if not isinstance(typ, idl.Message):
continue
+ if typ.name in ("Tsread", "Tswrite"): # SPECIAL (9P2000.e)
+ continue
max_iov = tmsg_max_iov if typ.msgid % 2 == 0 else rmsg_max_iov
max_copy = tmsg_max_copy if typ.msgid % 2 == 0 else rmsg_max_copy
for version in typ.in_versions:
@@ -511,9 +547,29 @@ enum {idprefix}version {{
ret += "\n"
directive = "if"
+ seen_e = False # SPECIAL (9P2000.e)
for maxval in sorted(inv, reverse=True):
ret += f"#{directive} {c_ver_ifdef(inv[maxval])}\n"
- ret += f"\t#define {idprefix.upper()}{name.upper()} {maxval}\n"
+ indent = 1
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ typ = next(typ for typ in typs if typ.name == "Tswrite")
+ sz = get_buffer_size(typ, "9P2000.e")
+ match name:
+ case "tmsg_max_iov":
+ maxexpr = f"{sz.max_iov}{sz.max_iov_extra}"
+ case "tmsg_max_copy":
+ maxexpr = f"{sz.max_copy}{sz.max_copy_extra}"
+ case _:
+ assert False
+ ret += f"\t#if {c_ver_ifdef({"9P2000.e"})}\n"
+ ret += f"\t\t#define {idprefix.upper()}{name.upper()} _{idprefix.upper()}MAX({maxval}, {maxexpr})\n"
+ ret += f"\t#else\n"
+ indent += 1
+ ret += f"{'\t'*indent}#define {idprefix.upper()}{name.upper()} {maxval}\n"
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ ret += "\t#endif\n"
+ if "9P2000.e" in inv[maxval]:
+ seen_e = True
directive = "elif"
ret += "#endif\n"
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h
index e3f4d01..881d2e3 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/include/lib9p/9p.generated.h
@@ -20,6 +20,13 @@
#ifndef CONFIG_9P_ENABLE_9P2000_e
#error config.h must define CONFIG_9P_ENABLE_9P2000_e
+#else
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)
+ #error if CONFIG_9P_ENABLE_9P2000_e then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM
+ #endif
+ static_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);
+ #endif
#endif
#ifndef CONFIG_9P_ENABLE_9P2000_p9p
@@ -742,7 +749,7 @@ struct lib9p_msg_Tunlinkat {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
-/* min_size = 13 ; exp_size = 477 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) ; max_iov = 131,070 ; max_copy = 131,083 */
+/* min_size = 13 ; exp_size = 477 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) ; max_iov = 0 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 13 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
struct lib9p_msg_Tsread {
lib9p_tag_t tag;
uint32_t fid;
@@ -750,7 +757,7 @@ struct lib9p_msg_Tsread {
struct lib9p_s *wname;
};
-/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 131,072 ; max_copy = 131,087 */
+/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
struct lib9p_msg_Tswrite {
lib9p_tag_t tag;
uint32_t fid;
@@ -1066,20 +1073,34 @@ struct lib9p_msg_Twstat {
/* sizes **********************************************************************/
-#if CONFIG_9P_ENABLE_9P2000_e
- #define LIB9P_TMSG_MAX_IOV 131072
-#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
- #define LIB9P_TMSG_MAX_IOV 32
+#define _LIB9P_MAX(a, b) ((a) > (b)) ? (a) : (b)
+
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_IOV _LIB9P_MAX(32, 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_IOV 32
+ #endif
#endif
-#if CONFIG_9P_ENABLE_9P2000_e
- #define LIB9P_TMSG_MAX_COPY 131087
-#elif CONFIG_9P_ENABLE_9P2000_u
- #define LIB9P_TMSG_MAX_COPY 76
+#if CONFIG_9P_ENABLE_9P2000_u
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(76, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 76
+ #endif
#elif CONFIG_9P_ENABLE_9P2000_L
- #define LIB9P_TMSG_MAX_COPY 67
-#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_p9p
- #define LIB9P_TMSG_MAX_COPY 62
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(67, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 67
+ #endif
+#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(62, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 62
+ #endif
#endif
#if CONFIG_9P_ENABLE_9P2000_u