- Jun 05, 2013
-
-
Avi Kivity authored
In order to optimize the fast path of tracepoints, we need to patch the call sites to skip calling the slow path code completely. In turn, that requires that each call site be unique -- a separate function. In the current implementations, tracepoints with the same signature map to the same type. It would have been great to use the name as a discriminant (tracepoint<"sched_queue", thread*> trace_sched_queue(...);), but C++ does not support string literals as template arguments. We could do const char* trace_sched_queue_name = "sched_queue"; tracepoint<trace_sched_queue_name, thread*> trace_sched_queue(...); but that doubles the code for declaring a tracepoint. Add a unique ID instead (and code to verify it is unique).
-
- May 30, 2013
-
-
Nadav Har'El authored
Previously, we re-implemented "unsupported" file operations (e.g., chmod for a pipe on which fchmod makes no sense) several times - there was an implementation only for chmod in kern_descrip.c, used in sys_socket.c, and af_local.cc had its own. As we add more file descriptor type (e.g., create_epoll()) we'll have even more copies of these silly functions, so let's do it once in fs/unsupported.c - with the fs/unsupported.h header file. This also gives us a central place to document (and argue) whether an unimplemented ioctl() should return ENOTTY or EBADF (I think the former).
-
- May 27, 2013
-
-
Guy Zana authored
the debug() console function is taking a lock before it access the console driver, it does that by acquiring a mutex which may sleep. since we want to be able to debug (and abort) in contexts where it's not possible sleep, such as in page_fault, a lockless debug print method is introduced. previousely to this patch, any abort on page_fault would cause an "endless" recursive abort() loop which hanged the system in a peculiar state.
-
- May 26, 2013
-
-
Avi Kivity authored
This are used to support ifunc functions, which are resolved at load-time based on cpu features, rather than at link time.
-
- May 24, 2013
-
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
Christoph Hellwig authored
-
- May 23, 2013
-
-
Avi Kivity authored
-
Avi Kivity authored
If there's nothing in the cpu_set (which is fairly common), there's no need to use an atomic operation.
-
- May 22, 2013
-
-
Nadav Har'El authored
1. osv::poweroff(), which can turn off a physical machine or in our case tell QEMU to quit. The implementation uses ACPI, through the ACPICA library. 2. osv::hang(), which ceases all computation on all cores, but does not turn off the machine. This can be useful if we want QEMU to remain alive for debugging, for example. The two functions are defined in the new <osv/power.hh> header files, and follow the new API guidelines we discussed today: They are C++-only, and are in the "osv" namespace.
-
Nadav Har'El authored
Added a timeout parameter to semaphore::wait(), which defaults to no timeout. semaphore:wait() is now a boolean, just like trywait(), and likewise can return false when the semaphore has not actually been decremented but rather we had a timeout. Because we need the mutex again after the wait, I replaced the "with_lock" mechanism by the better-looking lock_guard and mutex parameter to wait_until.
-
Nadav Har'El authored
Leak detection (e.g., by running with "--leak") used to have a devastating effect on the performance of the checked program, which although was tolerable (for leak detection, long runs are often unnecessary), it was still annoying. While before this patch leak-detection runs were roughly 5 times slower than regular runs, after this patch they are only about 40% slower than a regular run! Read on for the details. The main reason for this slowness was a simplistic vector which was used to keep the records for currently living allocations. This vector was linearly searched both for free spots (to remember new allocations) and for specific addresses (to forget freed allocations). Because this list often grew to a hundred thousand of items, it became incredibly slow and slowed down the whole program. For example, getting a prompt from cli.jar happened in 2 seconds without leak detection, but in 9 seconds with leak detection. A possible solution would have been to use an O(1) data structure, such as a hash table. This would be complicated by our desire to avoid frequent memory allocation inside the leak detector, or our general desire to avoid complicated stuff in the leak detector because they always end leading to complicated deadlocks :-) This patch uses a different approach, inspired by an idea by Guy. It still uses an ordinary vector for holding the records, but additionally keeps for each record one "next" pointer which is used for maintaining two separate lists of records: 1. A list of free records. This allows a finding a record for a new allocation in O(1) time. 2. A list of filled records, starting with the most-recently-filled record. When we free(), we walk this list and very often finish very quickly, because malloc() closely followed by free() are very common. Without this list, we had to walk the whole vector filled with ancient allocations and even free records, just to find the most recent allocation. Two examples of the performance with and without this patch: 1. Getting a prompt from cli.jar takes 2 seconds without leak detection, 9 seconds with leak detection before this patch, and 3 seconds with this patch. 2. The "sunflow" benchmark runs 53 ops/second without leak detection, which went down to 10 ops/second with leak detection before this patch, and after this patch - 33 ops/second. I verified (by commenting out the search algorithm and always using the first item in the vector) that the allocation record search is no longer having any effect on performance, so it is no longer interesting to replace this code with an even more efficient hash table. The remaining slowdown is probably due to the backtrace() operation and perhaps also the tracker lock.
-
Avi Kivity authored
Intrusive lists are faster since they require no allocations.
-
Avi Kivity authored
Previously, the mutex was stored using a pointer to avoid overflowing glibc's sem_t. Now we no longer have this restriction, drop the indirection.
-
Avi Kivity authored
Use Nadav's idea of iterating over the list and selecting wait records that fit the available units.
-
Avi Kivity authored
No code changes.
-
- May 21, 2013
-
-
Nadav Har'El authored
As Avi suggested, add an option (turned on by default) to remember only the most recent function calls - instead of the most high-level function calls like I did until now - in an allocation's stack trace. In our project, where we often don't care about the top-level functions (various Java stuff), it is more useful.
-
- May 20, 2013
-
-
Avi Kivity authored
pthread_mutex_t has a 32-bit field, __kind, at offset 16. Non-standard static initializers set this field to a nonzero value, which can corrupt fields in our implementation. Rearrange field layout so we have a hole in that position. To keep the structure size small enough so that condvar will still fit in pthread_condvar_t, we need to change the size of the _depth field to 16 bits.
-
Avi Kivity authored
Instead of a subclass, make it a thread attribute. This simplifies usage and also allows detaching a thread after creation.
-
Avi Kivity authored
Detached threads are auto collected, so give users a chance to execute some cleanup function before dying.
-
Nadav Har'El authored
for the very deep calls in Java. Increase it. In the future, I should have an option to save only the deepest calls, not the calls nearest the root.
-
Nadav Har'El authored
mmu::allocate(), implementing mmap(), used to first evacuate the region (marking it free), then allocate a tiny vma object (a start,end pair), and finally populate the region. But it turns out that the allocation, if it calls backtrace() for the first time, ends up calling mmap() too :-) These two running mmap()s aren't protected by the mutex (it's the same thread), and the second mmap could take the region just freed by the first mmap - before returning to the first mmap who would reuse this region. We solve this bug by allocating the vma object before evacuating the region, so the other mmap picks different memory. Before this fix, "--leak tests/tst-mmap.so" crashes with assertion failure. With this fix, it succeeds.
-
Nadav Har'El authored
libunwind, which the next patches will use to implement a more reliable backtrace(), needs the msync() function. It doesn't need it to actually sync anything - just to recognize valid frame addresses (stacks are always mmap()ed). Note this implementation does the checking, but is missing the "sync" part of msync ;-) It doesn't matter because: 1. libunwind doesn't need (or want) this syncing, and neither does anything else in the Java stack (until now, msync() was never used). 2. We don't (yet?) have write-back of mmap'ed memory anyway, so there's no sense in doing any writing in msync either. We'll need to work on a full read-write implementation of file-backed mmap() later.
-
- May 18, 2013
-
-
Avi Kivity authored
include/glibc-compat defines headers that munge the musl headers (by including other headers or defining some symbols) and using #include_next. Eventually it should go away, but for now it reduces churn.
-
Avi Kivity authored
musl doesn't provide it.
-
Avi Kivity authored
-
Avi Kivity authored
With __musl's definition, the compile fails. It isn't justified anyway.
-
Avi Kivity authored
We got some from musl, remove it from our list.
-
Avi Kivity authored
Need to get __BEGIN_DECLS from somewhere.
-
Avi Kivity authored
SIOCSIFNAME (which is named after the BSD creator's daughter, incidentally).
-
Avi Kivity authored
Add missing symbols to make bsd happy.
-
Avi Kivity authored
Missing timezone type.
-
Avi Kivity authored
confused with bsd's
-
Avi Kivity authored
-