It turned out we used one version of kmalloc for malloc() and another for kfree()!
Now fixed.
Added parent-child relationship to tasks. Need to polish handling CLONE_PARENT and THREAD.
A new or forked thread will have its tgid same as its unique thread id.
A cloned thread (i.e. in the same space) will get its parent's tgid if
the parent tgid is supplied as the suggested tgid in the ids field. Otherwise
the thread will have its tgid same as its unique thread id.
Previously we also allocated a tgid from a separate pool, but this doesn't
make sense. It is cleaner to have the unique thread id get used also as the tgid.
l4_unmap now returns -1 if given range was only partially unmapped.
do_munmap() now only unmaps address ranges that have correspondence in
the unmapped vmas. Trying to unmap regions with no correspondent vmas
causes problems in corner cases, e.g. mm0 that tries to mmap its own
address space during initialisation would unmap its whole address space
and fail to execute.
sched_resume_async() used to forbit current tasks to wake up themselves
since it seems tasks can never be runnable to wake themselves up. However
there's a special case in the scheduler where a task that is about to sleep
may notice it has a pending event and wake itself up asynchronously. Since
all sleeping preparation has already been done and scheduler code is a safe
zone, it is safe to undo it all and resume about-to-sleep task in the scheduler.
We may want to put a BKPT in the pager's suspend routine if it waits for the
sleeping task to resume itself, to see if such a wait is successful. It rarely happens.
When sys_munmap() splits a vma, the new vma had no copy of the objects
in the original vma. Now we fixed that using a vma_copy_links() function
which can also be used as part of fork().
Still testing sys_munmap(). It now correctly spots and unmaps the overlapping vma.
The issue now is that if a split occurs, we forgot to add same objects to new vma.
File open was failing when using 2 files with same name. TODO: Look at it in the future.
Need to increase writeable file size in fs0. 16 pages don't work.
do_munmap currently shrinks, splits, destroys vmas and unmaps the given
virtual address range from the task. Unmapped pages may go completely unused
but page reclamation will be done in another part of the pager rather than
directly on the munmap instance.
- Fixed an important bug with shadow object handling.
When a shadow is dropped, if there are references left
to it, both the object in front and dropped object becomes
a shadow of the original object underneath. We had thought
of this case but had not increase the shadow count.
- Added a test mechanism that tests the number of objects,
vmfiles, shadows etc. by first counting them and trying to
reach the same number by other means, i.e. per-object-shadow counts.
It discovered a plethora of bugs.
- Added new set of functions to register objects, files and tasks
globally with the pager, these functions introduce a refcount as
well as adding structures to linked lists.
- fork/exit now seems to work stably i.e. no negative shadow counts etc.
- Scheduler was increasing total priorities only when resuming tasks had 0 ticks.
This caused forked tasks that have parent's share of ticks to finish their jobs,
if these tasks exited quick enough, they would cause the total priorities to deduce
without increasing it in the first place. This is now fixed.
- Also strengthened rq locking, now both queues are locked before touching any.
- Also removed task suspends in irq, this would cause a race condition on ticks and
runqueues, since neither is protected against irqs.
- Added cleaner allocation of shm addresses by moving the allocation to do_mmap().
- Added deletion routine for all objects: shadow, vm_file of type vfs_file, shm_file, etc.
- Need to make sure objects get deleted properly after exit().
- Currently we allow a single, unique virtual address for each shm segment.