Skip to content
Snippets Groups Projects
  1. Jul 08, 2013
    • Guy Zana's avatar
      pcpu-worker: add a per cpu worker thread that can execute work items · 45e40421
      Guy Zana authored
      simply allows setting up and execution of a handler in the context of
      a specified CPU, the handler is defined staticly in compile time, and
      is invoked when the worker_item is signaled for a specied CPU.
      
      doesn't use locks to avoid unnecessary contention.
      
      needed for the per-cpu memory allocator, instead of creating additional
      n threads (per each cpu), the plan is to define and register a simple
      handler (lambda function).
      
      example of usage:
      
      void say_hello()
      {
          debug("Hello, world!");
      }
      
      // define hello_tester as a worker_item
      PCPU_WORKERITEM(hello_tester, [] { say_hello(); });
      
      .
      .
      .
      
      // anywhere in the code:
      hello_tester.signal(sched::cpus[1]);
      
      // will invoke say_hello() in the context of cpu 1
      
      Thanks to Avi for adding code that I was able to copy & paste :)
      45e40421
    • Guy Zana's avatar
      tests: test the spsc lockless ring · c00f2dc1
      Guy Zana authored
      2 threads are created on 2 different vcpus, one consumer and one producer.
      
      Both threads are pushing and popping concurrently 1,000,000,000 elements,
      the producer is pushing a random number between 0 and 7 and consumer pops
      those numbers. Both of the threads keeps track on the values they
      pushed/popped. per each value, the number of pushed elements
      should be equal to the number of popped elements.
      
       - ring_spsc: 14.8 Mop/s per core
      c00f2dc1
    • Guy Zana's avatar
      lockless: spsc ring buffer of fixed size · 120a19d9
      Guy Zana authored
      single-producer / single-consumer lockless ring buffer of fixed size.
      
          1. _begin points to the head of the ring, _end points to the tail.
             both advance forward, adding items (_end++), consuming items (_begin++)
      
          2. all indexes of the ring are running, so the condition for empty ring is
             different than full ring.
                  *) Empty -> (_begin == _end)
                  *) Full -> (_end - _begin = MaxSize)
      
          3. uses only store and load operations, no rmw.
      120a19d9
    • Guy Zana's avatar
      arch: add CACHELINE_ALIGNED macro · 2f6cf02f
      Guy Zana authored
      2f6cf02f
  2. Jul 04, 2013
    • Nadav Har'El's avatar
      Fix misalignment bug in lock-free mutex_t · 506c4642
      Nadav Har'El authored
      Because the lockfree::mutex type is heavy in C++, in C it was just a
      char[40], with static assertions verifying that this 40 is indeed the
      correct size.
      
      But this wasn't quite correct - if a mutex is contained in another
      structure, the char[40] can come anywhere, while the lockfree::mutex
      C++ type starts with a pointer, so the compiler adds padding to
      ensure 8-byte alignment of this pointer. So we had a serious bug
      when C and C++ code which used the same structure containing a
      mutex. For example, struct ifqueue from if_var.h. Each language
      thought the mutex was positioned in a different place inside this
      structure, causing attempts to access the same mutex at different
      addresses (offset by 4 bytes).
      
      Now, instead of a char[40], the C mutex will be a union, of
      char[40] (to achieve the desired size), and a void* (to
      achieve the desired alignment). Static assertions verify that
      this indeed results in the same alignment and the same size
      as that of the C++ object.
      506c4642
    • Nadav Har'El's avatar
      Trivial: used relaxed memory ordering in lockfree::mutex::owned() · 40afd5b5
      Nadav Har'El authored
      No reason to do anything but relaxed memory ordering here.
      We aren't touching any other memory in this function, and owned()
      isn't expected to synchronize access to any memory.
      40afd5b5
    • Dor Laor's avatar
      Trivial: get rid of sglist entirely · 18beb1b6
      Dor Laor authored
      18beb1b6
    • Dor Laor's avatar
      Sglist virtio usage refactore · ddef97f6
      Dor Laor authored
      Use a single instance per queue vector of sglist data.
      Before this patch sglist was implemented as a std::list
      which caused it to allocate heap memory and travel through pointers.
      Now we use a single vector per queue to temoprary keep the
      buffer data between the upper virtio layer and the lower one.
      ddef97f6
    • Dor Laor's avatar
      481f4ebd
    • Nadav Har'El's avatar
      Fix typo bug in lockfree::mutex::try_lock() · a90a024a
      Nadav Har'El authored
      From the "how could I have not seen this before" department, we bring you
      the following bug:
      
      try_lock() as a last attempt tries to get a handoff from a concurrent
      unlock() to take the lock for itself. Obviously, it should only do so
      if the "handoff" variable is set (non-zero). The typo was that we checked
      !handoff instead of handoff, so we took a non-existant handoff and
      possibly got the lock while someone else was still holding it.
      
      This bug is especially visible in Java, which uses try_lock() a lot
      in its monitor implementation (it spins with try_lock() and only
      uses lock() after giving up the spinning) - but wasn't visible in
      my tst-mutex.cc which didn't test try_lock().
      a90a024a
    • Nadav Har'El's avatar
      Add assertions to lockfree::mutex::unlock() · 3432dc6e
      Nadav Har'El authored
      assert() that unlock() is only done on a mutex locked by this thread.
      This helped catch a couple of nasty lockfree-mutex bugs (see next
      patches), so I think it's good to have such a check, at least for
      now.
      
      I previously avoided this assertion thinking it will significantly
      impact performance, but it seems it doesn't have a big impact (at
      least in benchmarks I tried). In the future we should perhaps have
      a mechanism to disable assertions (or some of them) in release
      builds.
      3432dc6e
    • Nadav Har'El's avatar
      Add sigignore() function · 7b91c1e9
      Nadav Har'El authored
      Add the simple sigignore() function. It's obsolete (it's from the System V
      days..) but memcached uses it if it exists (and it does exist on Linux).
      7b91c1e9
    • Glauber Costa's avatar
      bsd: xenbus original files · d7af1416
      Glauber Costa authored
      d7af1416
    • Glauber Costa's avatar
      bsd: original gnttab file · df37a640
      Glauber Costa authored
      Included separately so we can easily diff for our changes
      df37a640
    • Glauber Costa's avatar
      bsd: xenstore file · 1a67d927
      Glauber Costa authored
      This is the unmodified BSD xenstore file. I am including it separately
      so we can easily diff our modifications.
      1a67d927
  3. Jul 03, 2013
  4. Jul 02, 2013
  5. Jul 01, 2013
    • Avi Kivity's avatar
      Merge branch 'sched2' · ef155e5a
      Avi Kivity authored
      Timer-based thread preemption.
      ef155e5a
    • Avi Kivity's avatar
      sched: reduce over-eager timer rearming · 0a2cc13e
      Avi Kivity authored
      If a thread schedules out before its time slice expires (due to blocking)
      and is then made runnable and scheduled back in again, the scheduler will
      update the preemption timer, first cancelling it (or possibly setting it
      for another thread), then re-setting it for the original thread.  Usually
      the new expiration time will be later than the original.
      
      For a context switch intensive load, this causes a lot of timer re-arms,
      which are fairly slow.
      
      Reduce the amount of re-arms by remembering the last expiration time we set.
      If the new expiration time comes after that time, don't bother rearming the
      timer.  Instead, the expiration of the already-set timer will recalculate
      the expiration time and set a new expiration time.
      
      This reduces timer arming greatly, and speeds up context switches back to
      their performance before the preemption patches.
      0a2cc13e
    • Avi Kivity's avatar
      sched: initialize borrow · 3b7ede7d
      Avi Kivity authored
      It will be reset during a future context switch, but best to start with a
      clean slate.
      3b7ede7d
    • Avi Kivity's avatar
      sched: initialize idle thread vruntime · a56b258e
      Avi Kivity authored
      Make sure it starts out high so we don't see needless context switches on
      startup.
      a56b258e
    • Avi Kivity's avatar
      56c55def
    • Avi Kivity's avatar
      sched: preemption timer · 0d1606ce
      Avi Kivity authored
      When switching to a new thread, or when a new thread is queued, calculate
      the vruntime difference to set a timer for the point in time when we need to
      context switch again.
      
      This change makes tst-fpu.so threads run completely in parallel.
      0d1606ce
    • Nadav Har'El's avatar
      ELF: Allow using prelinked libraries · 4723a592
      Nadav Har'El authored
      This patch allows to use shared libraries copied from Linux, even if
      they already underwent "prelink" modifications.
      
      Without this patch, if the prelinked library used one of our library
      functions (e.g., malloc()), its address would not be correctly
      calculated, and the call will be made to a random address, and crash.
      
      A few details about the problem and the fix:
      
      When using a function from a shared library, calls go to a ".plt"
      function, which, to make a long story short, jumps to a address written
      in the ".plt.got" entry for this function.
      
      Normally, and this is what the existing code expected, the .plt.got entry
      is initialized to point to the second instruction in the .plt function
      (after the jump), which calls the linker to look up the function.
      This allows lazy symbol lookup, but after the lookup, the next calls
      to the PLT function will jump to the right function address immediately.
      
      But prelinking changes that - the prelinker looks up the symbols once
      and fills the .plt.got with the addresses it assigned to the functions
      in the other library. These addresses do not make any sense in the
      context of OSV (or any other system besides the one that the prelinker
      ran on), so we cannot use them, and instead need to overwrite them
      again with links to the .plt functions.
      4723a592
    • Avi Kivity's avatar
      sched: adjust timer expiration when the clock is not running · 6085ca37
      Avi Kivity authored
      Change the condition for expiration to allow an exact match between the
      current time and the timer expiration time.
      
      This helps the scheduler keep going when the clock is still not running
      during system startup.  Ideally we shouldn't depend on such details, but
      fixing this is too complicated for now.
      6085ca37
    • Avi Kivity's avatar
      sched: stop vruntime overflow in idle thread · 5c96e31c
      Avi Kivity authored
      We set the idle thread's vruntime at the maximum possible, to ensure it
      has the lowest priority, but this can cause an overflow when we add the
      idle thread's running time.
      
      Detect the overflow and prevent it.
      5c96e31c
Loading