From 18a620cc1abfa9b34a37c180273bb7c54a351a7f Mon Sep 17 00:00:00 2001
From: Justine Tunney <jtunney@gmail.com>
Date: Sat, 27 Jul 2024 08:20:18 -0700
Subject: [PATCH] Make some improvements of little consequence

---
 build/objdump                        | 16 ++++----
 libc/calls/statfs.c                  | 57 ++++++++++++++++++++++++++++
 libc/stdio/flockfile.c               |  2 +
 libc/stdio/stdio.h                   |  2 +-
 libc/thread/pthread_attr_init.c      |  2 +
 libc/thread/pthread_cancel.c         |  1 +
 libc/thread/pthread_detach.c         |  1 +
 libc/thread/pthread_getaffinity_np.c |  3 ++
 libc/thread/pthread_setaffinity_np.c |  3 ++
 libc/thread/pthread_timedjoin_np.c   |  1 +
 tool/cosmocc/README.md               | 18 ++++++---
 11 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/build/objdump b/build/objdump
index f1acb58a5..3683e9bc8 100755
--- a/build/objdump
+++ b/build/objdump
@@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
 fi
 
 find_objdump() {
-  if [ -x .cosmocc/3.3.5/bin/$1-linux-cosmo-objdump ]; then
-    OBJDUMP=.cosmocc/3.3.5/bin/$1-linux-cosmo-objdump
-  elif [ -x .cosmocc/3.3.5/bin/$1-linux-musl-objdump ]; then
-    OBJDUMP=.cosmocc/3.3.5/bin/$1-linux-musl-objdump
-  elif [ -x "$COSMO/.cosmocc/3.3.5/bin/$1-linux-cosmo-objdump" ]; then
-    OBJDUMP="$COSMO/.cosmocc/3.3.5/bin/$1-linux-cosmo-objdump"
-  elif [ -x "$COSMO/.cosmocc/3.3.5/bin/$1-linux-musl-objdump" ]; then
-    OBJDUMP="$COSMO/.cosmocc/3.3.5/bin/$1-linux-musl-objdump"
+  if [ -x .cosmocc/3.6.0/bin/$1-linux-cosmo-objdump ]; then
+    OBJDUMP=.cosmocc/3.6.0/bin/$1-linux-cosmo-objdump
+  elif [ -x .cosmocc/3.6.0/bin/$1-linux-musl-objdump ]; then
+    OBJDUMP=.cosmocc/3.6.0/bin/$1-linux-musl-objdump
+  elif [ -x "$COSMO/.cosmocc/3.6.0/bin/$1-linux-cosmo-objdump" ]; then
+    OBJDUMP="$COSMO/.cosmocc/3.6.0/bin/$1-linux-cosmo-objdump"
+  elif [ -x "$COSMO/.cosmocc/3.6.0/bin/$1-linux-musl-objdump" ]; then
+    OBJDUMP="$COSMO/.cosmocc/3.6.0/bin/$1-linux-musl-objdump"
   else
     echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
     exit 1
diff --git a/libc/calls/statfs.c b/libc/calls/statfs.c
index 6068760d7..ef71c8bc4 100644
--- a/libc/calls/statfs.c
+++ b/libc/calls/statfs.c
@@ -34,6 +34,63 @@
 /**
  * Returns information about filesystem.
  *
+ * The `struct statfs` returned has the following fields:
+ *
+ * - `f_fstypename` holds a NUL-terminated string identifying the file
+ *   system type. On Linux, this will usually be "nfs". On FreeBSD, it
+ *   will usually be "zfs". On OpenBSD and NetBSD, it's usually "ffs".
+ *   On MacOS it's usually "apfs", and on Windows it's usually "NTFS".
+ *
+ * - `f_bsize` is the optimal transfer block size. This may be used to
+ *   appropriately chunk your i/o operations. On local file systems it
+ *   will usually be somewhere between 4096 and 131072 bytes. With NFS
+ *   it may be as high as 512kb.
+ *
+ * - `f_frsize` is the fragment size of the file system. This could be
+ *   anywhere between 512 and 4096 bytes for local filesystems usually
+ *   although it could go higher. It should less than, or equal to the
+ *   `f_bsize`. This fragment size is what you want to use to multiply
+ *   other fields that count blocks into a byte count.
+ *
+ * - `f_bfree` is the number of free blocks in the filesystem. You can
+ *   multiply this number by `f_frsize` to obtain the free byte count.
+ *
+ * - `f_bavail` is the number of free blocks in the filesystem you can
+ *   access from userspace. It's less than or equal to `f_bfree` which
+ *   generally has some blocks reserved for root in a pinch. You could
+ *   multiply this by `f_frsize` to convert this number to bytes.
+ *
+ * - `f_files` is the total number of file nodes. Not every OS has it.
+ *   On Windows for instance it's currently always `INT64_MAX`. It has
+ *   an unspecified meaning. It should be seen as informative.
+ *
+ * - `f_fsid` is an opaque data structure that uniquely identifies the
+ *   filesystem. We're not yet certain how reliable this is across the
+ *   various OSes and filesystem types.
+ *
+ * - `f_namelen` is basically the same as `NAME_MAX` which seems to be
+ *   255 on all the OSes we've evaluated. It's the maximum length when
+ *   it comes to individual components in a filesystem path.
+ *
+ * - `f_type` is an OS-specific file system type ID. This is just some
+ *   magic number. No defines are provided by Cosmopolitan Libc for it
+ *
+ * - `f_flags` specifies the options used when a filesystem is mounted
+ *   and the numbers vary across OSes. Cosmopolitan Libc polyfills the
+ *   magic numbers somewhat consistently. If `IsWindows()` is set then
+ *   the constants defined by Microsoft (e.g. `FILE_READ_ONLY_VOLUME`)
+ *   should be used. Otherwise on any other UNIX system, the following
+ *   constants are provided. You should check each constant at runtime
+ *   before using them, to determine if they're non-zero, for support.
+ *
+ *   - `ST_RDONLY` if mounted in read-only mode (works UNIX + Windows)
+ *   - `ST_NOSUID` if setuid binaries are forbidden (all UNIX support)
+ *   - `ST_NODEV` when device file access forbidden (all UNIX support)
+ *   - `ST_NOEXEC` when a file executions forbidden (all UNIX support)
+ *   - `ST_SYNCHRONOUS`, if `O_SYNC` always happens (all UNIX support)
+ *   - `ST_NOATIME` if access timestamps aren't set (all UNIX support)
+ *   - `ST_RELATIME` if relative acces time is used (all UNIX support)
+ *
  * @return 0 on success, or -1 w/ errno
  * @raise ECANCELED if thread was cancelled in masked mode
  * @raise EINTR if signal was delivered
diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c
index 2c381295f..06bfe2359 100644
--- a/libc/stdio/flockfile.c
+++ b/libc/stdio/flockfile.c
@@ -16,6 +16,7 @@
 │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
+#include "libc/assert.h"
 #include "libc/stdio/fflush.internal.h"
 #include "libc/stdio/internal.h"
 #include "libc/stdio/stdio.h"
@@ -26,6 +27,7 @@
  * Acquires reentrant lock on stdio object, blocking if needed.
  */
 void flockfile(FILE *f) {
+  unassert(f != NULL);
   pthread_mutex_lock(&f->lock);
 }
 
diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h
index 02773651b..028c31d3a 100644
--- a/libc/stdio/stdio.h
+++ b/libc/stdio/stdio.h
@@ -41,7 +41,7 @@ int fileno(FILE *) libcesque paramsnonnull() nosideeffect;
 int fputc(int, FILE *) libcesque paramsnonnull();
 int fputs(const char *, FILE *) libcesque paramsnonnull();
 int fputws(const wchar_t *, FILE *) libcesque paramsnonnull();
-void flockfile(FILE *) libcesque paramsnonnull();
+void flockfile(FILE *) libcesque;
 void funlockfile(FILE *) libcesque paramsnonnull();
 int ftrylockfile(FILE *) libcesque paramsnonnull();
 char *fgets(char *, int, FILE *) libcesque paramsnonnull();
diff --git a/libc/thread/pthread_attr_init.c b/libc/thread/pthread_attr_init.c
index b4c82204e..ec5fa47b1 100644
--- a/libc/thread/pthread_attr_init.c
+++ b/libc/thread/pthread_attr_init.c
@@ -34,6 +34,8 @@
  * @see pthread_attr_setschedpolicy()
  * @see pthread_attr_setinheritsched()
  * @see pthread_attr_setscope()
+ * @see pthread_attr_setsigaltstack_np()
+ * @see pthread_attr_setsigaltstacksize_np()
  */
 errno_t pthread_attr_init(pthread_attr_t *attr) {
   *attr = (pthread_attr_t){
diff --git a/libc/thread/pthread_cancel.c b/libc/thread/pthread_cancel.c
index 5ddbea0db..bd6a1c6ea 100644
--- a/libc/thread/pthread_cancel.c
+++ b/libc/thread/pthread_cancel.c
@@ -354,6 +354,7 @@ static errno_t _pthread_cancel_everyone(void) {
  */
 errno_t pthread_cancel(pthread_t thread) {
   struct PosixThread *arg;
+  unassert(thread);
   if ((arg = (struct PosixThread *)thread)) {
     return _pthread_cancel_single(arg);
   } else {
diff --git a/libc/thread/pthread_detach.c b/libc/thread/pthread_detach.c
index 2456ec69f..8c0bc0c6f 100644
--- a/libc/thread/pthread_detach.c
+++ b/libc/thread/pthread_detach.c
@@ -62,6 +62,7 @@ static errno_t pthread_detach_impl(struct PosixThread *pt) {
  * @returnserrno
  */
 errno_t pthread_detach(pthread_t thread) {
+  unassert(thread);
   struct PosixThread *pt = (struct PosixThread *)thread;
   errno_t err = pthread_detach_impl(pt);
   STRACE("pthread_detach(%d) → %s", _pthread_tid(pt), DescribeErrno(err));
diff --git a/libc/thread/pthread_getaffinity_np.c b/libc/thread/pthread_getaffinity_np.c
index 50cd3e011..83c134ac9 100644
--- a/libc/thread/pthread_getaffinity_np.c
+++ b/libc/thread/pthread_getaffinity_np.c
@@ -16,6 +16,7 @@
 │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
+#include "libc/assert.h"
 #include "libc/calls/sched-sysv.internal.h"
 #include "libc/calls/struct/cpuset.h"
 #include "libc/dce.h"
@@ -39,6 +40,8 @@
 errno_t pthread_getaffinity_np(pthread_t thread, size_t size,
                                cpu_set_t *bitset) {
   int rc, tid;
+  unassert(thread);
+  unassert(bitset);
   tid = _pthread_tid((struct PosixThread *)thread);
 
   if (size != sizeof(cpu_set_t)) {
diff --git a/libc/thread/pthread_setaffinity_np.c b/libc/thread/pthread_setaffinity_np.c
index 4c1b3aa46..96aa4466b 100644
--- a/libc/thread/pthread_setaffinity_np.c
+++ b/libc/thread/pthread_setaffinity_np.c
@@ -16,6 +16,7 @@
 │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
 │ PERFORMANCE OF THIS SOFTWARE.                                                │
 ╚─────────────────────────────────────────────────────────────────────────────*/
+#include "libc/assert.h"
 #include "libc/calls/sched-sysv.internal.h"
 #include "libc/calls/struct/cpuset.h"
 #include "libc/calls/syscall_support-nt.internal.h"
@@ -54,6 +55,8 @@ errno_t pthread_setaffinity_np(pthread_t thread, size_t size,
   int e, rc, tid;
   cpu_set_t bs = {0};
   struct PosixThread *pt;
+  unassert(thread);
+  unassert(bitset);
   e = errno;
   if (size < sizeof(cpu_set_t)) {
     memcpy(&bs, bitset, size);
diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c
index 9dcc410a0..b6b5c2e8a 100644
--- a/libc/thread/pthread_timedjoin_np.c
+++ b/libc/thread/pthread_timedjoin_np.c
@@ -118,6 +118,7 @@ errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr,
   struct PosixThread *pt;
   enum PosixThreadStatus status;
   pt = (struct PosixThread *)thread;
+  unassert(thread);
 
   // "The behavior is undefined if the value specified by the thread
   //  argument to pthread_join() does not refer to a joinable thread."
diff --git a/tool/cosmocc/README.md b/tool/cosmocc/README.md
index 762fbcac6..3120bc38a 100644
--- a/tool/cosmocc/README.md
+++ b/tool/cosmocc/README.md
@@ -181,11 +181,19 @@ The following supplemental flags are defined by cosmocc:
   to pass `-Os` too. Please note that this mode is granted leeway to
   trade away performance whenever possible. Functions like memmove()
   will stop using fancy vectorization which can dramatically decrease
-  the performance of certain use cases. malloc() will stop using cookies
-  which add bloat but are considered important by some people for both
-  security and reporting errors on corruption. APIs will also begin
-  refraining from detecting usage errors that are the fault of the
-  caller, so this mode isn't recommended for development.
+  the performance of certain use cases. malloc() will no longer be
+  scalable either. Cosmo malloc() will normally perform similarly to
+  things like jemalloc. But in -mtiny mode it's protected by a GIL that
+  may cause a multithreaded C++ HTTP server that makes intense usage of
+  the STL may drop from 3.7 million requests per second to just 17k.
+  We've seen it happen. malloc() will also stop using cookies which add
+  bloat but are considered important by some people for both security
+  and reporting errors on corruption. APIs will also begin refraining
+  from detecting usage errors that are the fault of the caller, so this
+  mode isn't recommended for development. Where -mtiny truly shines is
+  when you're writing tiny programs. Particularly if they're ephemeral
+  and frequent (e.g. build tooling), because the tiny runtime needs to
+  do less work at process startup.
 
 - `-moptlinux` uses the optimized Linux-only version of Cosmopolitan
   Libc runtime libraries. Your program will only be able to run on