prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  cpu cores estimate based on cgroups
  I was reading the announcement for 2.4.0 and got interested in https://github.com/dask/distributed/pull/3039 by @jcrist 
  
  That did lead me to this part of the code:
  https://github.com/dask/distributed/blob/7d017c467590c758fa4b8cb2b1193205fe5aa7ad/distributed/system.py#L62
  
  Just by looking at it (and although I'm not an expert I think I know what's going on), I have to observations -- half way between a question and a bugreport.
  
  1. in my docker environment I have here (ubuntu 18.04), the filename is different:
  
  ```
  ~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us 
  100000
  ~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us 
  220000
  ```
  in the code is that path:
  ```
  ~$ ls /sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us
  ls: cannot access '/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us': No such file or directory
  ```
  
  2. The actual calculation is `int(quota / period)`. I think this should round up, not down. The point is, if you have a fraction like "2.5 cores", it will report 2 cores and keep half a core unused. It would be better if it reports 3 cores and then cgroups limits to the actual 2.5.
  
  
  
  </issue>
  <code>
  [start of distributed/system.py]
  1 import os
  2 import sys
  3 
  4 import psutil
  5 
  6 __all__ = ("memory_limit", "cpu_count", "MEMORY_LIMIT", "CPU_COUNT")
  7 
  8 
  9 def memory_limit():
  10     """Get the memory limit (in bytes) for this system.
  11 
  12     Takes the minimum value from the following locations:
  13 
  14     - Total system host memory
  15     - Cgroups limit (if set)
  16     - RSS rlimit (if set)
  17     """
  18     limit = psutil.virtual_memory().total
  19 
  20     # Check cgroups if available
  21     if sys.platform == "linux":
  22         try:
  23             with open("/sys/fs/cgroup/memory/memory.limit_in_bytes") as f:
  24                 cgroups_limit = int(f.read())
  25             if cgroups_limit > 0:
  26                 limit = min(limit, cgroups_limit)
  27         except Exception:
  28             pass
  29 
  30     # Check rlimit if available
  31     try:
  32         import resource
  33 
  34         hard_limit = resource.getrlimit(resource.RLIMIT_RSS)[1]
  35         if hard_limit > 0:
  36             limit = min(limit, hard_limit)
  37     except (ImportError, OSError):
  38         pass
  39 
  40     return limit
  41 
  42 
  43 def cpu_count():
  44     """Get the available CPU count for this system.
  45 
  46     Takes the minimum value from the following locations:
  47 
  48     - Total system cpus available on the host.
  49     - CPU Affinity (if set)
  50     - Cgroups limit (if set)
  51     """
  52     count = os.cpu_count()
  53 
  54     # Check CPU affinity if available
  55     try:
  56         affinity_count = len(psutil.Process().cpu_affinity())
  57         if affinity_count > 0:
  58             count = min(count, affinity_count)
  59     except Exception:
  60         pass
  61 
  62     # Check cgroups if available
  63     if sys.platform == "linux":
  64         try:
  65             with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us") as f:
  66                 quota = int(f.read())
  67             with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us") as f:
  68                 period = int(f.read())
  69             cgroups_count = int(quota / period)
  70             if cgroups_count > 0:
  71                 count = min(count, cgroups_count)
  72         except Exception:
  73             pass
  74 
  75     return count
  76 
  77 
  78 MEMORY_LIMIT = memory_limit()
  79 CPU_COUNT = cpu_count()
  80
  [end of distributed/system.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/distributed/system.py b/distributed/system.py
  --- a/distributed/system.py
  +++ b/distributed/system.py
  @@ -1,3 +1,4 @@
  +import math
   import os
   import sys
   
  @@ -61,16 +62,20 @@
   
       # Check cgroups if available
       if sys.platform == "linux":
  -        try:
  -            with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us") as f:
  -                quota = int(f.read())
  -            with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us") as f:
  -                period = int(f.read())
  -            cgroups_count = int(quota / period)
  -            if cgroups_count > 0:
  -                count = min(count, cgroups_count)
  -        except Exception:
  -            pass
  +        # The directory name isn't standardized across linux distros, check both
  +        for dirname in ["cpuacct,cpu", "cpu,cpuacct"]:
  +            try:
  +                with open("/sys/fs/cgroup/%s/cpu.cfs_quota_us" % dirname) as f:
  +                    quota = int(f.read())
  +                with open("/sys/fs/cgroup/%s/cpu.cfs_period_us" % dirname) as f:
  +                    period = int(f.read())
  +                # We round up on fractional CPUs
  +                cgroups_count = math.ceil(quota / period)
  +                if cgroups_count > 0:
  +                    count = min(count, cgroups_count)
  +                break
  +            except Exception:
  +                pass
   
       return count
  
verification_info: {"golden_diff": "diff --git a/distributed/system.py b/distributed/system.py\n--- a/distributed/system.py\n+++ b/distributed/system.py\n@@ -1,3 +1,4 @@\n+import math\n import os\n import sys\n \n@@ -61,16 +62,20 @@\n \n     # Check cgroups if available\n     if sys.platform == \"linux\":\n-        try:\n-            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\") as f:\n-                quota = int(f.read())\n-            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us\") as f:\n-                period = int(f.read())\n-            cgroups_count = int(quota / period)\n-            if cgroups_count > 0:\n-                count = min(count, cgroups_count)\n-        except Exception:\n-            pass\n+        # The directory name isn't standardized across linux distros, check both\n+        for dirname in [\"cpuacct,cpu\", \"cpu,cpuacct\"]:\n+            try:\n+                with open(\"/sys/fs/cgroup/%s/cpu.cfs_quota_us\" % dirname) as f:\n+                    quota = int(f.read())\n+                with open(\"/sys/fs/cgroup/%s/cpu.cfs_period_us\" % dirname) as f:\n+                    period = int(f.read())\n+                # We round up on fractional CPUs\n+                cgroups_count = math.ceil(quota / period)\n+                if cgroups_count > 0:\n+                    count = min(count, cgroups_count)\n+                break\n+            except Exception:\n+                pass\n \n     return count\n", "issue": "cpu cores estimate based on cgroups\nI was reading the announcement for 2.4.0 and got interested in https://github.com/dask/distributed/pull/3039 by @jcrist \r\n\r\nThat did lead me to this part of the code:\r\nhttps://github.com/dask/distributed/blob/7d017c467590c758fa4b8cb2b1193205fe5aa7ad/distributed/system.py#L62\r\n\r\nJust by looking at it (and although I'm not an expert I think I know what's going on), I have to observations -- half way between a question and a bugreport.\r\n\r\n1. in my docker environment I have here (ubuntu 18.04), the filename is different:\r\n\r\n```\r\n~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us \r\n100000\r\n~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us \r\n220000\r\n```\r\nin the code is that path:\r\n```\r\n~$ ls /sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\r\nls: cannot access '/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us': No such file or directory\r\n```\r\n\r\n2. The actual calculation is `int(quota / period)`. I think this should round up, not down. The point is, if you have a fraction like \"2.5 cores\", it will report 2 cores and keep half a core unused. It would be better if it reports 3 cores and then cgroups limits to the actual 2.5.\r\n\r\n\n", "before_files": [{"content": "import os\nimport sys\n\nimport psutil\n\n__all__ = (\"memory_limit\", \"cpu_count\", \"MEMORY_LIMIT\", \"CPU_COUNT\")\n\n\ndef memory_limit():\n    \"\"\"Get the memory limit (in bytes) for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system host memory\n    - Cgroups limit (if set)\n    - RSS rlimit (if set)\n    \"\"\"\n    limit = psutil.virtual_memory().total\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        try:\n            with open(\"/sys/fs/cgroup/memory/memory.limit_in_bytes\") as f:\n                cgroups_limit = int(f.read())\n            if cgroups_limit > 0:\n                limit = min(limit, cgroups_limit)\n        except Exception:\n            pass\n\n    # Check rlimit if available\n    try:\n        import resource\n\n        hard_limit = resource.getrlimit(resource.RLIMIT_RSS)[1]\n        if hard_limit > 0:\n            limit = min(limit, hard_limit)\n    except (ImportError, OSError):\n        pass\n\n    return limit\n\n\ndef cpu_count():\n    \"\"\"Get the available CPU count for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system cpus available on the host.\n    - CPU Affinity (if set)\n    - Cgroups limit (if set)\n    \"\"\"\n    count = os.cpu_count()\n\n    # Check CPU affinity if available\n    try:\n        affinity_count = len(psutil.Process().cpu_affinity())\n        if affinity_count > 0:\n            count = min(count, affinity_count)\n    except Exception:\n        pass\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        try:\n            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\") as f:\n                quota = int(f.read())\n            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us\") as f:\n                period = int(f.read())\n            cgroups_count = int(quota / period)\n            if cgroups_count > 0:\n                count = min(count, cgroups_count)\n        except Exception:\n            pass\n\n    return count\n\n\nMEMORY_LIMIT = memory_limit()\nCPU_COUNT = cpu_count()\n", "path": "distributed/system.py"}]}