Hey, I figured I'd post this patch because it seems to work and I've toasted another filesystem. Which means I'll have some more work to do to get a decent build environment up again.
I've only done limiting testing on this. That is, I mmaped a few pages, then mlocked them, the program did not return any errors. I tried to mmap a gig of anonymous memory and mlock return invalid argument, so I assume the mmap failed, thus causing mlock to fail. I then malloc'd a gig and tried to mlock it. This didn't freeze my system, but did cause a kernel panic after a minute or so. The error was something like panic: alloc pt zone exhausted", which I assume means the kernel was wiring the memory and ran out. I'm posting this here because I haven't had a chance to try the read loop. If the read loop works properly then we can probably only use it. Anyway, have fun. James A. Morrison 2003-03-25 James A Morrison <[EMAIL PROTECTED]> * mlock.c (mlock): Check the memory protections for the regions to be locked and ensure each page is in memory before it is wired by the kernel. Index: mlock.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/mach/hurd/mlock.c,v retrieving revision 1.2 diff -u -r1.2 mlock.c --- mlock.c 6 Jul 2001 04:55:57 -0000 1.2 +++ mlock.c 24 Mar 2003 00:44:41 -0000 @@ -1,5 +1,5 @@ /* mlock -- guarantee pages are resident in memory. Mach/Hurd version. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 03 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,17 +30,90 @@ mlock (const void *addr, size_t len) { mach_port_t hostpriv; - vm_address_t page; + vm_address_t page, working; error_t err; + size_t remaining, wiring, size; + boolean_t shared; + vm_prot_t cur_prot, max_prot; + mach_port_t obj_name; + vm_offset_t offset; + vm_inherit_t inherit; + volatile char *poke; + volatile char ch; + + static size_t touches = 1; err = __get_privileged_ports (&hostpriv, NULL); if (err) return __hurd_fail (EPERM); - page = trunc_page ((vm_address_t) addr); - len = round_page ((vm_address_t) addr + len) - page; - err = __vm_wire (hostpriv, __mach_task_self (), page, len, - VM_PROT_ALL); /* XXX ? */ + working = page = trunc_page ((vm_address_t) addr); + remaining = len = round_page ((vm_address_t) addr + len) - page; + + do + { + size_t do_touch; + err = __vm_region (__mach_task_self (), &page, &size, &cur_prot, + &max_prot, &inherit, &shared, &obj_name, &offset); + if (err) + goto err_state; + else if (page != working) + { + err = ENOMEM; + goto err_state; + } + + /* Prune size if it is larger than we need. */ + size = size > remaining ? remaining : size; + + for (working = page; working < (page + size); + working += (size_t)wiring) + { + do_touch = remaining / vm_page_size; + do_touch = do_touch > touches ? touches : do_touch; + wiring = do_touch * vm_page_size; + + /* write to the page if we can. */ + if (cur_prot & VM_PROT_WRITE) + for (poke = page; poke < working + wiring; poke += vm_page_size) + *poke = *poke; + else + for (poke = page; poke < working + wiring; poke += vm_page_size) + ch = *poke; + + /* Use the current protection because the programmer should have the + correct protections in place before trying to do anything. It + looks safer this way as well. */ + err = __vm_wire (hostpriv, __mach_task_self (), working, wiring, + cur_prot); + if (err) + goto err_state; + + remaining -= wiring; + } + + } + while (remaining); + +err_state: + if (err) + { + /* Assume the memory wasn't locked before, so we unlock it all to restore + the state it was in. */ + working = page; + remaining = len - remaining; + while (remaining) + { + err = __vm_region (__mach_task_self (), &working, &size, &cur_prot, + &max_prot, &inherit, &shared, &obj_name, &offset); + size = size > remaining ? remaining : size; + err = __vm_wire (hostpriv, __mach_task_self (), working, wiring, + VM_PROT_NONE); + + remaining -= size; + } + } + __mach_port_deallocate (__mach_task_self (), hostpriv); return err ? __hurd_fail (err) : 0; _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd