diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fbc34173390a1be01be3058772629779558f5c4a..4bd751b506019e8530859bb2fff876d1039c0d4a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -21,6 +21,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
 	console.c
 	hu_stuff.c
 	i_time.c
+	i_threads.c
 	y_inter.c
 	st_stuff.c
 	m_aatree.c
diff --git a/src/Makefile.d/dedicated.mk b/src/Makefile.d/dedicated.mk
index 698ea553191a84775acf23c45715ba8fee6d0862..6c66d3b9460d345936738e73f1d9230d247158b1 100644
--- a/src/Makefile.d/dedicated.mk
+++ b/src/Makefile.d/dedicated.mk
@@ -13,11 +13,6 @@ ifdef MINGW
 libs+=-mconsole
 endif
 
-ifndef NOTHREADS
-opts+=-DHAVE_THREADS
-sources+=dedicated/i_threads.c
-endif
-
 NOOPENMPT=1
 NOGME=1
 NOHW=1
diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk
index 59806862d50d884329ab5183d1061b15987c9d01..9415506c4f762601fe79569fcc12f1655202274c 100644
--- a/src/Makefile.d/features.mk
+++ b/src/Makefile.d/features.mk
@@ -18,6 +18,11 @@ opts+=-DHWRENDER
 sources+=$(call List,hardware/Sourcefile)
 endif
 
+ifndef NOTHREADS
+opts+=-DHAVE_THREADS
+sources+=i_threads.c
+endif
+
 ifndef NOMD5
 sources+=md5.c
 endif
diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk
index d5e83989c2d1955146a8c228c15034d9f2b9e091..4314f7fd25ef45395c53eb29df6a07a3eb389494 100644
--- a/src/Makefile.d/sdl.mk
+++ b/src/Makefile.d/sdl.mk
@@ -43,11 +43,6 @@ sources+=sdl/mixer_sound.c
   endif
 endif
 
-ifndef NOTHREADS
-opts+=-DHAVE_THREADS
-sources+=sdl/i_threads.c
-endif
-
 ifdef SDL_PKGCONFIG
 $(eval $(call Use_pkg_config,SDL))
 else
diff --git a/src/dedicated/i_threads.c b/src/i_threads.c
similarity index 98%
rename from src/dedicated/i_threads.c
rename to src/i_threads.c
index 55c0a069e5d3f42e03c8286d4862f87e9c8f4a8e..fd2b24649bfc698b4e3816a64db3660c1c4d067a 100644
--- a/src/dedicated/i_threads.c
+++ b/src/i_threads.c
@@ -13,9 +13,9 @@
 
 #include <pthread.h>
 
-#include "../i_threads.h"
-#include "../doomdef.h"
-#include "../doomtype.h"
+#include "i_threads.h"
+#include "doomdef.h"
+#include "doomtype.h"
 
 typedef struct thread_s thread_t;
 
diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt
index 8950846ee4f43cf794bd6d2505bbf039e6c71d2f..46332f3f7525ec779b765be65a23b40aa5e63dad 100644
--- a/src/sdl/CMakeLists.txt
+++ b/src/sdl/CMakeLists.txt
@@ -2,7 +2,6 @@
 
 target_sources(SRB2SDL2 PRIVATE
 	ogl_sdl.c
-	i_threads.c
 	i_net.c
 	i_system.c
 	i_main.c
diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c
deleted file mode 100644
index c05936072ea9893a3079a4cbb86525196b75da89..0000000000000000000000000000000000000000
--- a/src/sdl/i_threads.c
+++ /dev/null
@@ -1,356 +0,0 @@
-// SONIC ROBO BLAST 2
-//-----------------------------------------------------------------------------
-// Copyright (C) 2020-2023 by James R.
-//
-// This program is free software distributed under the
-// terms of the GNU General Public License, version 2.
-// See the 'LICENSE' file for more details.
-//-----------------------------------------------------------------------------
-/// \file  i_threads.c
-/// \brief Multithreading abstraction
-
-#include "../doomdef.h"
-#include "../i_threads.h"
-
-#include <SDL.h>
-
-typedef void * (*Create_fn)(void);
-
-struct Link;
-struct Thread;
-
-typedef struct Link   * Link;
-typedef struct Thread * Thread;
-
-struct Link
-{
-	void * data;
-	Link   next;
-	Link   prev;
-};
-
-struct Thread
-{
-	I_thread_fn   entry;
-	void        * userdata;
-
-	SDL_Thread  * thread;
-};
-
-static Link    i_thread_pool;
-static Link    i_mutex_pool;
-static Link    i_cond_pool;
-
-static I_mutex        i_thread_pool_mutex;
-static I_mutex        i_mutex_pool_mutex;
-static I_mutex        i_cond_pool_mutex;
-
-static SDL_atomic_t   i_threads_running = {1};
-
-static Link
-Insert_link (
-		Link * head,
-		Link   link
-){
-	link->prev = NULL;
-	link->next = (*head);
-	if ((*head))
-		(*head)->prev = link;
-	(*head)    = link;
-	return link;
-}
-
-static void
-Free_link (
-		Link * head,
-		Link   link
-){
-	if (link->prev)
-		link->prev->next = link->next;
-	else
-		(*head) = link->next;
-
-	if (link->next)
-		link->next->prev = link->prev;
-
-	free(link->data);
-	free(link);
-}
-
-static Link
-New_link (void *data)
-{
-	Link link;
-
-	link = malloc(sizeof *link);
-
-	if (! link)
-		abort();
-
-	link->data = data;
-
-	return link;
-}
-
-static void *
-Identity (
-		Link      *  pool_anchor,
-		I_mutex      pool_mutex,
-
-		void      ** anchor,
-
-		Create_fn    create_fn
-){
-	void * id;
-
-	id = SDL_AtomicGetPtr(anchor);
-
-	if (! id)
-	{
-		I_lock_mutex(&pool_mutex);
-		{
-			id = SDL_AtomicGetPtr(anchor);
-
-			if (! id)
-			{
-				id = (*create_fn)();
-
-				if (! id)
-					abort();
-
-				Insert_link(pool_anchor, New_link(id));
-
-				SDL_AtomicSetPtr(anchor, id);
-			}
-		}
-		I_unlock_mutex(pool_mutex);
-	}
-
-	return id;
-}
-
-static int
-Worker (
-		Link link
-){
-	Thread th;
-
-	th = link->data;
-
-	(*th->entry)(th->userdata);
-
-	if (SDL_AtomicGet(&i_threads_running))
-	{
-		I_lock_mutex(&i_thread_pool_mutex);
-		{
-			if (SDL_AtomicGet(&i_threads_running))
-			{
-				SDL_DetachThread(th->thread);
-				Free_link(&i_thread_pool, link);
-			}
-		}
-		I_unlock_mutex(i_thread_pool_mutex);
-	}
-
-	return 0;
-}
-
-void
-I_spawn_thread (
-		const char  * name,
-		I_thread_fn   entry,
-		void        * userdata
-){
-	Link   link;
-	Thread th;
-
-	th = malloc(sizeof *th);
-
-	if (! th)
-		abort();/* this is pretty GNU of me */
-
-	th->entry    = entry;
-	th->userdata = userdata;
-
-	I_lock_mutex(&i_thread_pool_mutex);
-	{
-		link = Insert_link(&i_thread_pool, New_link(th));
-
-		if (SDL_AtomicGet(&i_threads_running))
-		{
-			th->thread = SDL_CreateThread(
-					(SDL_ThreadFunction)Worker,
-					name,
-					link
-			);
-
-			if (! th->thread)
-				abort();
-		}
-	}
-	I_unlock_mutex(i_thread_pool_mutex);
-}
-
-int
-I_thread_is_stopped (void)
-{
-	return ( ! SDL_AtomicGet(&i_threads_running) );
-}
-
-void
-I_start_threads (void)
-{
-	i_thread_pool_mutex = SDL_CreateMutex();
-	i_mutex_pool_mutex  = SDL_CreateMutex();
-	i_cond_pool_mutex   = SDL_CreateMutex();
-
-	if (!(
-				i_thread_pool_mutex &&
-				i_mutex_pool_mutex  &&
-				i_cond_pool_mutex
-	)){
-		abort();
-	}
-}
-
-void
-I_stop_threads (void)
-{
-	Link        link;
-	Link        next;
-
-	Thread      th;
-	SDL_mutex * mutex;
-	SDL_cond  * cond;
-
-	if (i_threads_running.value)
-	{
-		/* rely on the good will of thread-san */
-		SDL_AtomicSet(&i_threads_running, 0);
-
-		I_lock_mutex(&i_thread_pool_mutex);
-		{
-			for (
-					link = i_thread_pool;
-					link;
-					link = next
-			){
-				next = link->next;
-				th   = link->data;
-
-				SDL_WaitThread(th->thread, NULL);
-
-				free(th);
-				free(link);
-			}
-		}
-		I_unlock_mutex(i_thread_pool_mutex);
-
-		for (
-				link = i_mutex_pool;
-				link;
-				link = next
-		){
-			next  = link->next;
-			mutex = link->data;
-
-			SDL_DestroyMutex(mutex);
-
-			free(link);
-		}
-
-		for (
-				link = i_cond_pool;
-				link;
-				link = next
-		){
-			next = link->next;
-			cond = link->data;
-
-			SDL_DestroyCond(cond);
-
-			free(link);
-		}
-
-		SDL_DestroyMutex(i_thread_pool_mutex);
-		SDL_DestroyMutex(i_mutex_pool_mutex);
-		SDL_DestroyMutex(i_cond_pool_mutex);
-	}
-}
-
-void
-I_lock_mutex (
-		I_mutex * anchor
-){
-	SDL_mutex * mutex;
-
-	mutex = Identity(
-			&i_mutex_pool,
-			i_mutex_pool_mutex,
-			anchor,
-			(Create_fn)SDL_CreateMutex
-	);
-
-	if (SDL_LockMutex(mutex) == -1)
-		abort();
-}
-
-void
-I_unlock_mutex (
-		I_mutex id
-){
-	if (SDL_UnlockMutex(id) == -1)
-		abort();
-}
-
-void
-I_hold_cond (
-		I_cond  * cond_anchor,
-		I_mutex   mutex_id
-){
-	SDL_cond * cond;
-
-	cond = Identity(
-			&i_cond_pool,
-			i_cond_pool_mutex,
-			cond_anchor,
-			(Create_fn)SDL_CreateCond
-	);
-
-	if (SDL_CondWait(cond, mutex_id) == -1)
-		abort();
-}
-
-void
-I_wake_one_cond (
-		I_cond * anchor
-){
-	SDL_cond * cond;
-
-	cond = Identity(
-			&i_cond_pool,
-			i_cond_pool_mutex,
-			anchor,
-			(Create_fn)SDL_CreateCond
-	);
-
-	if (SDL_CondSignal(cond) == -1)
-		abort();
-}
-
-void
-I_wake_all_cond (
-		I_cond * anchor
-){
-	SDL_cond * cond;
-
-	cond = Identity(
-			&i_cond_pool,
-			i_cond_pool_mutex,
-			anchor,
-			(Create_fn)SDL_CreateCond
-	);
-
-	if (SDL_CondBroadcast(cond) == -1)
-		abort();
-}