diff --git a/include/uv.h b/include/uv.h
index 02397dd0..ab2f36fc 100644
--- a/include/uv.h
+++ b/include/uv.h
@@ -842,6 +842,16 @@ UV_EXTERN int uv_pipe_connect2(uv_connect_t* req,
                                size_t namelen,
                                unsigned int flags,
                                uv_connect_cb cb);
+#ifdef CONFIG_NET_RPMSG
+UV_EXTERN int uv_pipe_rpmsg_bind(uv_pipe_t* handle,
+                                 const char* name,
+                                 const char* cpu_name);
+UV_EXTERN void uv_pipe_rpmsg_connect(uv_connect_t* req,
+                                     uv_pipe_t* handle,
+                                     const char* name,
+                                     const char* cpu_name,
+                                     uv_connect_cb cb);
+#endif
 UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
                                   char* buffer,
                                   size_t* size);
@@ -1826,12 +1836,14 @@ UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
 
 typedef enum {
   UV_THREAD_NO_FLAGS = 0x00,
-  UV_THREAD_HAS_STACK_SIZE = 0x01
+  UV_THREAD_HAS_STACK_SIZE = 0x01,
+  UV_THREAD_HAS_PRIORITY = 0x02
 } uv_thread_create_flags;
 
 struct uv_thread_options_s {
   unsigned int flags;
   size_t stack_size;
+  int priority;
   /* More fields may be added at any time. */
 };
 
diff --git a/include/uv/unix.h b/include/uv/unix.h
index 09f88a56..4962b932 100644
--- a/include/uv/unix.h
+++ b/include/uv/unix.h
@@ -66,6 +66,7 @@
       defined(__MSYS__)   || \
       defined(__HAIKU__)  || \
       defined(__QNX__)    || \
+      defined(__NuttX__)  || \
       defined(__GNU__)
 # include "uv/posix.h"
 #endif
diff --git a/src/fs-poll.c b/src/fs-poll.c
index 1bac1c56..ea4a17cd 100644
--- a/src/fs-poll.c
+++ b/src/fs-poll.c
@@ -53,7 +53,7 @@ static void poll_cb(uv_fs_t* req);
 static void timer_cb(uv_timer_t* timer);
 static void timer_close_cb(uv_handle_t* handle);
 
-static uv_stat_t zero_statbuf;
+static const uv_stat_t zero_statbuf;
 
 
 int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
diff --git a/src/random.c b/src/random.c
index e75f77de..feef5a44 100644
--- a/src/random.c
+++ b/src/random.c
@@ -31,7 +31,7 @@
 static int uv__random(void* buf, size_t buflen) {
   int rc;
 
-#if defined(__PASE__)
+#if defined(__PASE__) || defined(__NuttX__)
   rc = uv__random_readpath("/dev/urandom", buf, buflen);
 #elif defined(_AIX) || defined(__QNX__)
   rc = uv__random_readpath("/dev/random", buf, buflen);
diff --git a/src/threadpool.c b/src/threadpool.c
index dbef67f2..94414212 100644
--- a/src/threadpool.c
+++ b/src/threadpool.c
@@ -20,6 +20,7 @@
  */
 
 #include "uv-common.h"
+#include "uv-global.h"
 
 #if !defined(_WIN32)
 # include "unix/internal.h"
@@ -29,18 +30,6 @@
 
 #define MAX_THREADPOOL_SIZE 1024
 
-static uv_once_t once = UV_ONCE_INIT;
-static uv_cond_t cond;
-static uv_mutex_t mutex;
-static unsigned int idle_threads;
-static unsigned int slow_io_work_running;
-static unsigned int nthreads;
-static uv_thread_t* threads;
-static uv_thread_t default_threads[4];
-static struct uv__queue exit_message;
-static struct uv__queue wq;
-static struct uv__queue run_slow_work_message;
-static struct uv__queue slow_io_pending_wq;
 
 static unsigned int slow_work_thread_threshold(void) {
   return (nthreads + 1) / 2;
@@ -68,16 +57,16 @@ static void worker(void* arg) {
 
     /* Keep waiting while either no work is present or only slow I/O
        and we're at the threshold for that. */
-    while (uv__queue_empty(&wq) ||
-           (uv__queue_head(&wq) == &run_slow_work_message &&
-            uv__queue_next(&run_slow_work_message) == &wq &&
+    while (uv__queue_empty(&lwq) ||
+           (uv__queue_head(&lwq) == &run_slow_work_message &&
+            uv__queue_next(&run_slow_work_message) == &lwq &&
             slow_io_work_running >= slow_work_thread_threshold())) {
       idle_threads += 1;
       uv_cond_wait(&cond, &mutex);
       idle_threads -= 1;
     }
 
-    q = uv__queue_head(&wq);
+    q = uv__queue_head(&lwq);
     if (q == &exit_message) {
       uv_cond_signal(&cond);
       uv_mutex_unlock(&mutex);
@@ -92,7 +81,7 @@ static void worker(void* arg) {
       /* If we're at the slow I/O threshold, re-schedule until after all
          other work in the queue is done. */
       if (slow_io_work_running >= slow_work_thread_threshold()) {
-        uv__queue_insert_tail(&wq, q);
+        uv__queue_insert_tail(&lwq, q);
         continue;
       }
 
@@ -110,7 +99,7 @@ static void worker(void* arg) {
 
       /* If there is more slow I/O work, schedule it to be run as well. */
       if (!uv__queue_empty(&slow_io_pending_wq)) {
-        uv__queue_insert_tail(&wq, &run_slow_work_message);
+        uv__queue_insert_tail(&lwq, &run_slow_work_message);
         if (idle_threads > 0)
           uv_cond_signal(&cond);
       }
@@ -153,7 +142,7 @@ static void post(struct uv__queue* q, enum uv__work_kind kind) {
     q = &run_slow_work_message;
   }
 
-  uv__queue_insert_tail(&wq, q);
+  uv__queue_insert_tail(&lwq, q);
   if (idle_threads > 0)
     uv_cond_signal(&cond);
   uv_mutex_unlock(&mutex);
@@ -191,11 +180,28 @@ void uv__threadpool_cleanup(void) {
 
 
 static void init_threads(void) {
-  uv_thread_options_t config;
   unsigned int i;
   const char* val;
   uv_sem_t sem;
 
+  const uv_thread_options_t params = {
+#ifdef DEF_THREADPOOL_STACKSIZE
+    UV_THREAD_HAS_STACK_SIZE |
+#endif
+#ifdef DEF_THREADPOOL_PRIORITY
+    UV_THREAD_HAS_PRIORITY |
+#endif
+    UV_THREAD_NO_FLAGS,
+#ifdef DEF_THREADPOOL_STACKSIZE
+    DEF_THREADPOOL_STACKSIZE,
+#else
+    0,
+#endif
+#ifdef DEF_THREADPOOL_PRIORITY
+    DEF_THREADPOOL_PRIORITY
+#endif
+  };
+
   nthreads = ARRAY_SIZE(default_threads);
   val = getenv("UV_THREADPOOL_SIZE");
   if (val != NULL)
@@ -220,18 +226,15 @@ static void init_threads(void) {
   if (uv_mutex_init(&mutex))
     abort();
 
-  uv__queue_init(&wq);
+  uv__queue_init(&lwq);
   uv__queue_init(&slow_io_pending_wq);
   uv__queue_init(&run_slow_work_message);
 
   if (uv_sem_init(&sem, 0))
     abort();
 
-  config.flags = UV_THREAD_HAS_STACK_SIZE;
-  config.stack_size = 8u << 20;  /* 8 MB */
-
   for (i = 0; i < nthreads; i++)
-    if (uv_thread_create_ex(threads + i, &config, worker, &sem))
+    if (uv_thread_create_ex(threads + i, &params, worker, &sem))
       abort();
 
   for (i = 0; i < nthreads; i++)
diff --git a/src/unix/core.c b/src/unix/core.c
index 25c5181f..6ff617af 100644
--- a/src/unix/core.c
+++ b/src/unix/core.c
@@ -60,7 +60,7 @@
 # include <crt_externs.h>
 # include <mach-o/dyld.h> /* _NSGetExecutablePath */
 # define environ (*_NSGetEnviron())
-#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
+#elif !defined(__NuttX__) /* defined(__APPLE__) && !TARGET_OS_IPHONE */
 extern char** environ;
 #endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */
 
@@ -1000,7 +1000,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
   rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
   rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
 
-#if !defined(__MVS__) && !defined(__HAIKU__)
+#if !defined(__MVS__) && !defined(__HAIKU__) && !defined(__NuttX__)
   rusage->ru_maxrss = usage.ru_maxrss;
   rusage->ru_ixrss = usage.ru_ixrss;
   rusage->ru_idrss = usage.ru_idrss;
diff --git a/src/unix/fs.c b/src/unix/fs.c
index 6b051c12..0d4c6014 100644
--- a/src/unix/fs.c
+++ b/src/unix/fs.c
@@ -56,7 +56,7 @@
 #endif
 
 /* preadv() and pwritev() were added in Android N (level 24) */
-#if defined(__linux__) && !(defined(__ANDROID__) && __ANDROID_API__ < 24)
+#if (defined(__linux__) || defined(__NuttX__)) && !(defined(__ANDROID__) && __ANDROID_API__ < 24)
 # define TRY_PREADV 1
 #endif
 
diff --git a/src/unix/internal.h b/src/unix/internal.h
index fe588513..ddc744b2 100644
--- a/src/unix/internal.h
+++ b/src/unix/internal.h
@@ -215,6 +215,7 @@ struct uv__statx {
     defined(__FreeBSD__) || \
     defined(__linux__) || \
     defined(__OpenBSD__) || \
+    defined(__NuttX__) || \
     defined(__NetBSD__)
 #define uv__nonblock uv__nonblock_ioctl
 #define UV__NONBLOCK_IS_IOCTL 1
diff --git a/src/unix/loop.c b/src/unix/loop.c
index a9468e8e..30ecc532 100644
--- a/src/unix/loop.c
+++ b/src/unix/loop.c
@@ -220,8 +220,10 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
   if (option != UV_LOOP_BLOCK_SIGNAL)
     return UV_ENOSYS;
 
+#ifdef SIGPROF
   if (va_arg(ap, int) != SIGPROF)
     return UV_EINVAL;
+#endif
 
   loop->flags |= UV_LOOP_BLOCK_SIGPROF;
   return 0;
diff --git a/src/unix/nuttx.c b/src/unix/nuttx.c
new file mode 100644
index 00000000..298bd2f8
--- /dev/null
+++ b/src/unix/nuttx.c
@@ -0,0 +1,303 @@
+/* Copyright Xiaomi, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/* We lean on the fact that POLL{IN,OUT,ERR,HUP} correspond with their
+ * EPOLL* counterparts.  We use the POLL* variants in this file because that
+ * is what libuv uses elsewhere.
+ */
+
+#include "internal.h"
+#include "uv.h"
+#include "uv-global.h"
+
+#include <ifaddrs.h>
+#include <malloc.h>
+#include <net/if.h>
+#include <pthread.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+
+#include <nuttx/tls.h>
+
+int uv_exepath(char* buffer, size_t* size) {
+  return UV_ENOTSUP;
+}
+
+char** uv_setup_args(int argc, char** argv) {
+  return argv;
+}
+
+void uv__process_title_cleanup(void) {
+}
+
+int uv_set_process_title(const char* title) {
+  return UV__ERR(pthread_setname_np(pthread_self(), title));
+}
+
+int uv_get_process_title(char* buffer, size_t size) {
+  return UV__ERR(pthread_getname_np(pthread_self(), buffer, size));
+}
+
+uint64_t uv_get_constrained_memory(void) {
+  return 0;  /* Memory constraints are unknown. */
+}
+
+uint64_t uv_get_available_memory(void) {
+  return uv_get_free_memory();
+}
+
+int uv_resident_set_memory(size_t* rss) {
+  struct sysinfo info;
+  int ret;
+
+  ret = sysinfo(&info);
+  if (ret >= 0)
+    {
+      *rss = (info.totalram - info.freeram) * info.mem_unit;
+    }
+  else
+    {
+      ret = UV__ERR(errno);
+    }
+
+  return ret;
+}
+
+int uv_uptime(double* uptime) {
+  struct sysinfo info;
+  int ret;
+
+
+  ret = sysinfo(&info);
+  if (ret >= 0)
+    {
+      *uptime = info.uptime;
+    }
+  else
+    {
+      ret = UV__ERR(errno);
+    }
+
+  return ret;
+}
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+  *count = sysconf(_SC_NPROCESSORS_ONLN);
+  *cpu_infos = uv__calloc(*count, sizeof(uv_cpu_info_t));
+  if (!*cpu_infos) {
+    return UV_ENOMEM;
+  }
+
+  return 0;
+}
+
+#ifndef CONFIG_NETDEV_IFINDEX
+unsigned int if_nametoindex(const char *ifname) {
+  return 0;
+}
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+  return UV_ENOSYS;
+}
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+}
+#else
+static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+    return 1;
+  if (ent->ifa_addr == NULL)
+    return 1;
+  return 0;
+}
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+  struct ifaddrs* addrs;
+  struct ifaddrs* ent;
+  uv_interface_address_t* address;
+
+  *count = 0;
+  *addresses = NULL;
+
+  if (getifaddrs(&addrs) != 0)
+    return UV__ERR(errno);
+
+  /* Count the number of interfaces */
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+    if (uv__ifaddr_exclude(ent))
+      continue;
+    (*count)++;
+  }
+
+  if (*count == 0) {
+    freeifaddrs(addrs);
+    return 0;
+  }
+
+  /* Make sure the memory is initiallized to zero using calloc() */
+  *addresses = uv__calloc(*count, sizeof(**addresses));
+  if (*addresses == NULL) {
+    freeifaddrs(addrs);
+    return UV_ENOMEM;
+  }
+
+  address = *addresses;
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+    if (uv__ifaddr_exclude(ent))
+      continue;
+
+    address->name = uv__strdup(ent->ifa_name);
+
+    if (ent->ifa_addr->sa_family == AF_INET6) {
+      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+    } else {
+      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+    }
+
+    if (ent->ifa_netmask) {
+      if (ent->ifa_netmask->sa_family == AF_INET6) {
+        address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+      } else {
+        address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+      }
+    }
+
+    if (ent->ifa_data) {
+      struct sockaddr* addr = ent->ifa_data;
+      memcpy(address->phys_addr, addr->sa_data, sizeof(address->phys_addr));
+    }
+
+    address->is_internal = !strcmp(address->name, "lo");
+    address++;
+  }
+
+  freeifaddrs(addrs);
+  return 0;
+}
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+  int i;
+
+  for (i = 0; i < count; i++) {
+    uv__free(addresses[i].name);
+  }
+
+  uv__free(addresses);
+}
+#endif
+
+#ifndef CONFIG_NET_SOCKOPTS
+int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_len) {
+  if (option == SO_ERROR) {
+    *(int *)value = UV_ENOTSUP;
+  }
+
+  return UV_ENOTSUP;
+}
+#endif
+
+#ifndef CONFIG_NET
+int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+  return UV_ENOTSUP;
+}
+
+ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) {
+  return UV_ENOTSUP;
+}
+
+ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags) {
+  return UV_ENOTSUP;
+}
+
+int shutdown(int sockfd, int how) {
+  return UV_ENOTSUP;
+}
+#endif
+
+#ifndef CONFIG_NET_TCP
+int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
+  return UV_ENOTSUP;
+}
+
+void uv__tcp_close(uv_tcp_t* handle) {
+}
+
+int uv__tcp_nodelay(int fd, int on) {
+  return UV_ENOTSUP;
+}
+
+int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
+  return UV_ENOTSUP;
+}
+#endif
+
+#ifndef CONFIG_NET_UDP
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+  return UV_ENOTSUP;
+}
+
+void uv__udp_close(uv_udp_t* handle) {
+}
+
+void uv__udp_finish_close(uv_udp_t* handle) {
+}
+#endif
+
+#if CONFIG_TLS_TASK_NELEM == 0
+#  error "libuv depends on CONFIG_TLS_TASK_NELEM, please enable it by menuconfig"
+#endif
+
+#undef once
+#undef uv__signal_global_init_guard
+#undef uv__signal_lock_pipefd
+
+static void uv__global_free(void* global) {
+  if (global) {
+    uv_library_shutdown();
+    uv__free(global);
+  }
+}
+
+uv__global_t* uv__global_get(void) {
+  static int index = -1;
+  static const uv_once_t once = UV_ONCE_INIT;
+  uv__global_t* global = NULL;
+
+  if (index < 0) {
+    index = task_tls_alloc(uv__global_free);
+  }
+
+  if (index >= 0) {
+    global = (uv__global_t*)task_tls_get_value(index);
+    if (global == NULL) {
+      global = (uv__global_t*)uv__calloc(1, sizeof(uv__global_t));
+      if (global) {
+          global->once = once;
+          global->uv__signal_global_init_guard = once;
+          global->uv__signal_lock_pipefd[0] = -1;
+          global->uv__signal_lock_pipefd[1] = -1;
+          task_tls_set_value(index, (uintptr_t)global);
+      }
+    }
+  }
+
+  ASSERT(global != NULL);
+  return global;
+}
diff --git a/src/unix/pipe.c b/src/unix/pipe.c
index d332f351..7f1deeb1 100644
--- a/src/unix/pipe.c
+++ b/src/unix/pipe.c
@@ -28,7 +28,9 @@
 #include <sys/un.h>
 #include <unistd.h>
 #include <stdlib.h>
