2004-10-07 Roland McGrath <roland@redhat.com>
* mem.c [LINUX] (sys_mbind, sys_set_mempolicy, sys_get_mempolicy):
New functions.
* linux/syscall.h: Declare them.
* linux/x86_64/syscallent.h: Likewise.
* linux/syscallent.h: Handle mbind, set_mempolicy, get_mempolicy.
From Ulrich Drepper <drepper@redhat.com>.
diff --git a/mem.c b/mem.c
index 885ce2d..7404ef2 100644
--- a/mem.c
+++ b/mem.c
@@ -657,4 +657,112 @@
}
return 0;
}
+
+
+#define MPOL_DEFAULT 0
+#define MPOL_PREFERRED 1
+#define MPOL_BIND 2
+#define MPOL_INTERLEAVE 3
+
+#define MPOL_F_NODE (1<<0)
+#define MPOL_F_ADDR (1<<1)
+
+#define MPOL_MF_STRICT (1<<0)
+
+
+static const struct xlat policies[] = {
+ { MPOL_DEFAULT, "MPOL_DEFAULT" },
+ { MPOL_PREFERRED, "MPOL_PREFERRED" },
+ { MPOL_BIND, "MPOL_BIND" },
+ { MPOL_INTERLEAVE, "MPOL_INTERLEAVE" },
+ { 0, NULL }
+};
+
+static const struct xlat mbindflags[] = {
+ { MPOL_MF_STRICT, "MPOL_MF_STRICT" },
+ { 0, NULL }
+};
+
+static const struct xlat mempolicyflags[] = {
+ { MPOL_F_NODE, "MPOL_F_NODE" },
+ { MPOL_F_ADDR, "MPOL_F_ADDR" },
+ { 0, NULL }
+};
+
+
+static void
+get_nodes(tcp, ptr, maxnodes, err)
+struct tcb *tcp;
+unsigned long ptr;
+unsigned long maxnodes;
+int err;
+{
+ int nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
+ if (err || !abbrev(tcp) || nlongs > getpagesize() / sizeof(long)
+ || nlongs == 0) {
+ long buf[nlongs];
+ if (umoven(tcp, ptr, nlongs * sizeof(long),
+ (char *) buf) < 0)
+ tprintf(", %lx", ptr);
+ else {
+ int i;
+ tprintf(", {");
+ for (i = 0; i < nlongs; ++i) {
+ if (i > 0)
+ tprintf(", ");
+ tprintf("%#0*lx", (int) sizeof(long) * 2 + 2,
+ buf[i]);
+ }
+ tprintf("}");
+ }
+ } else
+ tprintf(", %lx", ptr);
+ tprintf(", %lu", maxnodes);
+}
+
+int
+sys_mbind(tcp)
+struct tcb *tcp;
+{
+ if (entering(tcp)) {
+ tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
+ printxval(policies, tcp->u_arg[2], "MPOL_???");
+ get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0);
+ tprintf(", ");
+ if (printflags(mbindflags, tcp->u_arg[5]) == 0)
+ tprintf("0");
+ }
+ return 0;
+}
+
+int
+sys_set_mempolicy(tcp)
+struct tcb *tcp;
+{
+ if (entering(tcp)) {
+ printxval(policies, tcp->u_arg[0], "MPOL_???");
+ get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0);
+ }
+ return 0;
+}
+
+int
+sys_get_mempolicy(tcp)
+struct tcb *tcp;
+{
+ if (exiting(tcp)) {
+ int pol;
+ if (tcp->u_arg[0] == 0)
+ tprintf("NULL");
+ else if (syserror(tcp) || umove(tcp, tcp->u_arg[0], &pol) < 0)
+ tprintf("%#lx", tcp->u_arg[0]);
+ else
+ printxval(policies, pol, "MPOL_???");
+ get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp));
+ tprintf(", %#lx, ", tcp->u_arg[3]);
+ if (printflags(mempolicyflags, tcp->u_arg[4]) == 0)
+ tprintf("0");
+ }
+ return 0;
+}
#endif