1. 23 Feb, 2022 1 commit
  2. 06 Dec, 2020 2 commits
  3. 08 Oct, 2020 1 commit
    • Improve the support of atomics · cc1d7f5c
      This change:
      
      * Starts using GCC's and clang's `__atomic_*` intrinsics instead of the
        `__sync_*` ones, since the former supercede the latter (and can be
        safely replaced by their equivalent `__atomic_*` version with the
        sequentially consistent model).
      * Makes `git_atomic64`'s value `volatile`. Otherwise, this will make
        ThreadSanitizer complain.
      * Adds ways to load the values from atomics. As it turns out,
        unsynchronized read are okay only in some architectures, but if we
        want to be correct (and make ThreadSanitizer happy), those loads
        should also be performed with the atomic builtins.
      * Fixes two ThreadSanitizer warnings, as a proof-of-concept that this
        works:
        - Avoid directly accessing `git_refcount`'s `owner` directly, and
          instead makes all callers go through the `GIT_REFCOUNT_*()` macros,
          which also use the atomic utilities.
        - Makes `pool_system_page_size()` race-free.
      
      Part of: #5592
      lhchavez committed
  4. 08 Jun, 2020 1 commit
  5. 07 Feb, 2020 1 commit
    • cache: fix invalid memory access in case updating cache entry fails · 7d1b1774
      When adding a new entry to our cache where an entry with the same OID
      exists already, then we only update the existing entry in case it is
      unparsed and the new entry is parsed. Currently, we do not check the
      return value of `git_oidmap_set` though when updating the existing
      entry. As a result, we will _not_ have updated the existing entry if
      `git_oidmap_set` fails, but have decremented its refcount and
      incremented the new entry's refcount. Later on, this may likely lead to
      dereferencing invalid memory.
      
      Fix the issue by checking the return value of `git_oidmap_set`. In case
      it fails, we will simply keep the existing stored instead, even though
      it's unparsed.
      Patrick Steinhardt committed
  6. 17 Jul, 2019 1 commit
    • cache: evict items more efficiently · 770b91b1
      When our object cache is full, we pick eight items (or the whole cache,
      if there are fewer) and evict them. For small cache sizes, this is fine,
      but when we're dealing with a large number of objects, we can repeatedly
      exhaust the cache and spend a large amount of time in git_oidmap_iterate
      trying to find items to evict.
      
      Instead, let's assume that if the cache gets full, we have a large
      number of objects that we're handling, and be more aggressive about
      evicting items. Let's remove one item for every 2048 items, but not less
      than 8. This causes us to scale our evictions in proportion to the size
      of the cache and significantly reduces the time we spend in
      git_oidmap_iterate.
      
      Before this change, a full pack of all the non-blob objects in the Linux
      repository took in excess of 30 minutes and spent 62.3% of total runtime
      in odb_read_1 and its children, and 44.3% of the time in
      git_oidmap_iterate. With this change, the same operation now takes 14
      minutes and 44 seconds, and odb_read_1 accounts for only 35.9% of total
      time, whereas git_oidmap_iterate consists of 6.2%.
      
      Note that we do spend a little more time inflating objects and a decent
      amount more time in memcmp. However, overall, the time taken is
      significantly improved, and time in pack building is now dominated by
      git_delta_create_from_index (33.7%), which is what we would expect.
      brian m. carlson committed
  7. 24 May, 2019 1 commit
    • cache: fix cache eviction using deallocated key · add17435
      When evicting cache entries, we first retrieve the object that is
      to be evicted, delete the object and then finally delete the key
      from the cache. In case where the cache eviction caused us to
      free the cached object, though, its key will point to invalid
      memory now when trying to remove it from the cache map. On my
      system, this causes us to not properly remove the key from the
      map, as its memory has been overwritten already and thus the key
      lookup it will fail and we cannot delete it.
      
      Fix this by only decrementing the refcount of the evictee after
      we have removed it from our cache map. Add a test that caused a
      segfault previous to that change.
      Patrick Steinhardt committed
  8. 21 Feb, 2019 1 commit
    • cache: fix misnaming of `git_cache_free` · bbdcd450
      Functions that free a structure's contents but not the structure
      itself shall be named `dispose` in the libgit2 project, but the
      function `git_cache_free` does not follow this naming pattern.
      
      Fix this by renaming it to `git_cache_dispose` and adjusting all
      callers to make use of the new name.
      Patrick Steinhardt committed
  9. 15 Feb, 2019 4 commits
    • cache: use iteration interface for cache eviction · 6a9117f5
      To relieve us from memory pressure, we may regularly call `cache_evict_entries`
      to remove some entries from it. Unfortunately, our cache does not support a
      least-recently-used mode or something similar, which is why we evict entries
      completeley at random right now. Thing is, this is only possible due to the map
      interfaces exposing the entry indices, and we intend to completely remove those
      to decouple map users from map implementations. As soon as that is done, we are
      unable to do this random eviction anymore.
      
      Convert this to make use of an iterator for now. Obviously, there is no random
      eviction possible like that anymore, but we'll always start by evicting from the
      beginning of the map. Due to hashing, one may hope that the selected buckets
      will be evicted at least in some way unpredictably. But more likely than not,
      this will not be the case. But let's see what happens and if any users complain
      about degraded performance. If so, we might come up with a different scheme than
      random removal, e.g. by using an LRU cache.
      Patrick Steinhardt committed
    • oidmap: introduce high-level setter for key/value pairs · 2e0a3048
      Currently, one would use either `git_oidmap_insert` to insert key/value pairs
      into a map or `git_oidmap_put` to insert a key only. These function have
      historically been macros, which is why their syntax is kind of weird: instead of
      returning an error code directly, they instead have to be passed a pointer to
      where the return value shall be stored. This does not match libgit2's common
      idiom of directly returning error codes.Furthermore, `git_oidmap_put` is tightly
      coupled with implementation details of the map as it exposes the index of
      inserted entries.
      
      Introduce a new function `git_oidmap_set`, which takes as parameters the map,
      key and value and directly returns an error code. Convert all trivial callers of
      `git_oidmap_insert` and `git_oidmap_put` to make use of it.
      Patrick Steinhardt committed
    • oidmap: introduce high-level getter for values · 9694ef20
      The current way of looking up an entry from a map is tightly coupled with the
      map implementation, as one first has to look up the index of the key and then
      retrieve the associated value by using the index. As a caller, you usually do
      not care about any indices at all, though, so this is more complicated than
      really necessary. Furthermore, it invites for errors to happen if the correct
      error checking sequence is not being followed.
      
      Introduce a new high-level function `git_oidmap_get` that takes a map and a key
      and returns a pointer to the associated value if such a key exists. Otherwise,
      a `NULL` pointer is returned. Adjust all callers that can trivially be
      converted.
      Patrick Steinhardt committed
    • maps: use uniform lifecycle management functions · 351eeff3
      Currently, the lifecycle functions for maps (allocation, deallocation, resize)
      are not named in a uniform way and do not have a uniform function signature.
      Rename the functions to fix that, and stick to libgit2's naming scheme of saying
      `git_foo_new`. This results in the following new interface for allocation:
      
      - `int git_<t>map_new(git_<t>map **out)` to allocate a new map, returning an
        error code if we ran out of memory
      
      - `void git_<t>map_free(git_<t>map *map)` to free a map
      
      - `void git_<t>map_clear(git<t>map *map)` to remove all entries from a map
      
      This commit also fixes all existing callers.
      Patrick Steinhardt committed
  10. 22 Jan, 2019 1 commit
  11. 01 Dec, 2018 1 commit
  12. 28 Nov, 2018 1 commit
  13. 03 Jul, 2017 1 commit
    • Make sure to always include "common.h" first · 0c7f49dd
      Next to including several files, our "common.h" header also declares
      various macros which are then used throughout the project. As such, we
      have to make sure to always include this file first in all
      implementation files. Otherwise, we might encounter problems or even
      silent behavioural differences due to macros or defines not being
      defined as they should be. So in fact, our header and implementation
      files should make sure to always include "common.h" first.
      
      This commit does so by establishing a common include pattern. Header
      files inside of "src" will now always include "common.h" as its first
      other file, separated by a newline from all the other includes to make
      it stand out as special. There are two cases for the implementation
      files. If they do have a matching header file, they will always include
      this one first, leading to "common.h" being transitively included as
      first file. If they do not have a matching header file, they instead
      include "common.h" as first file themselves.
      
      This fixes the outlined problems and will become our standard practice
      for header and source files inside of the "src/" from now on.
      Patrick Steinhardt committed
  14. 17 Feb, 2017 12 commits
  15. 29 Dec, 2016 1 commit
  16. 12 Jul, 2015 1 commit
  17. 10 Jun, 2015 1 commit
  18. 26 Aug, 2014 1 commit
  19. 12 Jun, 2013 1 commit
  20. 07 Jun, 2013 1 commit
  21. 31 May, 2013 2 commits
    • Mutex init can fail · 1a42dd17
      It is obviously quite a serious problem if this happens, but mutex
      initialization can fail and we should detect it.  It's a bit like
      a memory allocation failure, in that you're probably pretty screwed
      if this occurs, but at least we'll catch it.
      Russell Belfer committed
    • Zero memory for major objects before freeing · f658dc43
      By zeroing out the memory when we free larger objects (i.e. those
      that serve as collections of other data, such as repos, odb, refdb),
      I'm hoping that it will be easier for libgit2 bindings to find
      errors in their object management code.
      Russell Belfer committed
  22. 24 May, 2013 1 commit
  23. 25 Apr, 2013 1 commit
  24. 24 Apr, 2013 1 commit