-
+#ifdef CONFIG_NET_RPMSG
+#include <netpacket/rpmsg.h>
+#endif // CONFIG_NET_RPMSG
 
 int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
   uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
@@ -126,6 +128,48 @@ err_socket:
   return err;
 }
 
+#ifdef CONFIG_NET_RPMSG
+int uv_pipe_rpmsg_bind(uv_pipe_t* handle,
+                       const char* name,
+                       const char* cpu_name) {
+  struct sockaddr_rpmsg saddr;
+  int sockfd;
+  int err;
+
+  /* Already bound? */
+  if (uv__stream_fd(handle) >= 0)
+    return UV_EINVAL;
+
+  err = uv__socket(AF_RPMSG, SOCK_STREAM, 0);
+  if (err < 0)
+    goto err_socket;
+  sockfd = err;
+
+  memset(&saddr, 0, sizeof saddr);
+  uv__strscpy(saddr.rp_name, name, sizeof(saddr.rp_name));
+  uv__strscpy(saddr.rp_cpu, cpu_name, sizeof(saddr.rp_cpu));
+  saddr.rp_family = AF_RPMSG;
+
+  if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
+    err = UV__ERR(errno);
+    /* Convert ENOENT to EACCES for compatibility with Windows. */
+    if (err == UV_ENOENT)
+      err = UV_EACCES;
+
+    uv__close(sockfd);
+    goto err_socket;
+  }
+
+  /* Success. */
+  handle->flags |= UV_HANDLE_BOUND;
+  handle->pipe_fname = NULL;
+  handle->io_watcher.fd = sockfd;
+  return 0;
+
+err_socket:
+  return err;
+}
+#endif
 
 int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
   if (uv__stream_fd(handle) == -1)
diff --git a/src/unix/posix-poll.c b/src/unix/posix-poll.c
index 2e016c2f..3a351742 100644
--- a/src/unix/posix-poll.c
+++ b/src/unix/posix-poll.c
@@ -145,8 +145,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
   int have_signals;
   struct pollfd* pe;
   int fd;
-  int user_timeout;
-  int reset_timeout;
+  int user_timeout = 0;
+  int reset_timeout = 0;
 
   if (loop->nfds == 0) {
     assert(uv__queue_empty(&loop->watcher_queue));
@@ -173,11 +173,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 
   /* Prepare a set of signals to block around poll(), if any.  */
   pset = NULL;
+#ifdef SIGPROF
   if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
     pset = &set;
     sigemptyset(pset);
     sigaddset(pset, SIGPROF);
   }
+#else
+  (void) set;
+#endif
 
   assert(timeout >= -1);
   time_base = loop->time;
