imagereclaim would happily uncache pages from the mountcache (port/cache.c)
without ever getting a Image* released from it. simple fix, just check for
p->image->notext but make sure todo it under the page lock :)
the compiler optimizes setting unused variables out, which is
problematic if they are used in waserror() handler which the
compiler isnt aware of. rearrange the code to avoid this problem.
catch potential interrupt error from kproc(). this can happen when
we run out of processes, then newproc() will call rsrcwait()
which does tsleep(). if the process gets a note, this might
raise a interrupt error.
get a bit more verbose about process image exhaustion and make
imagreclaim() try to get at least one image on the freelist.
use rsrcwait() to notify the state, and call freebroken() in
case imagereclaim() couldnt free any images.
the variables elem and file0 and commited are explicitely
set to avoid that they get freed in ther waserror() handlers.
but it turns out the compiler optimizes this out as he
thinks the variables arent used any further. (the compiler
is not aware of the waserror() / longjmp() semantics).
rearrange the code to account for this. instead of using
a local variable to check for point of no return (commited),
we use up->seg[SSEG] to figure it out.
for file0 and elem, we just rearrange the code. elem can be
checked in the error handler if it was already assigned to
up->text, and file0 is just free()'d after the poperror().
remove silly busy loop in sysrendez. it is not needed.
dequeueproc() will make sure that the process has come to
rest.
we now always use the new FXSAVE format in FPsave structure and fpregs
file, converting back and forth in fpx87save() and fpx87restore().
document that fprestore() is a destructive operation now.
change fp register definition in libmach and adapt fpr() acid funciton.
avoid unneccesary copy of fpstate and fpsave in sysfork(). functions
including syscalls do not preserve the fp registers and copying fpstate
from the current process would mean we had to fpsave(&up->fpsave); first.
simply not doing it, new process starts in FPinit state.
If you run this:
{for (i in `{seq 1 70000}) echo '½•α·'} | mc | wc
mc will eventually suicide. The error comes from
/sys/src/libdraw/font.c:/^agefont which assumes it has a
display. Normally, this is set up by geninitdraw (usually
via initdraw), but mc.c avoids that to avoid the screen
redraws (flicker, at a minimum, but worse in long-running
cases).
graphics(2) does not prohibit this use, so I made the least
intrusive change to make it work.
the fpenv() instruction stores in x87 format, using mathstate()
would interpret fpsave as FPssestate in case it was enabled!
instead, pass the status word and fppc explicitely to mathnote()
in matherror().
get rid of m->fpsavealign buffer, as we can just use FPssesave struct
which has enougth padding so rounding up base pointer will not overflow.
use resrcwait() when waiting for memory to become available. randomize
the sleep time and properly restore old process status in case tsleep()
gets interrupted.
filesystems do not handle i/o errors well (cwfs will abandon the blocks),
and temporary exhaustion of kernel memory (because of too many i/o's in
parallel) causes read and write on the partition to fail.
i think it is better to wait for the memory to become available in
this case. the single allocation is at max SDmaxio bytes, which makes
it likely to become available. if we havnt even enought fo that, then
rebooting the machine would be the best option. (aux/reboot)