diff --git a/libc/calls/CPU_COUNT_S.c b/libc/calls/CPU_COUNT_S.c new file mode 100644 index 000000000..c14a9e947 --- /dev/null +++ b/libc/calls/CPU_COUNT_S.c @@ -0,0 +1,28 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/struct/cpuset.h" +#include "libc/intrin/popcnt.h" + +int CPU_COUNT_S(size_t size, const cpu_set_t *set) { + int i, c = 0; + for (i = 0; i < size / sizeof(*set->__bits); i++) { + c += popcnt(set->__bits[i]); + } + return c; +} diff --git a/libc/calls/struct/cpuset.h b/libc/calls/struct/cpuset.h index c0df8bc1c..dafddbb14 100644 --- a/libc/calls/struct/cpuset.h +++ b/libc/calls/struct/cpuset.h @@ -17,15 +17,31 @@ int sched_setaffinity(int, size_t, const cpu_set_t *); #define CPU_SET(i, s) ((s)->__bits[(i) / 64] |= 1ull << ((i) % 64)) #define CPU_CLR(i, s) ((s)->__bits[(i) / 64] &= ~(1ull << ((i) % 64))) #define CPU_ISSET(i, s) (!!((s)->__bits[(i) / 64] & (1ull << ((i) % 64)))) + void CPU_ZERO(cpu_set_t *); +#define CPU_ZERO(x) CPU_ZERO(x) + int CPU_COUNT(cpu_set_t *); +#define CPU_COUNT(x) CPU_COUNT(x) + int CPU_EQUAL(cpu_set_t *, cpu_set_t *); +#define CPU_EQUAL(x, y) CPU_EQUAL(x, y) + void CPU_AND(cpu_set_t *, cpu_set_t *, cpu_set_t *); +#define CPU_AND(x, y, z) CPU_AND(x, y, z) + void CPU_OR(cpu_set_t *, cpu_set_t *, cpu_set_t *); +#define CPU_OR(x, y, z) CPU_OR(x, y, z) + void CPU_XOR(cpu_set_t *, cpu_set_t *, cpu_set_t *); +#define CPU_XOR(x, y, z) CPU_XOR(x, y, z) + +int CPU_COUNT_S(size_t, const cpu_set_t *); +#define CPU_COUNT_S(x, y) CPU_COUNT_S(x, y) #define CPU_ALLOC_SIZE(n) \ ((((n) + (8 * sizeof(long) - 1)) & -(8 * sizeof(long))) / sizeof(long)) + #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1, CPU_ALLOC_SIZE(n))) #define CPU_FREE(set) free(set) #define CPU_ZERO_S(size, set) memset(set, 0, size) diff --git a/tool/decode/zip.c b/tool/decode/zip.c index 4370a44a0..063067047 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -29,6 +29,7 @@ #include "libc/nexgen32e/crc32.h" #include "libc/nt/struct/filetime.h" #include "libc/stdio/stdio.h" +#include "libc/stdio/sysparam.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" @@ -401,29 +402,31 @@ void ShowCentralDirHeader64(uint8_t *cd) { } uint8_t *GetZipCdir32(const uint8_t *p, size_t n) { - size_t i; + int64_t i, e; if (n >= kZipCdirHdrMinSize) { i = n - kZipCdirHdrMinSize; - do { + e = MAX(0, n - 65536); + for (; i >= e; --i) { if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipEocd32(p, n, i) == kZipOk) { return (/*unconst*/ uint8_t *)(p + i); } - } while (i--); + } } return NULL; } uint8_t *GetZipCdir64(const uint8_t *p, size_t n) { - uint64_t i, j; + int64_t e, i, j; if (n >= kZipCdir64LocatorSize) { i = n - kZipCdir64LocatorSize; - do { + e = MAX(0, n - 65536); + for (; i >= e; --i) { if (READ32LE(p + i) == kZipCdir64LocatorMagic && (j = ZIP_LOCATE64_OFFSET(p + i)) + kZipCdir64HdrMinSize <= n) { return (uint8_t *)p + j; } - } while (i--); + } } return NULL; }