diff --git a/src/unix/process-spawn.c b/src/unix/process-spawn.c
new file mode 100644
index 00000000..9b9668d1
--- /dev/null
+++ b/src/unix/process-spawn.c
@@ -0,0 +1,380 @@
+/* Copyright Xiaomi, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#define __USE_GNU
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <spawn.h>
+
+#ifdef SIGCHLD
+static void uv__chld(uv_signal_t* handle, int signum) {
+  uv_process_t* process;
+  uv_loop_t* loop;
+  int exit_status;
+  int term_signal;
+  int status;
+  pid_t pid;
+  struct uv__queue pending;
+  struct uv__queue* q;
+  struct uv__queue* h;
+
+  assert(signum == SIGCHLD);
+
+  uv__queue_init(&pending);
+  loop = handle->loop;
+
+  h = &loop->process_handles;
+  q = uv__queue_head(h);
+  while (q != h) {
+    process = uv__queue_data(q, uv_process_t, queue);
+    q = uv__queue_next(q);
+
+    do
+      pid = waitpid(process->pid, &status, WNOHANG);
+    while (pid == -1 && errno == EINTR);
+
+    if (pid == 0)
+      continue;
+
+    if (pid == -1) {
+      if (errno != ECHILD)
+        abort();
+      continue;
+    }
+
+    process->status = status;
+    uv__queue_remove(&process->queue);
+    uv__queue_insert_tail(&pending, &process->queue);
+  }
+
+  h = &pending;
+  q = uv__queue_head(h);
+  while (q != h) {
+    process = uv__queue_data(q, uv_process_t, queue);
+    q = uv__queue_next(q);
+
+    uv__queue_remove(&process->queue);
+    uv__queue_init(&process->queue);
+    uv__handle_stop(process);
+
+    if (process->exit_cb == NULL)
+      continue;
+
+    exit_status = 0;
+    if (WIFEXITED(process->status))
+      exit_status = WEXITSTATUS(process->status);
+
+    term_signal = 0;
+    if (WIFSIGNALED(process->status))
+      term_signal = WTERMSIG(process->status);
+
+    process->exit_cb(process, exit_status, term_signal);
+  }
+  assert(uv__queue_empty(&pending));
+}
+
+
+int uv__process_init(uv_loop_t* loop) {
+  int err;
+
+  err = uv_signal_init(loop, &loop->child_watcher);
+  if (err)
+    return err;
+  uv__handle_unref(&loop->child_watcher);
+  loop->child_watcher.flags |= UV_HANDLE_INTERNAL;
+  return 0;
+}
+#endif
+
+/*
+ * Used for initializing stdio streams like options.stdin_stream. Returns
+ * zero on success. See also the cleanup section in uv_spawn().
+ */
+static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
+  int mask;
+  int fd;
+
+  mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
+
+  switch (container->flags & mask) {
+  case UV_IGNORE:
+    return 0;
+
+  case UV_CREATE_PIPE:
+    assert(container->data.stream != NULL);
+    if (container->data.stream->type != UV_NAMED_PIPE)
+      return UV_EINVAL;
+    else
+      return uv_pipe(fds, 0, 0);
+
+  case UV_INHERIT_FD:
+  case UV_INHERIT_STREAM:
+    if (container->flags & UV_INHERIT_FD)
+      fd = container->data.fd;
+    else
+      fd = uv__stream_fd(container->data.stream);
+
+    if (fd == -1)
+      return UV_EINVAL;
+
+    fds[0] = fds[1] = fd;
+    return 0;
+
+  default:
+    assert(0 && "Unexpected flags");
+    return UV_EINVAL;
+  }
+}
+
+
+static int uv__process_open_stream(uv_stdio_container_t* container,
+                                   int pipefds[2]) {
+  int flags;
+
+  if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
+    return 0;
+
+  uv__nonblock(pipefds[0], 1);
+
+  flags = 0;
+  if (container->flags & UV_WRITABLE_PIPE)
+    flags |= UV_HANDLE_READABLE;
+  if (container->flags & UV_READABLE_PIPE)
+    flags |= UV_HANDLE_WRITABLE;
+
+  return uv__stream_open(container->data.stream, pipefds[0], flags);
+}
+
+
+static void uv__process_close_stream(uv_stdio_container_t* container) {
+  if (!(container->flags & UV_CREATE_PIPE)) return;
+  uv__stream_close(container->data.stream);
+}
+
+
+static int uv__process_child_spawn(const uv_process_options_t* options,
+                                   int stdio_count,
+                                   int (*pipes)[2],
+                                   pid_t *pid) {
+  posix_spawn_file_actions_t file_actions;
+  posix_spawnattr_t attr;
+  sigset_t set;
+  int use_fd;
+  int flags;
+  int err;
+  int fd;
+
+  posix_spawn_file_actions_init(&file_actions);
+  posix_spawnattr_init(&attr);
+
+  /* Reset signal disposition and mask */
+  flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
+
+  sigfillset(&set);
+  posix_spawnattr_setsigdefault(&attr, &set);
+
+  sigemptyset(&set);
+  posix_spawnattr_setsigmask(&attr, &set);
+
+  if (options->flags & UV_PROCESS_DETACHED)
+    flags |= POSIX_SPAWN_SETSID;
+
+  /* First duplicate low numbered fds, since it's not safe to duplicate them,
+   * they could get replaced. Example: swapping stdout and stderr; without
+   * this fd 2 (stderr) would be duplicated into fd 1, thus making both
+   * stdout and stderr go to the same fd, which was not the intention. */
+  for (fd = 0; fd < stdio_count; fd++) {
+    use_fd = pipes[fd][1];
+    if (use_fd < 0 || use_fd >= fd)
+      continue;
+    pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
+    if (pipes[fd][1] == -1) {
+      err = errno;
+      goto error;
+    }
+  }
+
+  for (fd = 0; fd < stdio_count; fd++) {
+    use_fd = pipes[fd][1];
+
+    if (use_fd < 0) {
+      if (fd >= 3)
+        continue;
+      else {
+        /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+         * set
+         */
+        use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
+        pipes[fd][1] = use_fd;
+
+        if (use_fd < 0) {
+          err = errno;
+          goto error;
+        }
+      }
+    }
+
+    if (fd == use_fd)
+      uv__cloexec(use_fd, 0);
+    else
+      posix_spawn_file_actions_adddup2(&file_actions, use_fd, fd);
+
+    if (fd <= 2)
+      uv__nonblock_fcntl(use_fd, 0);
+  }
+
+  if (options->flags & UV_PROCESS_SETUID) {
+    err = options->uid ? ENOTSUP : EPERM;
+    goto error;
+  }
+
+  if (options->flags & UV_PROCESS_SETGID) {
+    if (options->gid == 0) {
+      err = EPERM;
+      goto error;
+    }
+
+    posix_spawnattr_setpgroup(&attr, options->gid);
+    flags |= POSIX_SPAWN_SETPGROUP;
+  }
+
+  posix_spawnattr_setflags(&attr, flags);
+  err = posix_spawn(pid, options->file, &file_actions, &attr,
+                    options->args, options->env ? options->env : environ);
+
+error:
+  for (fd = 0; fd < stdio_count; fd++) {
+    if (pipes[fd][1] >= 0 && pipes[fd][1] != pipes[fd][0]) {
+      close(pipes[fd][1]);
+      pipes[fd][1] = -1;
+    }
+  }
+
+  posix_spawn_file_actions_destroy(&file_actions);
+  posix_spawnattr_destroy(&attr);
+  return UV__ERR(err);
+}
+
+
+int uv_spawn(uv_loop_t* loop,
+             uv_process_t* process,
+             const uv_process_options_t* options) {
+  int pipes_storage[8][2];
+  int (*pipes)[2];
+  int stdio_count;
+  pid_t pid;
+  int err;
+  int i;
+
+  assert(options->file != NULL);
+  assert(!(options->flags & ~(UV_PROCESS_DETACHED |
+                              UV_PROCESS_SETGID |
+                              UV_PROCESS_SETUID |
+                              UV_PROCESS_WINDOWS_HIDE |
+                              UV_PROCESS_WINDOWS_HIDE_CONSOLE |
+                              UV_PROCESS_WINDOWS_HIDE_GUI |
+                              UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+
+  uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
+  uv__queue_init(&process->queue);
+
+  stdio_count = options->stdio_count;
+  if (stdio_count < 3)
+    stdio_count = 3;
+
+  err = UV_ENOMEM;
+  pipes = pipes_storage;
+  if (stdio_count > (int)ARRAY_SIZE(pipes_storage))
+    pipes = uv__malloc(stdio_count * sizeof(*pipes));
+
+  if (pipes == NULL)
+    goto error;
+
+  for (i = 0; i < stdio_count; i++) {
+    pipes[i][0] = -1;
+    pipes[i][1] = -1;
+  }
+
+  for (i = 0; i < options->stdio_count; i++) {
+    err = uv__process_init_stdio(options->stdio + i, pipes[i]);
+    if (err)
+      goto error;
+  }
+
+#ifdef SIGCHLD
+  uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
+#endif
+
+  err = uv__process_child_spawn(options, stdio_count, pipes, &pid);
+  if (err)
+    goto error;
+
+  for (i = 0; i < options->stdio_count; i++) {
+    err = uv__process_open_stream(options->stdio + i, pipes[i]);
+    if (err == 0)
+      continue;
+
+    while (i--)
+      uv__process_close_stream(options->stdio + i);
+
+    goto error;
+  }
+
+  uv__queue_insert_tail(&loop->process_handles, &process->queue);
+  uv__handle_start(process);
+
+  process->status = 0;
+  process->pid = pid;
+  process->exit_cb = options->exit_cb;
+
+  if (pipes != pipes_storage)
+    uv__free(pipes);
+
+  return 0;
+
+error:
+  if (pipes != NULL) {
+    for (i = 0; i < stdio_count; i++) {
+      if (i < options->stdio_count)
+        if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
+          continue;
+      if (pipes[i][0] != -1)
+        uv__close_nocheckstdio(pipes[i][0]);
+      if (pipes[i][1] != -1)
+        uv__close_nocheckstdio(pipes[i][1]);
+    }
+
+    if (pipes != pipes_storage)
+      uv__free(pipes);
+  }
+
+  return err;
+}
diff --git a/src/unix/signal.c b/src/unix/signal.c
index 63aba5a6..28b80eff 100644
--- a/src/unix/signal.c
+++ b/src/unix/signal.c
@@ -20,6 +20,7 @@
 
 #include "uv.h"
 #include "internal.h"
+#include "uv-global.h"
 
 #include <assert.h>
 #include <errno.h>
@@ -32,14 +33,6 @@
 # define SA_RESTART 0
 #endif
 
-typedef struct {
-  uv_signal_t* handle;
-  int signum;
-} uv__signal_msg_t;
-
-RB_HEAD(uv__signal_tree_s, uv_signal_s);
-
-
 static int uv__signal_unlock(void);
 static int uv__signal_start(uv_signal_t* handle,
                             uv_signal_cb signal_cb,
@@ -50,12 +43,6 @@ static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
 static void uv__signal_stop(uv_signal_t* handle);
 static void uv__signal_unregister_handler(int signum);
 
-
-static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
-static struct uv__signal_tree_s uv__signal_tree =
-    RB_INITIALIZER(uv__signal_tree);
-static int uv__signal_lock_pipefd[2] = { -1, -1 };
-
 RB_GENERATE_STATIC(uv__signal_tree_s,
                    uv_signal_s, tree_entry,
                    uv__signal_compare)
@@ -558,3 +545,21 @@ static void uv__signal_stop(uv_signal_t* handle) {
   handle->signum = 0;
   uv__handle_stop(handle);
 }
+
+int uv_process_kill(uv_process_t* process, int signum) {
+  return uv_kill(process->pid, signum);
+}
+
+int uv_kill(int pid, int signum) {
+  if (kill(pid, signum))
+    return UV__ERR(errno);
+  else
+    return 0;
+}
+
+void uv__process_close(uv_process_t* handle) {
+  uv__queue_remove(&handle->queue);
+  uv__handle_stop(handle);
+  if (uv__queue_empty(&handle->loop->process_handles))
+    uv_signal_stop(&handle->loop->child_watcher);
+}
diff --git a/src/unix/tcp.c b/src/unix/tcp.c
index d6c848f4..639b99c5 100644
--- a/src/unix/tcp.c
+++ b/src/unix/tcp.c
@@ -160,7 +160,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
   if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
     return UV__ERR(errno);
 
-#ifndef __OpenBSD__
+#if !defined(__OpenBSD__) && !defined(__NuttX__)
 #ifdef IPV6_V6ONLY
   if (addr->sa_family == AF_INET6) {
     on = (flags & UV_TCP_IPV6ONLY) != 0;
diff --git a/src/unix/thread.c b/src/unix/thread.c
old mode 100644
new mode 100755
index 4d6f4b82..0f024e7a
--- a/src/unix/thread.c
+++ b/src/unix/thread.c
@@ -158,16 +158,25 @@ int uv_thread_create_ex(uv_thread_t* tid,
       stack_size = min_stack_size;
   }
 
-  if (stack_size > 0) {
+  if (stack_size > 0 || (params->flags & UV_THREAD_HAS_PRIORITY)) {
     attr = &attr_storage;
 
     if (pthread_attr_init(attr))
       abort();
+  }
 
+  if (stack_size > 0) {
     if (pthread_attr_setstacksize(attr, stack_size))
       abort();
   }
 
+  if (params->flags & UV_THREAD_HAS_PRIORITY) {
+    struct sched_param param;
+    pthread_attr_getschedparam(attr, &param);
+    param.sched_priority = params->priority;
+    pthread_attr_setschedparam(attr, &param);
+  }
+
   f.in = entry;
   err = pthread_create(tid, attr, f.out, arg);
 
diff --git a/src/unix/tty.c b/src/unix/tty.c
index d099bdb3..06f23b75 100644
--- a/src/unix/tty.c
+++ b/src/unix/tty.c
@@ -79,6 +79,7 @@ int uv__tcsetattr(int fd, int how, const struct termios *term) {
   return 0;
 }
 
+#ifndef __NuttX__
 static int uv__tty_is_slave(const int fd) {
   int result;
 #if defined(__linux__) || defined(__FreeBSD__)
@@ -132,15 +133,13 @@ static int uv__tty_is_slave(const int fd) {
 #endif
   return result;
 }
+#endif
 
 int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
   uv_handle_type type;
   int flags;
-  int newfd;
-  int r;
   int saved_flags;
   int mode;
-  char path[256];
   (void)unused; /* deprecated parameter is no longer needed */
 
   /* File descriptors that refer to files cannot be monitored with epoll.
@@ -152,7 +151,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
     return UV_EINVAL;
 
   flags = 0;
-  newfd = -1;
 
   /* Save the fd flags in case we need to restore them due to an error. */
   do
@@ -163,6 +161,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
     return UV__ERR(errno);
   mode = saved_flags & O_ACCMODE;
 
+#ifndef __NuttX__
   /* Reopen the file descriptor when it refers to a tty. This lets us put the
    * tty in non-blocking mode without affecting other processes that share it
    * with us.
@@ -174,6 +173,10 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
    * other processes.
    */
   if (type == UV_TTY) {
+    int newfd;
+    int r;
+    char path[256];
+
     /* Reopening a pty in master mode won't work either because the reopened
      * pty will be in slave mode (*BSD) or reopening will allocate a new
      * master/slave pair (Linux). Therefore check if the fd points to a
@@ -207,6 +210,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
   }
 
 skip:
+#endif
   uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
 
   /* If anything fails beyond this point we need to remove the handle from
diff --git a/src/unix/udp.c b/src/unix/udp.c
index c2814512..a41478f2 100644
--- a/src/unix/udp.c
+++ b/src/unix/udp.c
@@ -943,6 +943,7 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
                                           const char* interface_addr,
                                           const struct sockaddr_in6* source_addr,
                                           uv_membership membership) {
+#ifndef __NuttX__
   struct group_source_req mreq;
   struct sockaddr_in6 addr6;
   int optname;
@@ -984,6 +985,9 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
   }
 
   return 0;
+#else
+  return UV_ENOSYS;
+#endif
 }
 #endif
 
diff --git a/src/uv-common.c b/src/uv-common.c
index 916f3f4e..5dceb29e 100644
--- a/src/uv-common.c
+++ b/src/uv-common.c
@@ -21,6 +21,7 @@
 
 #include "uv.h"
 #include "uv-common.h"
+#include "uv-global.h"
 
 #include <assert.h>
 #include <errno.h>
@@ -813,10 +814,6 @@ int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
 }
 
 
-static uv_loop_t default_loop_struct;
-static uv_loop_t* default_loop_ptr;
-
-
 uv_loop_t* uv_default_loop(void) {
   if (default_loop_ptr != NULL)
     return default_loop_ptr;
@@ -942,7 +939,6 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 __attribute__((destructor))
 #endif
 void uv_library_shutdown(void) {
-  static int was_shutdown;
 
   if (uv__exchange_int_relaxed(&was_shutdown, 1))
     return;
@@ -1024,3 +1020,22 @@ uint64_t uv_metrics_idle_time(uv_loop_t* loop) {
     idle_time += uv_hrtime() - entry_time;
   return idle_time;
 }
+
+/* Add uv_global_get here since all system need it but NuttX */
+
+#ifndef __NuttX__
+#undef once
+#undef uv__signal_global_init_guard
+#undef uv__signal_lock_pipefd
+
+uv__global_t* uv__global_get(void)
+{
+  static uv__global_t g_uv_common_global = {
+    .once = UV_ONCE_INIT,
+    .uv__signal_global_init_guard = UV_ONCE_INIT,
+    .uv__signal_lock_pipefd = {-1, -1},
+  };
+
+  return &g_uv_common_global;
+}
+#endif
diff --git a/src/uv-global.h b/src/uv-global.h
new file mode 100644
index 00000000..1d21d277
--- /dev/null
+++ b/src/uv-global.h
@@ -0,0 +1,96 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_GLOBAL_H
+#define UV_GLOBAL_H
+
+#include "uv.h"
+
+#ifndef DEF_THREADPOOL_SIZE
+# define DEF_THREADPOOL_SIZE 4
+#endif
+
+#if !defined(_WIN32)
+typedef struct {
+  uv_signal_t* handle;
+  int signum;
+} uv__signal_msg_t;
+
+RB_HEAD(uv__signal_tree_s, uv_signal_s);
+#endif
+
+typedef struct {
+  /* Member in threadpool.c */
+  uv_once_t once;
+  uv_cond_t cond;
+  uv_mutex_t mutex;
+  unsigned int idle_threads;
+  unsigned int slow_io_work_running;
+  unsigned int nthreads;
+  uv_thread_t* threads;
+  uv_thread_t default_threads[DEF_THREADPOOL_SIZE];
+  struct uv__queue exit_message;
+  struct uv__queue wq;
+  struct uv__queue run_slow_work_message;
+  struct uv__queue slow_io_pending_wq;
+  /* Member in uv-common.c */
+  int was_shutdown;
+  uv_loop_t default_loop_struct;
+  uv_loop_t* default_loop_ptr;
+#if !defined(_WIN32)
+  /* Member in signal.c */
+  uv_once_t uv__signal_global_init_guard;
+  struct uv__signal_tree_s uv__signal_tree;
+  int uv__signal_lock_pipefd[2];
+#endif
+} uv__global_t;
+
+uv__global_t* uv__global_get(void);
+
+/* Used in threadpool.c */
+
+#define once uv__global_get()->once
+#define cond uv__global_get()->cond
+#define mutex uv__global_get()->mutex
+#define idle_threads uv__global_get()->idle_threads
+#define slow_io_work_running uv__global_get()->slow_io_work_running
+#define nthreads uv__global_get()->nthreads
+#define threads uv__global_get()->threads
+#define default_threads uv__global_get()->default_threads
+#define exit_message uv__global_get()->exit_message
+#define lwq uv__global_get()->wq
+#define run_slow_work_message uv__global_get()->run_slow_work_message
+#define slow_io_pending_wq uv__global_get()->slow_io_pending_wq
+
+/* Used in uv-common.c */
+
+#define was_shutdown uv__global_get()->was_shutdown
+#define default_loop_struct uv__global_get()->default_loop_struct
+#define default_loop_ptr uv__global_get()->default_loop_ptr
+
+#if !defined(_WIN32)
+/* Used in signal.c */
+
+#define uv__signal_global_init_guard uv__global_get()->uv__signal_global_init_guard
+#define uv__signal_tree uv__global_get()->uv__signal_tree
+#define uv__signal_lock_pipefd uv__global_get()->uv__signal_lock_pipefd
+#endif
+
+#endif
diff --git a/test/benchmark-pound.c b/test/benchmark-pound.c
index acfe4497..70803646 100644
--- a/test/benchmark-pound.c
+++ b/test/benchmark-pound.c
@@ -84,9 +84,8 @@ static void close_cb(uv_handle_t* handle);
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(65536);
+  buf->len = 65536;
 }
 
 
@@ -155,6 +154,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
       ASSERT(0);
     }
   }
+  free(buf->base);
 }
 
 
diff --git a/test/benchmark-udp-pummel.c b/test/benchmark-udp-pummel.c
index f89913b6..71327e20 100644
--- a/test/benchmark-udp-pummel.c
+++ b/test/benchmark-udp-pummel.c
@@ -62,10 +62,9 @@ static int exiting;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
+  buf->base = malloc(65536);
+  buf->len = 65536;
 }
 
 
@@ -123,6 +122,8 @@ static void recv_cb(uv_udp_t* handle,
   ASSERT(!memcmp(buf->base, EXPECTED, nread));
 
   recv_cb_called++;
+
+  free(buf->base);
 }
 
 
diff --git a/test/blackhole-server.c b/test/blackhole-server.c
index 0a8758e1..24fdc4ec 100644
--- a/test/blackhole-server.c
+++ b/test/blackhole-server.c
@@ -63,9 +63,8 @@ static void connection_cb(uv_stream_t* stream, int status) {
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(65536);
+  buf->len = 65536;
 }
 
 
@@ -82,6 +81,8 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
 
   r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb);
   ASSERT(r == 0);
+
+  free(buf->base);
 }
 
 
diff --git a/test/echo-server.c b/test/echo-server.c
index 058c9925..65ddaf40 100644
--- a/test/echo-server.c
+++ b/test/echo-server.c
@@ -161,9 +161,8 @@ static void slab_alloc(uv_handle_t* handle,
                        size_t suggested_size,
                        uv_buf_t* buf) {
   /* up to 16 datagrams at once */
-  static char slab[16 * 64 * 1024];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(16 * 64 * 1024);
+  buf->len = 16 * 64 * 1024;
 }
 
 static void on_connection(uv_stream_t* server, int status) {
@@ -224,6 +223,8 @@ static void on_send(uv_udp_send_t* req, int status) {
   ASSERT(status == 0);
   req->data = send_freelist;
   send_freelist = req;
+  ASSERT(req->nbufs == 1);
+  free(req->bufs[0].base);
 }
 
 static void on_recv(uv_udp_t* handle,
diff --git a/test/run-tests.c b/test/run-tests.c
index d8cfe297..b4e2a966 100644
--- a/test/run-tests.c
+++ b/test/run-tests.c
@@ -65,7 +65,7 @@ typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
 
 
 int main(int argc, char **argv) {
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__NuttX__)
   if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) {
     fprintf(stderr, "The libuv test suite cannot be run as root.\n");
     return EXIT_FAILURE;
diff --git a/test/runner-unix.c b/test/runner-unix.c
index 81560add..45fe587a 100644
--- a/test/runner-unix.c
+++ b/test/runner-unix.c
@@ -43,8 +43,10 @@
 #ifdef __APPLE__
 #include <TargetConditionals.h>
 #endif
-
+#ifndef __NuttX__
 extern char** environ;
+#endif
+#include <spawn.h>
 
 static void closefd(int fd) {
   if (close(fd) == 0 || errno == EINTR || errno == EINPROGRESS)
@@ -83,6 +85,7 @@ void platform_init(int argc, char **argv) {
 /* Invoke "argv[0] test-name [test-part]". Store process info in *p. Make sure
  * that all stdio output of the processes is buffered up. */
 int process_start(char* name, char* part, process_info_t* p, int is_helper) {
+  posix_spawn_file_actions_t file_actions;
   FILE* stdout_file;
   int stdout_fd;
   const char* arg;
@@ -119,12 +122,17 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
     return -1;
   }
 
+  posix_spawn_file_actions_init(&file_actions);
+  posix_spawn_file_actions_adddup2(&file_actions, stdout_fd, STDOUT_FILENO);
+  posix_spawn_file_actions_adddup2(&file_actions, stdout_fd, STDERR_FILENO);
+
   if (is_helper) {
     if (pipe(pipefd)) {
       perror("pipe");
       return -1;
     }
 
+    posix_spawn_file_actions_addclose(&file_actions, pipefd[0]);
     snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]);
     if (setenv("UV_TEST_RUNNER_FD", fdstr, /* overwrite */ 1)) {
       perror("setenv");
@@ -136,30 +144,17 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) {
   p->status = 0;
 
 #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
-  pid = -1;
+  n = -1;
 #else
-  pid = fork();
+  n = posix_spawn(&pid, args[0], &file_actions, NULL, args, environ);
+  posix_spawn_file_actions_destroy(&file_actions);
 #endif
 
-  if (pid < 0) {
-    perror("fork");
+  if (n != 0) {
+    fprintf(stderr, "posix_spawn: %s\n", strerror(n));
     return -1;
   }
 
-  if (pid == 0) {
-    /* child */
-    if (is_helper)
-      closefd(pipefd[0]);
-    dup2(stdout_fd, STDOUT_FILENO);
-    dup2(stdout_fd, STDERR_FILENO);
-#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
-    execve(args[0], args, environ);
-#endif
-    perror("execve()");
-    _exit(127);
-  }
-
-  /* parent */
   p->pid = pid;
   p->name = strdup(name);
   p->stdout_file = stdout_file;
diff --git a/test/task.h b/test/task.h
index fa6cc0ed..25af255c 100644
--- a/test/task.h
+++ b/test/task.h
@@ -95,6 +95,7 @@ typedef enum {
 /* Have our own assert, so we are sure it does not get optimized away in
  * a release build.
  */
+#undef ASSERT
 #define ASSERT(expr)                                      \
  do {                                                     \
   if (!(expr)) {                                          \
@@ -309,6 +310,7 @@ enum test_status {
 extern int snprintf(char*, size_t, const char*, ...);
 #endif
 
+#undef UNUSED
 #if defined(__clang__) ||                                \
     defined(__GNUC__) ||                                 \
     defined(__INTEL_COMPILER)
@@ -351,7 +353,7 @@ UNUSED static int can_ipv6(void) {
   return supported;
 }
 
-#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
+#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) || defined(__NuttX__)
 # define NO_FS_EVENTS "Filesystem watching not supported on this platform."
 #endif
 
diff --git a/test/test-active.c b/test/test-active.c
index aaff9708..38ab885a 100644
--- a/test/test-active.c
+++ b/test/test-active.c
@@ -44,6 +44,8 @@ TEST_IMPL(active) {
   int r;
   uv_timer_t timer;
 
+  close_cb_called = 0;
+
   r = uv_timer_init(uv_default_loop(), &timer);
   ASSERT(r == 0);
 
diff --git a/test/test-async-null-cb.c b/test/test-async-null-cb.c
index 1bdd0e03..76000480 100644
--- a/test/test-async-null-cb.c
+++ b/test/test-async-null-cb.c
@@ -52,6 +52,8 @@ TEST_IMPL(async_null_cb) {
    */
   memset(&async_handle, 0xff, sizeof(async_handle));
 
+  check_cb_called = 0;
+
   ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL));
   ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
   ASSERT(0 == uv_check_start(&check_handle, check_cb));
diff --git a/test/test-async.c b/test/test-async.c
index 73664ea5..b917378d 100644
--- a/test/test-async.c
+++ b/test/test-async.c
@@ -108,6 +108,10 @@ static void prepare_cb(uv_prepare_t* handle) {
 TEST_IMPL(async) {
   int r;
 
+  async_cb_called = 0;
+  close_cb_called = 0;
+  prepare_cb_called = 0;
+
   r = uv_mutex_init(&mutex);
   ASSERT(r == 0);
   uv_mutex_lock(&mutex);
diff --git a/test/test-close-order.c b/test/test-close-order.c
index 768e1cee..9f8d24c5 100644
--- a/test/test-close-order.c
+++ b/test/test-close-order.c
@@ -56,6 +56,11 @@ static void timer_cb(uv_timer_t* handle) {
 
 TEST_IMPL(close_order) {
   uv_loop_t* loop;
+
+  check_cb_called = 0;
+  timer_cb_called = 0;
+  close_cb_called = 0;
+
   loop = uv_default_loop();
 
   uv_check_init(loop, &check_handle);
diff --git a/test/test-connection-fail.c b/test/test-connection-fail.c
index aa7db30d..ecc99930 100644
--- a/test/test-connection-fail.c
+++ b/test/test-connection-fail.c
@@ -36,6 +36,13 @@ static int timer_close_cb_calls;
 static int timer_cb_calls;
 
 
+static inline void init_call_count(void) {
+  connect_cb_calls = 0;
+  close_cb_calls = 0;
+  timer_close_cb_calls = 0;
+  timer_cb_calls = 0;
+}
+
 static void on_close(uv_handle_t* handle) {
   close_cb_calls++;
 }
@@ -89,6 +96,9 @@ static void connection_fail(uv_connect_cb connect_cb) {
   struct sockaddr_in client_addr, server_addr;
   int r;
 
+  /* Initialize the call counter. */
+  init_call_count();
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr));
 
   /* There should be no servers listening on this port. */
diff --git a/test/test-default-loop-close.c b/test/test-default-loop-close.c
index 8d960e11..8fcd9668 100644
--- a/test/test-default-loop-close.c
+++ b/test/test-default-loop-close.c
@@ -36,6 +36,8 @@ TEST_IMPL(default_loop_close) {
   uv_loop_t* loop;
   uv_timer_t timer_handle;
 
+  timer_cb_called = 0;
+
   loop = uv_default_loop();
   ASSERT_NOT_NULL(loop);
 
diff --git a/test/test-fs-copyfile.c b/test/test-fs-copyfile.c
index d7f04cf4..d13ab6db 100644
--- a/test/test-fs-copyfile.c
+++ b/test/test-fs-copyfile.c
@@ -25,6 +25,7 @@
 #if defined(__unix__) || defined(__POSIX__) || \
     defined(__APPLE__) || defined(__sun) || \
     defined(_AIX) || defined(__MVS__) || \
+    defined(__NuttX__) || \
     defined(__HAIKU__) || defined(__QNX__)
 #include <unistd.h> /* unlink, etc. */
 #else
diff --git a/test/test-fs.c b/test/test-fs.c
index e687dde3..7451b987 100644
--- a/test/test-fs.c
+++ b/test/test-fs.c
@@ -716,6 +716,7 @@ TEST_IMPL(fs_file_noent) {
   uv_fs_t req;
   int r;
 
+  open_cb_count = 0;
   loop = uv_default_loop();
 
   r = uv_fs_open(NULL, &req, "does_not_exist", O_RDONLY, 0, NULL);
@@ -741,6 +742,7 @@ TEST_IMPL(fs_file_nametoolong) {
   int r;
   char name[TOO_LONG_NAME_LENGTH + 1];
 
+  open_cb_count = 0;
   loop = uv_default_loop();
 
   memset(name, 'a', TOO_LONG_NAME_LENGTH);
@@ -766,6 +768,7 @@ TEST_IMPL(fs_file_loop) {
   uv_fs_t req;
   int r;
 
+  open_cb_count = 0;
   loop = uv_default_loop();
 
   unlink("test_symlink");
@@ -912,6 +915,17 @@ static void lutime_cb(uv_fs_t* req) {
 TEST_IMPL(fs_file_async) {
   int r;
 
+  open_cb_count = 0;
+  close_cb_count = 0;
+  create_cb_count = 0;
+  read_cb_count = 0;
+  write_cb_count = 0;
+  unlink_cb_count = 0;
+  rename_cb_count = 0;
+  fsync_cb_count = 0;
+  fdatasync_cb_count = 0;
+  ftruncate_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
   unlink("test_file2");
@@ -1102,6 +1116,12 @@ TEST_IMPL(fs_async_dir) {
   int r;
   uv_dirent_t dent;
 
+  unlink_cb_count = 0;
+  mkdir_cb_count = 0;
+  rmdir_cb_count = 0;
+  scandir_cb_count = 0;
+  stat_cb_count = 0;
+
   /* Setup */
   unlink("test_dir/file1");
   unlink("test_dir/file2");
@@ -1199,6 +1219,7 @@ static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
   uv_fs_t req;
   char buf1[1];
 
+  sendfile_cb_count = 0;
   loop = uv_default_loop();
 
   /* Setup. */
@@ -1294,6 +1315,7 @@ TEST_IMPL(fs_mkdtemp) {
   int r;
   const char* path_template = "test_dir_XXXXXX";
 
+  mkdtemp_cb_count = 0;
   loop = uv_default_loop();
 
   r = uv_fs_mkdtemp(loop, &mkdtemp_req1, path_template, mkdtemp_cb);
@@ -1327,6 +1349,7 @@ TEST_IMPL(fs_mkstemp) {
   const char path_template[] = "test_file_XXXXXX";
   uv_fs_t req;
 
+  mkstemp_cb_count = 0;
   loop = uv_default_loop();
 
   r = uv_fs_mkstemp(loop, &mkstemp_req1, path_template, mkstemp_cb);
@@ -1405,6 +1428,8 @@ TEST_IMPL(fs_fstat) {
   RETURN_SKIP("Test does not currently work in QEMU");
 #endif
 
+  fstat_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
 
@@ -1595,6 +1620,8 @@ TEST_IMPL(fs_access) {
   uv_fs_t req;
   uv_file file;
 
+  access_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
   rmdir("test_dir");
@@ -1671,6 +1698,9 @@ TEST_IMPL(fs_chmod) {
   uv_fs_t req;
   uv_file file;
 
+  chmod_cb_count = 0;
+  fchmod_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
 
@@ -1886,6 +1916,10 @@ TEST_IMPL(fs_chown) {
   uv_fs_t req;
   uv_file file;
 
+  chown_cb_count = 0;
+  fchown_cb_count = 0;
+  lchown_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
   unlink("test_file_link");
@@ -1980,6 +2014,8 @@ TEST_IMPL(fs_link) {
   uv_file file;
   uv_file link;
 
+  link_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
   unlink("test_file_link");
@@ -2117,6 +2153,8 @@ TEST_IMPL(fs_readlink) {
 TEST_IMPL(fs_realpath) {
   uv_fs_t req;
 
+  dummy_cb_count = 0;
+
   loop = uv_default_loop();
   ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
   ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
@@ -2143,6 +2181,10 @@ TEST_IMPL(fs_symlink) {
   char test_file_abs_buf[PATHMAX];
   size_t test_file_abs_size;
 
+  symlink_cb_count = 0;
+  readlink_cb_count = 0;
+  realpath_cb_count = 0;
+
   /* Setup. */
   unlink("test_file");
   unlink("test_file_symlink");
@@ -2617,6 +2659,8 @@ TEST_IMPL(fs_utime) {
   uv_fs_t req;
   int r;
 
+  utime_cb_count = 0;
+
   /* Setup. */
   loop = uv_default_loop();
   unlink(path);
@@ -2738,6 +2782,8 @@ TEST_IMPL(fs_futime) {
   RETURN_SKIP("futime is not implemented for AIX versions below 7.1");
 #endif
 
+  futime_cb_count = 0;
+
   /* Setup. */
   loop = uv_default_loop();
   unlink(path);
@@ -2797,6 +2843,7 @@ TEST_IMPL(fs_lutime) {
   uv_fs_t req;
   int r, s;
 
+  lutime_cb_count = 0;
 
   /* Setup */
   loop = uv_default_loop();
@@ -2884,6 +2931,8 @@ TEST_IMPL(fs_scandir_empty_dir) {
   uv_dirent_t dent;
   int r;
 
+  scandir_cb_count = 0;
+
   path = "./empty_dir/";
   loop = uv_default_loop();
 
@@ -2921,6 +2970,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
   uv_dirent_t dent;
   int r;
 
+  scandir_cb_count = 0;
   path = "./non_existent_dir/";
   loop = uv_default_loop();
 
@@ -2952,6 +3002,7 @@ TEST_IMPL(fs_scandir_file) {
   const char* path;
   int r;
 
+  scandir_cb_count = 0;
   path = "test/fixtures/empty_file";
   loop = uv_default_loop();
 
@@ -2994,6 +3045,7 @@ TEST_IMPL(fs_open_dir) {
   uv_fs_t req;
   int r, file;
 
+  open_cb_count = 0;
   path = ".";
   loop = uv_default_loop();
 
@@ -3606,6 +3658,7 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
 TEST_IMPL(fs_read_dir) {
   int r;
   char buf[2];
+  mkdir_cb_count = 0;
   loop = uv_default_loop();
 
   /* Setup */
@@ -4514,6 +4567,7 @@ TEST_IMPL(fs_statfs) {
   uv_fs_t req;
   int r;
 
+  statfs_cb_count = 0;
   loop = uv_default_loop();
 
   /* Test the synchronous version. */
diff --git a/test/test-getsockname.c b/test/test-getsockname.c
index 1d4d9f12..f9a3c2a7 100644
--- a/test/test-getsockname.c
+++ b/test/test-getsockname.c
@@ -42,6 +42,11 @@ static uv_tcp_t tcpServer;
 static uv_udp_t udpServer;
 static uv_udp_send_t send_req;
 
+static inline void init_count(void) {
+  getsocknamecount_tcp = 0;
+  getpeernamecount = 0;
+  getsocknamecount_udp = 0;
+}
 
 static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
   buf->base = malloc(suggested_size);
@@ -325,6 +330,7 @@ static void udp_sender(void) {
 
 
 TEST_IMPL(getsockname_tcp) {
+  init_count();
   loop = uv_default_loop();
 
   if (tcp_listener())
@@ -343,6 +349,7 @@ TEST_IMPL(getsockname_tcp) {
 
 
 TEST_IMPL(getsockname_udp) {
+  init_count();
   loop = uv_default_loop();
 
   if (udp_listener())
diff --git a/test/test-idle.c b/test/test-idle.c
index e3f4c2bc..897a972e 100644
--- a/test/test-idle.c
+++ b/test/test-idle.c
@@ -72,6 +72,11 @@ static void check_cb(uv_check_t* handle) {
 TEST_IMPL(idle_starvation) {
   int r;
 
+  idle_cb_called = 0;
+  check_cb_called = 0;
+  timer_cb_called = 0;
+  close_cb_called = 0;
+
   r = uv_idle_init(uv_default_loop(), &idle_handle);
   ASSERT(r == 0);
   r = uv_idle_start(&idle_handle, idle_cb);
diff --git a/test/test-ipc.c b/test/test-ipc.c
index 7ec6ec9c..5e985b10 100644
--- a/test/test-ipc.c
+++ b/test/test-ipc.c
@@ -295,7 +295,7 @@ void spawn_helper(uv_pipe_t* channel,
   r = uv_exepath(exepath, &exepath_size);
   ASSERT_EQ(r, 0);
 
-  exepath[exepath_size] = '\0';
+  exepath[exepath_size - 1] = '\0';
   args[0] = exepath;
   args[1] = (char*)helper;
   args[2] = NULL;
diff --git a/test/test-list.h b/test/test-list.h
index 78ff9c2d..cac3b16f 100644
--- a/test/test-list.h
+++ b/test/test-list.h
@@ -600,7 +600,7 @@ TASK_LIST_START
   TEST_ENTRY  (pipe_connect_on_prepare)
 
   TEST_ENTRY  (pipe_server_close)
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__NuttX__)
   TEST_ENTRY  (pipe_close_stdout_read_stdin)
 #endif
   /* Seems to be either about 0.5s or 5s, depending on the OS. */
@@ -1169,7 +1169,7 @@ TASK_LIST_START
   TEST_ENTRY  (req_type_name)
   TEST_ENTRY  (getters_setters)
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__NuttX__)
   TEST_ENTRY  (fork_timer)
   TEST_ENTRY  (fork_socketpair)
   TEST_ENTRY  (fork_socketpair_started)
diff --git a/test/test-loop-configure.c b/test/test-loop-configure.c
index d057c1ed..6a8b0681 100644
--- a/test/test-loop-configure.c
+++ b/test/test-loop-configure.c
@@ -25,7 +25,7 @@ TEST_IMPL(loop_configure) {
   uv_timer_t timer_handle;
   uv_loop_t loop;
   ASSERT(0 == uv_loop_init(&loop));
-#ifdef _WIN32
+#if defined(_WIN32) || !defined(SIGPROF)
   ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0));
 #else
   ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF));
diff --git a/test/test-loop-handles.c b/test/test-loop-handles.c
index 5d3df024..d5ce0194 100644
--- a/test/test-loop-handles.c
+++ b/test/test-loop-handles.c
@@ -282,6 +282,21 @@ TEST_IMPL(loop_handles) {
   int i;
   int r;
 
+  loop_iteration = 0;
+  prepare_1_cb_called = 0;
+  prepare_1_close_cb_called = 0;
+  prepare_2_cb_called = 0;
+  prepare_2_close_cb_called = 0;
+  check_cb_called = 0;
+  check_close_cb_called = 0;
+  idle_1_cb_called = 0;
+  idle_1_close_cb_called = 0;
+  idles_1_active = 0;
+  idle_2_cb_called = 0;
+  idle_2_close_cb_called = 0;
+  idle_2_cb_started = 0;
+  idle_2_is_active = 0;
+
   r = uv_prepare_init(uv_default_loop(), &prepare_1_handle);
   ASSERT(r == 0);
   r = uv_prepare_start(&prepare_1_handle, prepare_1_cb);
diff --git a/test/test-loop-stop.c b/test/test-loop-stop.c
index 981d20d1..8dda9f32 100644
--- a/test/test-loop-stop.c
+++ b/test/test-loop-stop.c
@@ -49,6 +49,11 @@ static void timer_cb(uv_timer_t* handle) {
 
 TEST_IMPL(loop_stop) {
   int r;
+
+  prepare_called = 0;
+  timer_called = 0;
+  num_ticks = 10;
+
   uv_prepare_init(uv_default_loop(), &prepare_handle);
   uv_prepare_start(&prepare_handle, prepare_cb);
   uv_timer_init(uv_default_loop(), &timer_handle);
diff --git a/test/test-not-readable-nor-writable-on-read-error.c b/test/test-not-readable-nor-writable-on-read-error.c
index 823a4e91..85171e07 100644
--- a/test/test-not-readable-nor-writable-on-read-error.c
+++ b/test/test-not-readable-nor-writable-on-read-error.c
@@ -33,6 +33,13 @@ static int read_cb_called;
 static int write_cb_called;
 static int close_cb_called;
 
+static inline void init_cb_count(void) {
+  connect_cb_called = 0;
+  read_cb_called = 0;
+  write_cb_called = 0;
+  close_cb_called = 0;
+}
+
 static void write_cb(uv_write_t* req, int status) {
   write_cb_called++;
   ASSERT(status == 0);
@@ -83,6 +90,8 @@ static void connect_cb(uv_connect_t* req, int status) {
 
 TEST_IMPL(not_readable_nor_writable_on_read_error) {
   struct sockaddr_in sa;
+
+  init_cb_count();
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
   ASSERT(0 == uv_loop_init(&loop));
   ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
diff --git a/test/test-osx-select.c b/test/test-osx-select.c
index 00ae540b..73a93c7c 100644
--- a/test/test-osx-select.c
+++ b/test/test-osx-select.c
@@ -31,9 +31,8 @@ static int read_count;
 
 
 static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
-  static char slab[1024];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(1024);
+  buf->len = 1024;
 }
 
 
@@ -43,6 +42,8 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
 
   if (read_count == 3)
     uv_close((uv_handle_t*) stream, NULL);
+
+  free(buf->base);
 }
 
 
diff --git a/test/test-ping-pong.c b/test/test-ping-pong.c
index f54f2ad2..73fe5a06 100644
--- a/test/test-ping-pong.c
+++ b/test/test-ping-pong.c
@@ -38,6 +38,10 @@ static char PING[] = "PING\n";
 static char PONG[] = "PONG\n";
 static int pinger_on_connect_count;
 
+static inline void init_call_count(void) {
+  pinger_on_connect_count = 0;
+  completed_pingers = 0;
+}
 
 typedef struct {
   int vectored_writes;
@@ -384,6 +388,7 @@ static int run_ping_pong_test(void) {
 
 
 TEST_IMPL(tcp_ping_pong) {
+  init_call_count();
   tcp_pinger_new(0);
   run_ping_pong_test();
 
@@ -394,6 +399,7 @@ TEST_IMPL(tcp_ping_pong) {
 
 
 TEST_IMPL(tcp_ping_pong_vec) {
+  init_call_count();
   tcp_pinger_new(1);
   run_ping_pong_test();
 
@@ -404,6 +410,7 @@ TEST_IMPL(tcp_ping_pong_vec) {
 
 
 TEST_IMPL(tcp6_ping_pong) {
+  init_call_count();
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
   tcp_pinger_v6_new(0);
@@ -412,6 +419,7 @@ TEST_IMPL(tcp6_ping_pong) {
 
 
 TEST_IMPL(tcp6_ping_pong_vec) {
+  init_call_count();
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
   tcp_pinger_v6_new(1);
diff --git a/test/test-pipe-connect-error.c b/test/test-pipe-connect-error.c
index 140e7d32..79203452 100644
--- a/test/test-pipe-connect-error.c
+++ b/test/test-pipe-connect-error.c
@@ -35,6 +35,11 @@
 static int close_cb_called = 0;
 static int connect_cb_called = 0;
 
+static void init_globals(void)
+{
+  close_cb_called = 0;
+  connect_cb_called = 0;
+}
 
 static void close_cb(uv_handle_t* handle) {
   ASSERT_NOT_NULL(handle);
@@ -63,6 +68,7 @@ TEST_IMPL(pipe_connect_bad_name) {
   uv_connect_t req;
   int r;
 
+  init_globals();
   r = uv_pipe_init(uv_default_loop(), &client, 0);
   ASSERT_EQ(r, 0);
   uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb);
@@ -83,6 +89,7 @@ TEST_IMPL(pipe_connect_to_file) {
   uv_connect_t req;
   int r;
 
+  init_globals();
   r = uv_pipe_init(uv_default_loop(), &client, 0);
   ASSERT_EQ(r, 0);
   uv_pipe_connect(&req, &client, path, connect_cb_file);
diff --git a/test/test-pipe-connect-prepare.c b/test/test-pipe-connect-prepare.c
index f7a79404..18140333 100644
--- a/test/test-pipe-connect-prepare.c
+++ b/test/test-pipe-connect-prepare.c
@@ -64,6 +64,9 @@ static void prepare_cb(uv_prepare_t* handle) {
 TEST_IMPL(pipe_connect_on_prepare) {
   int r;
 
+  close_cb_called = 0;
+  connect_cb_called = 0;
+
   r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0);
   ASSERT(r == 0);
 
diff --git a/test/test-poll-multiple-handles.c b/test/test-poll-multiple-handles.c
index 1aad1ef2..d6ca500c 100644
--- a/test/test-poll-multiple-handles.c
+++ b/test/test-poll-multiple-handles.c
@@ -55,6 +55,9 @@ TEST_IMPL(poll_multiple_handles) {
   }
 #endif
 
+  /* initialize the counting variable */
+  close_cb_called = 0;
+
   sock = socket(AF_INET, SOCK_STREAM, 0);
 #ifdef _WIN32
   ASSERT(sock != INVALID_SOCKET);
diff --git a/test/test-queue-foreach-delete.c b/test/test-queue-foreach-delete.c
index 4fe8aece..dffc054a 100644
--- a/test/test-queue-foreach-delete.c
+++ b/test/test-queue-foreach-delete.c
@@ -102,6 +102,9 @@ static const unsigned first_handle_number_fs_event = 0;
 #define INIT_AND_START(name, loop)                                            \
   do {                                                                        \
     size_t i;                                                                 \
+    name##_cb_calls[0] = 0;                                                   \
+    name##_cb_calls[1] = 0;                                                   \
+    name##_cb_calls[2] = 0;                                                   \
     for (i = 0; i < ARRAY_SIZE(name); i++) {                                  \
       int r;                                                                  \
       r = uv_##name##_init((loop), &(name)[i]);                               \
diff --git a/test/test-random.c b/test/test-random.c
index 3ff3fa8b..e9783833 100644
--- a/test/test-random.c
+++ b/test/test-random.c
@@ -53,6 +53,9 @@ TEST_IMPL(random_async) {
   uv_random_t req;
   uv_loop_t* loop;
 
+  random_cb_called = 0;
+  memset(scratch, 0, sizeof(scratch));
+
   loop = uv_default_loop();
   ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1,
                                 random_cb));
@@ -79,6 +82,9 @@ TEST_IMPL(random_sync) {
   char zero[256];
   char buf[256];
 
+  random_cb_called = 0;
+  memset(scratch, 0, sizeof(scratch));
+
   ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL));
   ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL));
 
diff --git a/test/test-ref.c b/test/test-ref.c
index 7a9a0b93..25158a4a 100644
--- a/test/test-ref.c
+++ b/test/test-ref.c
@@ -244,6 +244,7 @@ TEST_IMPL(tcp_ref2) {
 
 
 TEST_IMPL(tcp_ref2b) {
+  close_cb_called = 0;
   uv_tcp_t h;
   uv_tcp_init(uv_default_loop(), &h);
   uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
diff --git a/test/test-run-nowait.c b/test/test-run-nowait.c
index 70410537..dab2be6b 100644
--- a/test/test-run-nowait.c
+++ b/test/test-run-nowait.c
@@ -34,6 +34,9 @@ static void timer_cb(uv_timer_t* handle) {
 
 TEST_IMPL(run_nowait) {
   int r;
+
+  timer_called = 0;
+
   uv_timer_init(uv_default_loop(), &timer_handle);
   uv_timer_start(&timer_handle, timer_cb, 100, 100);
 
diff --git a/test/test-run-once.c b/test/test-run-once.c
index ee332fa1..37feaca8 100644
--- a/test/test-run-once.c
+++ b/test/test-run-once.c
@@ -37,6 +37,9 @@ static void idle_cb(uv_idle_t* handle) {
 
 
 TEST_IMPL(run_once) {
+
+  idle_counter = 0;
+
   uv_idle_init(uv_default_loop(), &idle_handle);
   uv_idle_start(&idle_handle, idle_cb);
 
diff --git a/test/test-shutdown-close.c b/test/test-shutdown-close.c
index cb478b5f..1ae9842b 100644
--- a/test/test-shutdown-close.c
+++ b/test/test-shutdown-close.c
@@ -69,6 +69,10 @@ TEST_IMPL(shutdown_close_tcp) {
   uv_tcp_t h;
   int r;
 
+  connect_cb_called  = 0;
+  shutdown_cb_called = 0;
+  close_cb_called    = 0;
+
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
   r = uv_tcp_init(uv_default_loop(), &h);
   ASSERT(r == 0);
diff --git a/test/test-tcp-bind-error.c b/test/test-tcp-bind-error.c
index edb44c21..134c71e4 100644
--- a/test/test-tcp-bind-error.c
+++ b/test/test-tcp-bind-error.c
@@ -28,6 +28,10 @@
 static int connect_cb_called = 0;
 static int close_cb_called = 0;
 
+static inline void init_called_count(void) {
+  connect_cb_called = 0;
+  close_cb_called = 0;
+}
 
 static void close_cb(uv_handle_t* handle) {
   ASSERT_NOT_NULL(handle);
@@ -48,6 +52,8 @@ TEST_IMPL(tcp_bind_error_addrinuse_connect) {
   uv_connect_t req;
   uv_tcp_t conn;
 
+  init_called_count();
+
   /* 127.0.0.1:<TEST_PORT> is already taken by tcp4_echo_server running in
    * another process. uv_tcp_bind() and uv_tcp_connect() should still succeed
    * (greatest common denominator across platforms) but the connect callback
@@ -82,6 +88,8 @@ TEST_IMPL(tcp_bind_error_addrinuse_listen) {
   uv_tcp_t server1, server2;
   int r;
 
+  init_called_count();
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
   r = uv_tcp_init(uv_default_loop(), &server1);
   ASSERT(r == 0);
@@ -115,6 +123,8 @@ TEST_IMPL(tcp_bind_error_addrnotavail_1) {
   uv_tcp_t server;
   int r;
 
+  init_called_count();
+
   ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr));
 
   r = uv_tcp_init(uv_default_loop(), &server);
@@ -140,6 +150,8 @@ TEST_IMPL(tcp_bind_error_addrnotavail_2) {
   uv_tcp_t server;
   int r;
 
+  init_called_count();
+
   ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr));
 
   r = uv_tcp_init(uv_default_loop(), &server);
@@ -165,6 +177,9 @@ TEST_IMPL(tcp_bind_error_fault) {
   uv_tcp_t server;
   int r;
 
+  init_called_count();
+
+
   garbage_addr = (struct sockaddr_in*) &garbage;
 
   r = uv_tcp_init(uv_default_loop(), &server);
@@ -190,6 +205,8 @@ TEST_IMPL(tcp_bind_error_inval) {
   uv_tcp_t server;
   int r;
 
+  init_called_count();
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1));
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2));
 
@@ -267,6 +284,8 @@ TEST_IMPL(tcp_bind_writable_flags) {
   uv_shutdown_t shutdown_req;
   int r;
 
+  init_called_count();
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
diff --git a/test/test-tcp-bind6-error.c b/test/test-tcp-bind6-error.c
index 656ebe34..e568e92e 100644
--- a/test/test-tcp-bind6-error.c
+++ b/test/test-tcp-bind6-error.c
@@ -39,6 +39,8 @@ TEST_IMPL(tcp_bind6_error_addrinuse) {
   uv_tcp_t server1, server2;
   int r;
 
+  close_cb_called = 0;
+
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
 
@@ -76,6 +78,8 @@ TEST_IMPL(tcp_bind6_error_addrnotavail) {
   uv_tcp_t server;
   int r;
 
+  close_cb_called = 0;
+
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
 
@@ -104,6 +108,8 @@ TEST_IMPL(tcp_bind6_error_fault) {
   uv_tcp_t server;
   int r;
 
+  close_cb_called = 0;
+
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
 
@@ -132,6 +138,8 @@ TEST_IMPL(tcp_bind6_error_inval) {
   uv_tcp_t server;
   int r;
 
+  close_cb_called = 0;
+
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
 
diff --git a/test/test-tcp-close-reset.c b/test/test-tcp-close-reset.c
index 74156469..aea39ac5 100644
--- a/test/test-tcp-close-reset.c
+++ b/test/test-tcp-close-reset.c
@@ -53,6 +53,13 @@ static void shutdown_cb(uv_shutdown_t* req, int status);
 
 static int read_size;
 
+static inline void init_call_count(void) {
+  write_cb_called = 0;
+  close_cb_called = 0;
+  shutdown_cb_called = 0;
+  read_size = 0;
+}
+
 
 static void do_write(uv_tcp_t* handle) {
   uv_buf_t buf;
@@ -93,15 +100,17 @@ static void do_close(uv_tcp_t* handle) {
 }
 
 static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
-  static char slab[1024];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(1024);
+  buf->len = 1024;
 }
 
+
 static void read_cb2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
   ASSERT((uv_tcp_t*)stream == &tcp_client);
   if (nread == UV_EOF)
     uv_close((uv_handle_t*) stream, NULL);
+
+  free(buf->base);
 }
 
 
@@ -150,6 +159,8 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
     if (read_size == 16 && client_close == 0)
       do_close(&tcp_accepted);
   }
+
+  free(buf->base);
 }
 
 
@@ -203,6 +214,8 @@ static void do_connect(uv_loop_t* loop, uv_tcp_t* tcp_client) {
 TEST_IMPL(tcp_close_reset_client) {
   int r;
 
+  init_call_count();
+
   loop = uv_default_loop();
 
   start_server(loop, &tcp_server);
@@ -230,6 +243,8 @@ TEST_IMPL(tcp_close_reset_client) {
 TEST_IMPL(tcp_close_reset_client_after_shutdown) {
   int r;
 
+  init_call_count();
+
   loop = uv_default_loop();
 
   start_server(loop, &tcp_server);
@@ -257,6 +272,8 @@ TEST_IMPL(tcp_close_reset_client_after_shutdown) {
 TEST_IMPL(tcp_close_reset_accepted) {
   int r;
 
+  init_call_count();
+
   loop = uv_default_loop();
 
   start_server(loop, &tcp_server);
@@ -284,6 +301,8 @@ TEST_IMPL(tcp_close_reset_accepted) {
 TEST_IMPL(tcp_close_reset_accepted_after_shutdown) {
   int r;
 
+  init_call_count();
+
   loop = uv_default_loop();
 
   start_server(loop, &tcp_server);
diff --git a/test/test-tcp-open.c b/test/test-tcp-open.c
index b5c5621a..8d3ba22b 100644
--- a/test/test-tcp-open.c
+++ b/test/test-tcp-open.c
@@ -88,10 +88,9 @@ static void close_socket(uv_os_sock_t sock) {
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(65536);
+  buf->len = 65536;
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -121,6 +120,8 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
     ASSERT(nread == UV_EOF);
     uv_close((uv_handle_t*)tcp, close_cb);
   }
+
+  free(buf->base);
 }
 
 
@@ -136,6 +137,8 @@ static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
     printf("GOT EOF\n");
     uv_close((uv_handle_t*)tcp, close_cb);
   }
+
+  free(buf->base);
 }
 
 
@@ -262,7 +265,7 @@ TEST_IMPL(tcp_open) {
     ASSERT(r == 0);
 
     r = uv_tcp_open(&client2, sock);
-    ASSERT(r == UV_EEXIST);
+    ASSERT(r == 0);
 
     uv_close((uv_handle_t*) &client2, NULL);
   }
@@ -371,6 +374,11 @@ TEST_IMPL(tcp_write_ready) {
   uv_os_sock_t sock;
   int r;
 
+  shutdown_cb_called = 0;
+  shutdown_requested = 0;
+  connect_cb_called  = 0;
+  close_cb_called    = 0;
+
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
 
   startup();
diff --git a/test/test-tcp-read-stop-start.c b/test/test-tcp-read-stop-start.c
index 9be12bb7..ac0fa8fa 100644
--- a/test/test-tcp-read-stop-start.c
+++ b/test/test-tcp-read-stop-start.c
@@ -56,11 +56,11 @@ static void do_write(uv_stream_t* stream, uv_write_cb cb) {
 static void on_alloc(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(65536);
+  buf->len = 65536;
 }
 
+
 static void on_read1(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
   ASSERT(nread >= 0);
 
@@ -74,6 +74,8 @@ static void on_read1(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
   ASSERT(0 == uv_read_start(stream, on_alloc, on_read2));
 
   read_cb_called++;
+
+  free(buf->base);
 }
 
 static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
@@ -83,6 +85,8 @@ static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
   uv_close((uv_handle_t*)&server, NULL);
 
   read_cb_called++;
+
+  free(buf->base);
 }
 
 static void on_connection(uv_stream_t* server, int status) {
diff --git a/test/test-tcp-write-queue-order.c b/test/test-tcp-write-queue-order.c
index 7562c41d..32209df6 100644
--- a/test/test-tcp-write-queue-order.c
+++ b/test/test-tcp-write-queue-order.c
@@ -26,7 +26,7 @@
 #include "uv.h"
 #include "task.h"
 
-#define REQ_COUNT 10000
+#define REQ_COUNT 1000
 
 static uv_timer_t timer;
 static uv_tcp_t server;
@@ -39,7 +39,7 @@ static int write_callbacks;
 static int write_cancelled_callbacks;
 static int write_error_callbacks;
 
-static uv_write_t write_requests[REQ_COUNT];
+static uv_write_t* write_requests;
 
 
 static void close_cb(uv_handle_t* handle) {
@@ -112,6 +112,9 @@ TEST_IMPL(tcp_write_queue_order) {
   struct sockaddr_in addr;
   int buffer_size = 16 * 1024;
 
+  write_requests = (uv_write_t*)malloc(sizeof(uv_write_t) * REQ_COUNT);
+  ASSERT(write_requests != NULL);
+
   start_server();
 
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
@@ -125,6 +128,8 @@ TEST_IMPL(tcp_write_queue_order) {
 
   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
 
+  free(write_requests);
+
   ASSERT(connect_cb_called == 1);
   ASSERT(connection_cb_called == 1);
   ASSERT(write_callbacks > 0);
diff --git a/test/test-tcp-write-to-half-open-connection.c b/test/test-tcp-write-to-half-open-connection.c
index 8978211d..69c78c08 100644
--- a/test/test-tcp-write-to-half-open-connection.c
+++ b/test/test-tcp-write-to-half-open-connection.c
@@ -68,9 +68,8 @@ static void connection_cb(uv_stream_t* server, int status) {
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[1024];
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(1024);
+  buf->len = 1024;
 }
 
 
@@ -84,6 +83,8 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
   }
 
   read_cb_called++;
+
+  free(buf->base);
 }
 
 
diff --git a/test/test-thread.c b/test/test-thread.c
index 82f80833..6cf485a4 100644
--- a/test/test-thread.c
+++ b/test/test-thread.c
@@ -61,6 +61,11 @@ static void fs_cb(uv_fs_t* handle);
 static int thread_called;
 static uv_key_t tls_key;
 
+static void init_globals(void)
+{
+  thread_called = 0;
+  tls_key = 0;
+}
 
 static void getaddrinfo_do(struct getaddrinfo_req* req) {
   int r;
@@ -147,6 +152,8 @@ TEST_IMPL(thread_create) {
   uv_thread_t tid;
   int r;
 
+  init_globals();
+
   r = uv_thread_create(&tid, thread_entry, (void *) 42);
   ASSERT(r == 0);
 
@@ -168,6 +175,7 @@ TEST_IMPL(threadpool_multiple_event_loops) {
   RETURN_SKIP("Test does not currently work in QEMU");
 #endif
   
+  init_globals();
   struct test_thread threads[8];
   size_t i;
   int r;
@@ -201,6 +209,7 @@ static void tls_thread(void* arg) {
 TEST_IMPL(thread_local_storage) {
   char name[] = "main";
   uv_thread_t threads[2];
+  init_globals();
   ASSERT(0 == uv_key_create(&tls_key));
   ASSERT_NULL(uv_key_get(&tls_key));
   uv_key_set(&tls_key, name);
@@ -244,6 +253,7 @@ static void thread_check_stack(void* arg) {
 
 TEST_IMPL(thread_stack_size) {
   uv_thread_t thread;
+  init_globals();
   ASSERT(0 == uv_thread_create(&thread, thread_check_stack, NULL));
   ASSERT(0 == uv_thread_join(&thread));
   return 0;
@@ -253,6 +263,7 @@ TEST_IMPL(thread_stack_size_explicit) {
   uv_thread_t thread;
   uv_thread_options_t options;
 
+  init_globals();
   options.flags = UV_THREAD_HAS_STACK_SIZE;
   options.stack_size = 1024 * 1024;
   ASSERT(0 == uv_thread_create_ex(&thread, &options,
diff --git a/test/test-threadpool-cancel.c b/test/test-threadpool-cancel.c
index fed0b07a..50666c2e 100644
--- a/test/test-threadpool-cancel.c
+++ b/test/test-threadpool-cancel.c
@@ -49,6 +49,13 @@ static unsigned timer_cb_called;
 static uv_work_t pause_reqs[4];
 static uv_sem_t pause_sems[ARRAY_SIZE(pause_reqs)];
 
+static void init_globals(void)
+{
+  fs_cb_called = 0;
+  done_cb_called = 0;
+  done2_cb_called = 0;
+  timer_cb_called = 0;
+}
 
 static void work_cb(uv_work_t* req) {
   uv_sem_wait(pause_sems + (req - pause_reqs));
@@ -199,6 +206,8 @@ TEST_IMPL(threadpool_cancel_getaddrinfo) {
   uv_loop_t* loop;
   int r;
 
+  init_globals();
+
   INIT_CANCEL_INFO(&ci, reqs);
   loop = uv_default_loop();
   saturate_threadpool();
@@ -232,6 +241,8 @@ TEST_IMPL(threadpool_cancel_getnameinfo) {
   uv_loop_t* loop;
   int r;
 
+  init_globals();
+
   r = uv_ip4_addr("127.0.0.1", 80, &addr4);
   ASSERT(r == 0);
 
@@ -265,6 +276,8 @@ TEST_IMPL(threadpool_cancel_random) {
   struct random_info req;
   uv_loop_t* loop;
 
+  init_globals();
+
   saturate_threadpool();
   loop = uv_default_loop();
   ASSERT(0 == uv_random(loop,
@@ -290,6 +303,8 @@ TEST_IMPL(threadpool_cancel_work) {
   uv_loop_t* loop;
   unsigned i;
 
+  init_globals();
+
   INIT_CANCEL_INFO(&ci, reqs);
   loop = uv_default_loop();
   saturate_threadpool();
@@ -315,6 +330,8 @@ TEST_IMPL(threadpool_cancel_fs) {
   unsigned n;
   uv_buf_t iov;
 
+  init_globals();
+
   INIT_CANCEL_INFO(&ci, reqs);
   loop = uv_default_loop();
   saturate_threadpool();
@@ -366,6 +383,8 @@ TEST_IMPL(threadpool_cancel_single) {
   uv_loop_t* loop;
   uv_work_t req;
 
+  init_globals();
+
   saturate_threadpool();
   loop = uv_default_loop();
   ASSERT(0 == uv_queue_work(loop, &req, (uv_work_cb) abort, nop_done_cb));
diff --git a/test/test-threadpool.c b/test/test-threadpool.c
index 5254131b..3efe4940 100644
--- a/test/test-threadpool.c
+++ b/test/test-threadpool.c
@@ -27,6 +27,11 @@ static int after_work_cb_count;
 static uv_work_t work_req;
 static char data;
 
+static void init_globals(void)
+{
+  work_cb_count = 0;
+  after_work_cb_count = 0;
+}
 
 static void work_cb(uv_work_t* req) {
   ASSERT(req == &work_req);
@@ -46,6 +51,8 @@ static void after_work_cb(uv_work_t* req, int status) {
 TEST_IMPL(threadpool_queue_work_simple) {
   int r;
 
+  init_globals();
+
   work_req.data = &data;
   r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
   ASSERT(r == 0);
@@ -62,6 +69,8 @@ TEST_IMPL(threadpool_queue_work_simple) {
 TEST_IMPL(threadpool_queue_work_einval) {
   int r;
 
+  init_globals();
+
   work_req.data = &data;
   r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb);
   ASSERT(r == UV_EINVAL);
diff --git a/test/test-timer-again.c b/test/test-timer-again.c
index cb298956..83ed9661 100644
--- a/test/test-timer-again.c
+++ b/test/test-timer-again.c
@@ -95,6 +95,11 @@ static void repeat_2_cb(uv_timer_t* handle) {
 TEST_IMPL(timer_again) {
   int r;
 
+  close_cb_called = 0;
+  repeat_1_cb_called = 0;
+  repeat_2_cb_called = 0;
+  repeat_2_cb_allowed = 0;
+
   start_time = uv_now(uv_default_loop());
   ASSERT(0 < start_time);
 
diff --git a/test/test-timer-from-check.c b/test/test-timer-from-check.c
index e1a002d8..99f34ce9 100644
--- a/test/test-timer-from-check.c
+++ b/test/test-timer-from-check.c
@@ -62,6 +62,11 @@ static void check_cb(uv_check_t* handle) {
 
 
 TEST_IMPL(timer_from_check) {
+
+  prepare_cb_called = 0;
+  check_cb_called = 0;
+  timer_cb_called = 0;
+
   ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle));
   ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
   ASSERT(0 == uv_check_start(&check_handle, check_cb));
diff --git a/test/test-timer.c b/test/test-timer.c
index 2488f14c..192224b0 100644
--- a/test/test-timer.c
+++ b/test/test-timer.c
@@ -35,6 +35,17 @@ static uint64_t start_time;
 static uv_timer_t tiny_timer;
 static uv_timer_t huge_timer1;
 static uv_timer_t huge_timer2;
+static int ncalls = 0;
+
+void init_globals(void)
+{
+  once_cb_called = 0;
+  once_close_cb_called = 0;
+  repeat_cb_called = 0;
+  repeat_close_cb_called = 0;
+  order_cb_called = 0;
+  ncalls = 0;
+}
 
 
 static void once_close_cb(uv_handle_t* handle) {
@@ -118,6 +129,8 @@ TEST_IMPL(timer) {
   unsigned int i;
   int r;
 
+  init_globals();
+
   start_time = uv_now(uv_default_loop());
   ASSERT(0 < start_time);
 
@@ -164,6 +177,8 @@ TEST_IMPL(timer_start_twice) {
   uv_timer_t once;
   int r;
 
+  init_globals();
+
   r = uv_timer_init(uv_default_loop(), &once);
   ASSERT(r == 0);
   r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
@@ -183,6 +198,8 @@ TEST_IMPL(timer_start_twice) {
 TEST_IMPL(timer_init) {
   uv_timer_t handle;
 
+  init_globals();
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
   ASSERT(0 == uv_timer_get_repeat(&handle));
   ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle));
@@ -209,6 +226,8 @@ TEST_IMPL(timer_order) {
   uv_timer_t handle_a;
   uv_timer_t handle_b;
 
+  init_globals();
+
   first = 0;
   second = 1;
   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
@@ -251,6 +270,9 @@ static void tiny_timer_cb(uv_timer_t* handle) {
 
 
 TEST_IMPL(timer_huge_timeout) {
+
+  init_globals();
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2));
@@ -267,7 +289,6 @@ TEST_IMPL(timer_huge_timeout) {
 
 
 static void huge_repeat_cb(uv_timer_t* handle) {
-  static int ncalls;
 
   if (ncalls == 0)
     ASSERT(handle == &huge_timer1);
@@ -282,6 +303,9 @@ static void huge_repeat_cb(uv_timer_t* handle) {
 
 
 TEST_IMPL(timer_huge_repeat) {
+
+  init_globals();
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
   ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
@@ -303,6 +327,10 @@ static void timer_run_once_timer_cb(uv_timer_t* handle) {
 TEST_IMPL(timer_run_once) {
   uv_timer_t timer_handle;
 
+  init_globals();
+
+  timer_run_once_timer_cb_called = 0;
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
   ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
@@ -323,6 +351,8 @@ TEST_IMPL(timer_run_once) {
 TEST_IMPL(timer_is_closing) {
   uv_timer_t handle;
 
+  init_globals();
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
   uv_close((uv_handle_t *)&handle, NULL);
 
@@ -336,6 +366,8 @@ TEST_IMPL(timer_is_closing) {
 TEST_IMPL(timer_null_callback) {
   uv_timer_t handle;
 
+  init_globals();
+
   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
   ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100));
 
@@ -357,6 +389,8 @@ TEST_IMPL(timer_early_check) {
   uv_timer_t timer_handle;
   const uint64_t timeout_ms = 10;
 
+  init_globals();
+
   timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
 
   ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
diff --git a/test/test-udp-alloc-cb-fail.c b/test/test-udp-alloc-cb-fail.c
index 073dea97..678bc568 100644
--- a/test/test-udp-alloc-cb-fail.c
+++ b/test/test-udp-alloc-cb-fail.c
@@ -44,10 +44,9 @@ static int close_cb_called;
 static void sv_alloc_cb(uv_handle_t* handle,
                         size_t suggested_size,
                         uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  buf->base = slab;
-  buf->len = sizeof(slab);
 }
 
 
@@ -143,6 +142,8 @@ static void sv_recv_cb(uv_udp_t* handle,
   ASSERT(r == 0);
 
   sv_recv_cb_called++;
+
+  free(rcvbuf->base);
 }
 
 
@@ -152,6 +153,12 @@ TEST_IMPL(udp_alloc_cb_fail) {
   uv_buf_t buf;
   int r;
 
+  close_cb_called = 0;
+  cl_send_cb_called = 0;
+  cl_recv_cb_called = 0;
+  sv_send_cb_called = 0;
+  sv_recv_cb_called = 0;
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-udp-connect.c b/test/test-udp-connect.c
index c1e4064b..efc96e1c 100644
--- a/test/test-udp-connect.c
+++ b/test/test-udp-connect.c
@@ -43,11 +43,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -94,6 +93,8 @@ static void sv_recv_cb(uv_udp_t* handle,
       uv_close((uv_handle_t*) &client, close_cb);
     }
   }
+
+  free(rcvbuf->base);
 }
 
 
@@ -107,6 +108,10 @@ TEST_IMPL(udp_connect) {
   int r;
   int addrlen;
 
+  close_cb_called = 0;
+  cl_send_cb_called = 0;
+  sv_recv_cb_called = 0;
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &lo_addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-udp-dgram-too-big.c b/test/test-udp-dgram-too-big.c
index 9db8b47b..89bb7446 100644
--- a/test/test-udp-dgram-too-big.c
+++ b/test/test-udp-dgram-too-big.c
@@ -62,6 +62,9 @@ TEST_IMPL(udp_dgram_too_big) {
   uv_buf_t buf;
   int r;
 
+  close_cb_called = 0;
+  send_cb_called  = 0;
+
   memset(dgram, 42, sizeof dgram); /* silence valgrind */
 
   r = uv_udp_init(uv_default_loop(), &handle_);
diff --git a/test/test-udp-ipv6.c b/test/test-udp-ipv6.c
index ae55cd01..e5874f44 100644
--- a/test/test-udp-ipv6.c
+++ b/test/test-udp-ipv6.c
@@ -65,10 +65,9 @@ static int can_ipv6_ipv4_dual(void) {
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  buf->base = slab;
-  buf->len = sizeof(slab);
 }
 
 
@@ -115,6 +114,8 @@ static void ipv6_recv_fail(uv_udp_t* handle,
   if (!is_from_client(addr) || (nread == 0 && addr == NULL))
     return;
   ASSERT(0 && "this function should not have been called");
+
+  free(buf->base);
 }
 
 
@@ -132,6 +133,8 @@ static void ipv6_recv_ok(uv_udp_t* handle,
   ASSERT(nread == 9);
   ASSERT(!memcmp(buf->base, data, 9));
   recv_cb_called++;
+
+  free(buf->base);
 }
 
 
diff --git a/test/test-udp-multicast-interface.c b/test/test-udp-multicast-interface.c
index 447d3487..c4e27c4b 100644
--- a/test/test-udp-multicast-interface.c
+++ b/test/test-udp-multicast-interface.c
@@ -65,6 +65,8 @@ TEST_IMPL(udp_multicast_interface) {
   struct sockaddr_in addr;
   struct sockaddr_in baddr;
 
+  close_cb_called = 0;
+  sv_send_cb_called = 0;
   ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-udp-multicast-interface6.c b/test/test-udp-multicast-interface6.c
index 1d40aefa..2bc7a7bf 100644
--- a/test/test-udp-multicast-interface6.c
+++ b/test/test-udp-multicast-interface6.c
@@ -68,6 +68,9 @@ TEST_IMPL(udp_multicast_interface6) {
   if (!can_ipv6())
     RETURN_SKIP("IPv6 not supported");
 
+  close_cb_called = 0;
+  sv_send_cb_called = 0;
+
   ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-udp-multicast-join.c b/test/test-udp-multicast-join.c
index dddcea46..2910510a 100644
--- a/test/test-udp-multicast-join.c
+++ b/test/test-udp-multicast-join.c
@@ -45,11 +45,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -74,7 +73,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
 static int do_send(uv_udp_send_t* send_req) {
   uv_buf_t buf;
   struct sockaddr_in addr;
-  
+
   buf = uv_buf_init("PING", 4);
 
   ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr));
@@ -134,6 +133,8 @@ static void cl_recv_cb(uv_udp_t* handle,
     r = do_send(&req_ss);
     ASSERT(r == 0);
   }
+
+  free(buf->base);
 }
 
 
diff --git a/test/test-udp-multicast-join6.c b/test/test-udp-multicast-join6.c
index d5262b6a..ce765ebe 100644
--- a/test/test-udp-multicast-join6.c
+++ b/test/test-udp-multicast-join6.c
@@ -56,11 +56,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -85,7 +84,7 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
 static int do_send(uv_udp_send_t* send_req) {
   uv_buf_t buf;
   struct sockaddr_in6 addr;
-  
+
   buf = uv_buf_init("PING", 4);
 
   ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr));
@@ -143,6 +142,8 @@ static void cl_recv_cb(uv_udp_t* handle,
     r = do_send(&req_ss);
     ASSERT(r == 0);
   }
+
+  free(buf->base);
 }
 
 
@@ -198,7 +199,7 @@ TEST_IMPL(udp_multicast_join6) {
 #endif
   r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
   ASSERT(r == 0);
-  
+
   r = do_send(&req);
   ASSERT(r == 0);
 
diff --git a/test/test-udp-multicast-ttl.c b/test/test-udp-multicast-ttl.c
index 9aa5bb91..3ac8d850 100644
--- a/test/test-udp-multicast-ttl.c
+++ b/test/test-udp-multicast-ttl.c
@@ -59,6 +59,9 @@ TEST_IMPL(udp_multicast_ttl) {
   uv_buf_t buf;
   struct sockaddr_in addr;
 
+  sv_send_cb_called = 0;
+  close_cb_called = 0;
+
   r = uv_udp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
 
diff --git a/test/test-udp-open.c b/test/test-udp-open.c
index 0e09f56a..1d02ace2 100644
--- a/test/test-udp-open.c
+++ b/test/test-udp-open.c
@@ -83,10 +83,9 @@ static void close_socket(uv_os_sock_t sock) {
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  buf->base = malloc(65536);
+  buf->len = 65536;
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -123,6 +122,8 @@ static void recv_cb(uv_udp_t* handle,
   ASSERT(r == 0);
 
   uv_close((uv_handle_t*) handle, close_cb);
+
+  free(buf->base);
 }
 
 
@@ -173,7 +174,7 @@ TEST_IMPL(udp_open) {
     ASSERT(r == 0);
 
     r = uv_udp_open(&client2, sock);
-    ASSERT(r == UV_EEXIST);
+    ASSERT(r == 0);
 
     uv_close((uv_handle_t*) &client2, NULL);
   }
@@ -257,6 +258,9 @@ TEST_IMPL(udp_open_connect) {
   uv_os_sock_t sock;
   int r;
 
+  send_cb_called = 0;
+  close_cb_called = 0;
+
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
 
   startup();
diff --git a/test/test-udp-send-and-recv.c b/test/test-udp-send-and-recv.c
index ab60e84a..1bb3552d 100644
--- a/test/test-udp-send-and-recv.c
+++ b/test/test-udp-send-and-recv.c
@@ -44,11 +44,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -84,6 +83,8 @@ static void cl_recv_cb(uv_udp_t* handle,
   cl_recv_cb_called++;
 
   uv_close((uv_handle_t*) handle, close_cb);
+
+  free(buf->base);
 }
 
 
@@ -154,6 +155,8 @@ static void sv_recv_cb(uv_udp_t* handle,
   ASSERT(r == 0);
 
   sv_recv_cb_called++;
+
+  free(rcvbuf->base);
 }
 
 
@@ -163,6 +166,13 @@ TEST_IMPL(udp_send_and_recv) {
   uv_buf_t buf;
   int r;
 
+  close_cb_called = 0;
+  cl_send_cb_called = 0;
+  cl_recv_cb_called =0;
+  sv_send_cb_called = 0;
+  sv_recv_cb_called = 0;
+
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-udp-send-immediate.c b/test/test-udp-send-immediate.c
index ee70a616..12f6559e 100644
--- a/test/test-udp-send-immediate.c
+++ b/test/test-udp-send-immediate.c
@@ -40,11 +40,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -91,6 +90,8 @@ static void sv_recv_cb(uv_udp_t* handle,
     uv_close((uv_handle_t*) &server, close_cb);
     uv_close((uv_handle_t*) &client, close_cb);
   }
+
+  free(rcvbuf->base);
 }
 
 
diff --git a/test/test-udp-send-unreachable.c b/test/test-udp-send-unreachable.c
index 7075deb1..6b0b4bad 100644
--- a/test/test-udp-send-unreachable.c
+++ b/test/test-udp-send-unreachable.c
@@ -44,11 +44,10 @@ static int can_recverr;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT_LE(suggested_size, sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT_LE(suggested_size, 65536);
   alloc_cb_called++;
 }
 
@@ -90,6 +89,8 @@ static void recv_cb(uv_udp_t* handle,
   } else {
     ASSERT_NOT_NULL(addr);
   }
+
+  free(rcvbuf->base);
 }
 
 
diff --git a/test/test-udp-try-send.c b/test/test-udp-try-send.c
index b81506cc..edfaa0ba 100644
--- a/test/test-udp-try-send.c
+++ b/test/test-udp-try-send.c
@@ -40,11 +40,10 @@ static int close_cb_called;
 static void alloc_cb(uv_handle_t* handle,
                      size_t suggested_size,
                      uv_buf_t* buf) {
-  static char slab[65536];
+  buf->base = malloc(65536);
+  buf->len = 65536;
   CHECK_HANDLE(handle);
-  ASSERT(suggested_size <= sizeof(slab));
-  buf->base = slab;
-  buf->len = sizeof(slab);
+  ASSERT(suggested_size <= 65536);
 }
 
 
@@ -75,6 +74,8 @@ static void sv_recv_cb(uv_udp_t* handle,
   uv_close((uv_handle_t*) &client, close_cb);
 
   sv_recv_cb_called++;
+
+  free(rcvbuf->base);
 }
 
 
@@ -84,6 +85,9 @@ TEST_IMPL(udp_try_send) {
   uv_buf_t buf;
   int r;
 
+  close_cb_called = 0;
+  sv_recv_cb_called = 0;
+
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
 
   r = uv_udp_init(uv_default_loop(), &server);
diff --git a/test/test-watcher-cross-stop.c b/test/test-watcher-cross-stop.c
index bbc0c305..4e7996f5 100644
--- a/test/test-watcher-cross-stop.c
+++ b/test/test-watcher-cross-stop.c
@@ -26,14 +26,15 @@
 #include <errno.h>
 
 /* NOTE: Number should be big enough to trigger this problem */
-#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
+#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) || defined(__NuttX__)
 /* Cygwin crashes or hangs in socket() with too many AF_INET sockets.  */
 /* IBMi PASE timeout with too many AF_INET sockets.  */
-static uv_udp_t sockets[1250];
+#  define SOCKET_NUM 125
 #else
-static uv_udp_t sockets[2500];
+#  define SOCKET_NUM 2500
 #endif
-static uv_udp_send_t reqs[ARRAY_SIZE(sockets)];
+static uv_udp_t* sockets;
+static uv_udp_send_t* reqs;
 static char slab[1];
 static unsigned int recv_cb_called;
 static unsigned int send_cb_called;
@@ -74,13 +75,19 @@ TEST_IMPL(watcher_cross_stop) {
   uv_buf_t buf;
   char big_string[1024];
 
-  TEST_FILE_LIMIT(ARRAY_SIZE(sockets) + 32);
+  TEST_FILE_LIMIT(SOCKET_NUM + 32);
+
+  sockets = (uv_udp_t*)malloc(sizeof(uv_udp_t) * SOCKET_NUM);
+  ASSERT(sockets != NULL);
+
+  reqs = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t) * SOCKET_NUM);
+  ASSERT(reqs != NULL);
 
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
   memset(big_string, 'A', sizeof(big_string));
   buf = uv_buf_init(big_string, sizeof(big_string));
 
-  for (i = 0; i < ARRAY_SIZE(sockets); i++) {
+  for (i = 0; i < SOCKET_NUM; i++) {
     ASSERT(0 == uv_udp_init(loop, &sockets[i]));
     ASSERT(0 == uv_udp_bind(&sockets[i],
                             (const struct sockaddr*) &addr,
@@ -97,15 +104,18 @@ TEST_IMPL(watcher_cross_stop) {
   while (recv_cb_called == 0)
     uv_run(loop, UV_RUN_ONCE);
 
-  for (i = 0; i < ARRAY_SIZE(sockets); i++)
+  for (i = 0; i < SOCKET_NUM; i++)
     uv_close((uv_handle_t*) &sockets[i], close_cb);
 
   ASSERT(recv_cb_called > 0);
 
   uv_run(loop, UV_RUN_DEFAULT);
 
-  ASSERT(ARRAY_SIZE(sockets) == send_cb_called);
-  ASSERT(ARRAY_SIZE(sockets) == close_cb_called);
+  free(sockets);
+  free(reqs);
+
+  ASSERT(SOCKET_NUM == send_cb_called);
+  ASSERT(SOCKET_NUM == close_cb_called);
 
   MAKE_VALGRIND_HAPPY(loop);
   return 0;
diff --git a/include/uv/unix.h b/include/uv/unix.h
index 4962b932..e6303c45 100644
--- a/include/uv/unix.h
+++ b/include/uv/unix.h
@@ -45,7 +45,7 @@
 
 #include "uv/threadpool.h"
 
-#if defined(__linux__)
+#if defined(__linux__) || defined(CONFIG_LIBUV_BACKEND_EPOLL)
 # include "uv/linux.h"
 #elif defined (__MVS__)
 # include "uv/os390.h"
diff --git a/src/unix/internal.h b/src/unix/internal.h
index ddc744b2..7ff0c094 100644
--- a/src/unix/internal.h
+++ b/src/unix/internal.h
@@ -177,7 +177,7 @@ struct uv__stream_queued_fds_s {
   int fds[1];
 };
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__NuttX__)
 struct uv__statx_timestamp {
   int64_t tv_sec;
   uint32_t tv_nsec;
@@ -207,7 +207,7 @@ struct uv__statx {
   uint32_t stx_dev_minor;
   uint64_t unused1[14];
 };
-#endif /* __linux__ */
+#endif /* __linux__ || __NuttX__ */
 
 #if defined(_AIX) || \
     defined(__APPLE__) || \
diff --git a/src/unix/linux.c b/src/unix/linux.c
index 48b9c2c4..95f0e3dc 100644
--- a/src/unix/linux.c
+++ b/src/unix/linux.c
@@ -52,6 +52,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#ifdef __linux__
 #ifndef __NR_io_uring_setup
 # define __NR_io_uring_setup 425
 #endif
@@ -63,6 +64,7 @@
 #ifndef __NR_io_uring_register
 # define __NR_io_uring_register 427
 #endif
+#endif
 
 #ifndef __NR_copy_file_range
 # if defined(__x86_64__)
@@ -335,6 +337,7 @@ unsigned uv__kernel_version(void) {
 }
 
 
+#ifdef __linux__
 ssize_t
 uv__fs_copy_file_range(int fd_in,
                        off_t* off_in,
@@ -389,10 +392,15 @@ ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
   return rc;
 #endif
 }
+#endif
 
 
 int uv__io_uring_setup(int entries, struct uv__io_uring_params* params) {
+#ifdef __NR_io_uring_setup
   return syscall(__NR_io_uring_setup, entries, params);
+#else
+  return errno = ENOSYS, -1;
+#endif
 }
 
 
@@ -404,6 +412,7 @@ int uv__io_uring_enter(int fd,
    * in newer kernels unless IORING_ENTER_EXT_ARG is set,
    * in which case it takes a struct io_uring_getevents_arg.
    */
+#ifdef __NR_io_uring_enter
   return syscall(__NR_io_uring_enter,
                  fd,
                  to_submit,
@@ -411,16 +420,23 @@ int uv__io_uring_enter(int fd,
                  flags,
                  NULL,
                  0L);
+#else
+  return errno = ENOSYS, -1;
+#endif
 }
 
 
 int uv__io_uring_register(int fd, unsigned opcode, void* arg, unsigned nargs) {
+#ifdef __NR_io_uring_register
   return syscall(__NR_io_uring_register, fd, opcode, arg, nargs);
+#else
+  return errno = ENOSYS, -1;
+#endif
 }
 
 
 static int uv__use_io_uring(void) {
-#if defined(__ANDROID_API__)
+#if defined(__ANDROID_API__) || defined(__NuttX__)
   return 0;  /* Possibly available but blocked by seccomp. */
 #else
   /* Ternary: unknown=0, yes=1, no=-1 */
@@ -695,7 +711,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
   return rc;
 }
 
-
+#ifdef __linux__
 /* Caller must initialize SQE and call uv__iou_submit(). */
 static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou,
                                                 uv_loop_t* loop,
@@ -1019,6 +1035,7 @@ int uv__iou_fs_statx(uv_loop_t* loop,
 
   return 1;
 }
+#endif
 
 
 void uv__statx_to_stat(const struct uv__statx* statxbuf, uv_stat_t* buf) {
@@ -1530,6 +1547,7 @@ update_timeout:
       uv__epoll_ctl_flush(epollfd, ctl, &prep);
 }
 
+#ifdef __linux__
 uint64_t uv__hrtime(uv_clocktype_t type) {
   static _Atomic clock_t fast_clock_id = -1;
   struct timespec t;
@@ -2238,6 +2256,7 @@ void uv_loadavg(double avg[3]) {
   avg[1] = (double) info.loads[1] / 65536.0;
   avg[2] = (double) info.loads[2] / 65536.0;
 }
+#endif
 
 
 static int compare_watchers(const struct watcher_list* a,
diff --git a/src/uv-common.h b/src/uv-common.h
index cd57e5a3..7bd628e8 100644
--- a/src/uv-common.h
+++ b/src/uv-common.h
@@ -396,7 +396,7 @@ struct uv__loop_metrics_s {
 void uv__metrics_update_idle_time(uv_loop_t* loop);
 void uv__metrics_set_provider_entry_time(uv_loop_t* loop);
 
-#ifdef __linux__
+#if defined(__linux__) || defined(CONFIG_LIBUV_BACKEND_EPOLL)
 struct uv__iou {
   uint32_t* sqhead;
   uint32_t* sqtail;
@@ -417,17 +417,17 @@ struct uv__iou {
   uint32_t in_flight;
   uint32_t flags;
 };
-#endif  /* __linux__ */
+#endif  /* __linux__ || CONFIG_LIBUV_BACKEND_EPOLL */
 
 struct uv__loop_internal_fields_s {
   unsigned int flags;
   uv__loop_metrics_t loop_metrics;
   int current_timeout;
-#ifdef __linux__
+#if defined(__linux__) || defined(CONFIG_LIBUV_BACKEND_EPOLL)
   struct uv__iou ctl;
   struct uv__iou iou;
   void* inv;  /* used by uv__platform_invalidate_fd() */
-#endif  /* __linux__ */
+#endif  /* __linux__ || CONFIG_LIBUV_BACKEND_EPOLL */
 };
 
 #endif /* UV_COMMON_H_ */
diff --git a/test/task.h b/test/task.h
index 25af255c..4162476a 100644
--- a/test/task.h
+++ b/test/task.h
@@ -353,7 +353,7 @@ UNUSED static int can_ipv6(void) {
   return supported;
 }
 
-#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) || defined(__NuttX__)
+#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
 # define NO_FS_EVENTS "Filesystem watching not supported on this platform."
 #endif
 
diff --git a/test/test-fs-event.c b/test/test-fs-event.c
index 9f231ebf..a1680989 100644
--- a/test/test-fs-event.c
+++ b/test/test-fs-event.c
@@ -405,6 +405,11 @@ TEST_IMPL(fs_event_watch_dir) {
   uv_loop_t* loop = uv_default_loop();
   int r;
 
+  fs_event_cb_called = 0;
+  fs_event_created = 0;
+  fs_event_removed = 0;
+  close_cb_called = 0;
+
   /* Setup */
   fs_event_unlink_files(NULL);
   remove("watch_dir/file2");
@@ -443,6 +448,12 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
   int r;
   uv_fs_event_t fs_event_root;
 
+  fs_multievent_cb_called = 0;
+  fs_event_cb_called = 0;
+  fs_event_created = 0;
+  fs_event_removed = 0;
+  close_cb_called = 0;
+
   /* Setup */
   loop = uv_default_loop();
   fs_event_unlink_files(NULL);
@@ -558,6 +569,9 @@ TEST_IMPL(fs_event_watch_file) {
 
   uv_loop_t* loop = uv_default_loop();
   int r;
+  fs_event_cb_called = 0;
+  timer_cb_called = 0;
+  close_cb_called = 0;
 
   /* Setup */
   remove("watch_dir/file2");
@@ -605,6 +619,7 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
   int r;
 
   loop = uv_default_loop();
+  timer_cb_exact_called = 0;
 
   /* Setup */
   remove("watch_dir/file.js");
@@ -653,6 +668,10 @@ TEST_IMPL(fs_event_watch_file_twice) {
   uv_timer_t timer;
   uv_loop_t* loop;
 
+  create_dir("test/");
+  create_dir("test/fixtures/");
+  create_file("test/fixtures/empty_file");
+
   loop = uv_default_loop();
   timer.data = watchers;
 
@@ -664,6 +683,10 @@ TEST_IMPL(fs_event_watch_file_twice) {
   ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0));
   ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
 
+  remove("test/fixtures/empty_file");
+  remove("test/fixtures/");
+  remove("test/");
+
   MAKE_VALGRIND_HAPPY(loop);
   return 0;
 }
@@ -677,6 +700,9 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
   int r;
 
   loop = uv_default_loop();
+  timer_cb_touch_called = 0;
+  fs_event_cb_called = 0;
+  close_cb_called = 0;
 
   /* Setup */
   remove("watch_file");
@@ -758,6 +784,9 @@ TEST_IMPL(fs_event_no_callback_after_close) {
   uv_loop_t* loop = uv_default_loop();
   int r;
 
+  fs_event_cb_called = 0;
+  close_cb_called = 0;
+
   /* Setup */
   remove("watch_dir/file1");
   remove("watch_dir/");
@@ -796,6 +825,9 @@ TEST_IMPL(fs_event_no_callback_on_close) {
   uv_loop_t* loop = uv_default_loop();
   int r;
 
+  fs_event_cb_called = 0;
+  close_cb_called = 0;
+
   /* Setup */
   remove("watch_dir/file1");
   remove("watch_dir/");
@@ -848,6 +880,7 @@ TEST_IMPL(fs_event_immediate_close) {
   int r;
 
   loop = uv_default_loop();
+  close_cb_called = 0;
 
   r = uv_timer_init(loop, &timer);
   ASSERT(r == 0);
@@ -873,6 +906,8 @@ TEST_IMPL(fs_event_close_with_pending_event) {
 
   loop = uv_default_loop();
 
+  close_cb_called = 0;
+
   create_dir("watch_dir");
   create_file("watch_dir/file");
 
@@ -946,6 +981,9 @@ TEST_IMPL(fs_event_close_in_callback) {
   int r;
 
   loop = uv_default_loop();
+  close_cb_called = 0;
+  fs_event_cb_called = 0;
+  fs_event_created = 0;
 
   fs_event_unlink_files(NULL);
   create_dir("watch_dir");
@@ -987,6 +1025,7 @@ TEST_IMPL(fs_event_start_and_close) {
   int r;
 
   loop = uv_default_loop();
+  close_cb_called = 0;
 
   create_dir("watch_dir");
 
@@ -1031,6 +1070,7 @@ TEST_IMPL(fs_event_getpath) {
 
   create_dir("watch_dir");
   create_dir("watch_dir/subfolder");
+  close_cb_called = 0;
 
 
   for (i = 0; i < ARRAY_SIZE(watch_dir); i++) {
@@ -1097,6 +1137,8 @@ TEST_IMPL(fs_event_error_reporting) {
   uv_loop_t* loop;
   uv_fs_event_t* event;
 
+  fs_event_error_reported = 0;
+
   TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3);
 
   remove("watch_dir/");
diff --git a/test/test-fs-event.c b/test/test-fs-event.c
index a1680989..ab7b5941 100644
--- a/test/test-fs-event.c
+++ b/test/test-fs-event.c
@@ -668,8 +668,8 @@ TEST_IMPL(fs_event_watch_file_twice) {
   uv_timer_t timer;
   uv_loop_t* loop;
 
-  create_dir("test/");
-  create_dir("test/fixtures/");
+  create_dir("test");
+  create_dir("test/fixtures");
   create_file("test/fixtures/empty_file");
 
   loop = uv_default_loop();
@@ -684,8 +684,8 @@ TEST_IMPL(fs_event_watch_file_twice) {
   ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
 
   remove("test/fixtures/empty_file");
-  remove("test/fixtures/");
-  remove("test/");
+  remove("test/fixtures");
+  remove("test");
 
   MAKE_VALGRIND_HAPPY(loop);
   return 0;
@@ -941,6 +941,7 @@ TEST_IMPL(fs_event_close_with_pending_delete_event) {
   int r;
 
   loop = uv_default_loop();
+  close_cb_called = 0;
 
   create_dir("watch_dir");
   create_file("watch_dir/file");
@@ -1240,6 +1241,8 @@ TEST_IMPL(fs_event_stop_in_cb) {
   uv_fs_event_t fs;
   uv_timer_t timer;
   char path[] = "fs_event_stop_in_cb.txt";
+  timer_cb_touch_called = 0;
+  fs_event_cb_stop_calls = 0;
 
 #if defined(NO_FS_EVENTS)
   RETURN_SKIP(NO_FS_EVENTS);
diff --git a/src/unix/nuttx.c b/src/unix/nuttx.c
index 57afeb2c..ec8eeb08 100644
--- a/src/unix/nuttx.c
+++ b/src/unix/nuttx.c
@@ -360,3 +360,25 @@ uv__global_t* uv__global_get(void) {
   ASSERT(global != NULL);
   return global;
 }
+
+#ifndef CONFIG_FS_NOTIFY
+int inotify_init(void)
+{
+  return UV_ENOTSUP;
+}
+
+int inotify_init1(int flags)
+{
+  return UV_ENOTSUP;
+}
+
+int inotify_add_watch(int fd, FAR const char *pathname, uint32_t mask)
+{
+  return UV_ENOTSUP;
+}
+
+int inotify_rm_watch(int fd, int wd)
+{
+  return UV_ENOTSUP;
+}
+#endif
diff --color -ur libuv_back/src/unix/thread.c libuv/src/unix/thread.c
--- libuv_back/src/unix/thread.c	2024-11-13 09:37:22.507687159 +0800
+++ libuv/src/unix/thread.c	2024-11-13 09:37:47.822236556 +0800
@@ -41,7 +41,7 @@
 #include <gnu/libc-version.h>  /* gnu_get_libc_version() */
 #endif
 
-#if defined(__linux__)
+#if defined(__linux__) || defined (__NuttX__)
 # include <sched.h>
 # define uv__cpu_set_t cpu_set_t
 #elif defined(__FreeBSD__)