summaryrefslogtreecommitdiff
path: root/src/unix.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-08-24 19:31:36 -0700
committerScott Gasch <[email protected]>2026-08-24 19:31:36 -0700
commit29d73f4dd59554a349aa8e86e5ea65f28c912ec9 (patch)
tree05e8dcbe6eb3c2f6d8bfd7c8065c250b2734254c /src/unix.c
parentc5ca1a37b0614f5cb55499692a7f61775f81d1eb (diff)
Started doing texel eval tuning.
Diffstat (limited to 'src/unix.c')
-rw-r--r--src/unix.c144
1 files changed, 65 insertions, 79 deletions
diff --git a/src/unix.c b/src/unix.c
index 99216d0..68d2319 100644
--- a/src/unix.c
+++ b/src/unix.c
@@ -27,8 +27,6 @@ Revision History:
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/select.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
@@ -1020,44 +1018,54 @@ SystemReleaseLock(ULONG u)
}
+/*
+ * These "semaphores" only ever signal between threads of this same
+ * process (see input.c's producer/consumer wait between the stdin
+ * reader thread and the command-dispatch thread) -- there is no
+ * cross-process handoff here, despite the SysV-semaphore-shaped API.
+ * A SysV semget(IPC_PRIVATE, ...) set is kernel-global, outlives the
+ * process, and only gets torn down by an explicit IPC_RMID -- so a
+ * killed (rather than gracefully quit()'d) process leaks it, and on a
+ * shared box with a low kern.ipc.semmni it doesn't take many leaked
+ * engines to exhaust the system-wide semaphore-set table. Every
+ * subsequent semget() then fails, and _WaitUntilTheresInputToRead
+ * (input.c) silently falls back to 100ms-polling instead of blocking
+ * on a real wait -- a ~1000x slowdown that looks exactly like machine
+ * contention. A pthread_mutex_t/pthread_cond_t pair does the same
+ * counting-semaphore job entirely in-process, with no kernel-persistent
+ * object to leak: the OS reclaims it unconditionally the instant the
+ * process dies, SIGKILL or not.
+ */
#define MAX_SEM (8)
-int g_rgSemaphores[MAX_SEM];
-#ifdef DEBUG
-ULONG g_rgSemValues[MAX_SEM];
-#endif
+
+typedef struct _SEM_ENTRY
+{
+ FLAG fInUse;
+ ULONG uCount;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+}
+SEM_ENTRY;
+
+SEM_ENTRY g_rgSemaphores[MAX_SEM];
ULONG
-SystemCreateSemaphore(ULONG uValue)
+SystemCreateSemaphore(ULONG uValue)
{
ULONG u;
- union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- } value;
if (uValue > MAX_USHORT) return((ULONG)-1);
LOCK_SYSTEM;
- for (u = 0; u < MAX_SEM; u++)
+ for (u = 0; u < MAX_SEM; u++)
{
- if (g_rgSemaphores[u] < 0)
+ if (g_rgSemaphores[u].fInUse == FALSE)
{
- g_rgSemaphores[u] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
- if (g_rgSemaphores[u] < 0)
- {
- u = (ULONG)-1;
- goto end;
- }
- value.val = uValue;
- if (semctl(g_rgSemaphores[u], 0, SETVAL, value) < 0)
- {
- (void)SystemDeleteSemaphore(u);
- u = (ULONG)-1;
- goto end;
- }
+ pthread_mutex_init(&(g_rgSemaphores[u].lock), NULL);
+ pthread_cond_init(&(g_rgSemaphores[u].cond), NULL);
+ g_rgSemaphores[u].uCount = uValue;
+ g_rgSemaphores[u].fInUse = TRUE;
#ifdef DEBUG
- g_rgSemValues[u] = uValue;
- Trace("Semaphore #%u created, initial value is %u\n",
+ Trace("Semaphore #%u created, initial value is %u\n",
u, uValue);
#endif
goto end;
@@ -1071,82 +1079,60 @@ SystemCreateSemaphore(ULONG uValue)
FLAG
SystemDeleteSemaphore(ULONG u) {
- union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- } value;
FLAG fRet = TRUE;
- memset(&value, 0, sizeof(value));
LOCK_SYSTEM;
- if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0))
+ if ((u < MAX_SEM) && (g_rgSemaphores[u].fInUse == TRUE))
{
- if (semctl(g_rgSemaphores[u], 0, IPC_RMID, value) < 0)
- {
- fRet = FALSE;
- }
- else
- {
- g_rgSemaphores[u] = -1;
- }
+ pthread_mutex_destroy(&(g_rgSemaphores[u].lock));
+ pthread_cond_destroy(&(g_rgSemaphores[u].cond));
+ g_rgSemaphores[u].fInUse = FALSE;
+ }
+ else
+ {
+ fRet = FALSE;
}
UNLOCK_SYSTEM;
return(fRet);
}
void
-SystemReleaseSemaphoreResource(ULONG u)
+SystemReleaseSemaphoreResource(ULONG u)
{
- struct sembuf operation;
-
LOCK_SYSTEM;
- if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0))
+ if ((u < MAX_SEM) && (g_rgSemaphores[u].fInUse == TRUE))
{
- operation.sem_num = u;
- operation.sem_op = +1;
- operation.sem_flg = 0;
- if (semop(g_rgSemaphores[u], &operation, 1) < 0)
- {
- UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE,
- NULL, "semop", (void *)errno, (void *)0,
- __FILE__, __LINE__);
- }
+ pthread_mutex_lock(&(g_rgSemaphores[u].lock));
+ g_rgSemaphores[u].uCount += 1;
#ifdef DEBUG
- g_rgSemValues[u] += 1;
- Trace("Semaphore #%u value incremented to %u\n", u,
- g_rgSemValues[u]);
+ Trace("Semaphore #%u value incremented to %u\n", u,
+ g_rgSemaphores[u].uCount);
#endif
+ pthread_cond_signal(&(g_rgSemaphores[u].cond));
+ pthread_mutex_unlock(&(g_rgSemaphores[u].lock));
}
UNLOCK_SYSTEM;
}
void
-SystemObtainSemaphoreResource(ULONG u)
+SystemObtainSemaphoreResource(ULONG u)
{
- struct sembuf operation;
-
LOCK_SYSTEM;
- if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0))
+ if ((u < MAX_SEM) && (g_rgSemaphores[u].fInUse == TRUE))
{
- operation.sem_num = u;
- operation.sem_op = -1;
- operation.sem_flg = 0;
+ pthread_mutex_lock(&(g_rgSemaphores[u].lock));
UNLOCK_SYSTEM;
- if (semop(g_rgSemaphores[u], &operation, 1) < 0)
+ while (g_rgSemaphores[u].uCount == 0)
{
- UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE,
- NULL, "semop", (void *)errno, (void *)1,
- __FILE__, __LINE__);
+ pthread_cond_wait(&(g_rgSemaphores[u].cond),
+ &(g_rgSemaphores[u].lock));
}
+ g_rgSemaphores[u].uCount -= 1;
#ifdef DEBUG
- if (g_rgSemValues[u] > 0)
- {
- g_rgSemValues[u] -= 1;
- Trace("Semaphore #%u value decremented to %u\n", u,
- g_rgSemValues[u]);
- }
+ Trace("Semaphore #%u value decremented to %u\n", u,
+ g_rgSemaphores[u].uCount);
#endif
+ pthread_mutex_unlock(&(g_rgSemaphores[u].lock));
return;
}
UNLOCK_SYSTEM;
@@ -1187,9 +1173,9 @@ Return value:
memset(g_AllocHash, 0, sizeof(g_AllocHash));
#endif
- for (u = 0; u < MAX_SEM; u++)
+ for (u = 0; u < MAX_SEM; u++)
{
- g_rgSemaphores[u] = -1;
+ g_rgSemaphores[u].fInUse = FALSE;
}
InitializeListHead(&g_SystemThreadList);
pthread_mutex_init(&g_SystemLock, NULL);