aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python/src/Python/thread_sgi.h
diff options
context:
space:
mode:
authornkozlovskiy <nmk@ydb.tech>2023-09-29 12:24:06 +0300
committernkozlovskiy <nmk@ydb.tech>2023-09-29 12:41:34 +0300
commite0e3e1717e3d33762ce61950504f9637a6e669ed (patch)
treebca3ff6939b10ed60c3d5c12439963a1146b9711 /contrib/tools/python/src/Python/thread_sgi.h
parent38f2c5852db84c7b4d83adfcb009eb61541d1ccd (diff)
downloadydb-e0e3e1717e3d33762ce61950504f9637a6e669ed.tar.gz
add ydb deps
Diffstat (limited to 'contrib/tools/python/src/Python/thread_sgi.h')
-rw-r--r--contrib/tools/python/src/Python/thread_sgi.h259
1 files changed, 259 insertions, 0 deletions
diff --git a/contrib/tools/python/src/Python/thread_sgi.h b/contrib/tools/python/src/Python/thread_sgi.h
new file mode 100644
index 0000000000..771ab2cc60
--- /dev/null
+++ b/contrib/tools/python/src/Python/thread_sgi.h
@@ -0,0 +1,259 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <ulocks.h>
+#include <errno.h>
+
+#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
+#define MAXPROC 100 /* max # of threads that can be started */
+
+static usptr_t *shared_arena;
+static ulock_t count_lock; /* protection for some variables */
+static ulock_t wait_lock; /* lock used to wait for other threads */
+static int waiting_for_threads; /* protected by count_lock */
+static int nthreads; /* protected by count_lock */
+static int exit_status;
+static int exiting; /* we're already exiting (for maybe_exit) */
+static pid_t my_pid; /* PID of main thread */
+static struct pidlist {
+ pid_t parent;
+ pid_t child;
+} pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */
+static int maxpidindex; /* # of PIDs in pidlist */
+/*
+ * Initialization.
+ */
+static void PyThread__init_thread(void)
+{
+#ifdef USE_DL
+ long addr, size;
+#endif /* USE_DL */
+
+
+#ifdef USE_DL
+ if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
+ perror("usconfig - CONF_INITSIZE (check)");
+ if (usconfig(CONF_INITSIZE, size) < 0)
+ perror("usconfig - CONF_INITSIZE (reset)");
+ addr = (long) dl_getrange(size + HDR_SIZE);
+ dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size));
+ errno = 0;
+ if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
+ perror("usconfig - CONF_ATTACHADDR (set)");
+#endif /* USE_DL */
+ if (usconfig(CONF_INITUSERS, 16) < 0)
+ perror("usconfig - CONF_INITUSERS");
+ my_pid = getpid(); /* so that we know which is the main thread */
+ if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
+ perror("usconfig - CONF_ARENATYPE");
+ usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
+#ifdef Py_DEBUG
+ if (thread_debug & 4)
+ usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
+ else if (thread_debug & 2)
+ usconfig(CONF_LOCKTYPE, US_DEBUG);
+#endif /* Py_DEBUG */
+ if ((shared_arena = usinit(tmpnam(0))) == 0)
+ perror("usinit");
+#ifdef USE_DL
+ if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
+ perror("usconfig - CONF_ATTACHADDR (reset)");
+#endif /* USE_DL */
+ if ((count_lock = usnewlock(shared_arena)) == NULL)
+ perror("usnewlock (count_lock)");
+ (void) usinitlock(count_lock);
+ if ((wait_lock = usnewlock(shared_arena)) == NULL)
+ perror("usnewlock (wait_lock)");
+ dprintf(("arena start: %p, arena size: %ld\n", shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
+}
+
+/*
+ * Thread support.
+ */
+
+static void clean_threads(void)
+{
+ int i, j;
+ pid_t mypid, pid;
+
+ /* clean up any exited threads */
+ mypid = getpid();
+ i = 0;
+ while (i < maxpidindex) {
+ if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
+ pid = waitpid(pid, 0, WNOHANG);
+ if (pid > 0) {
+ /* a thread has exited */
+ pidlist[i] = pidlist[--maxpidindex];
+ /* remove references to children of dead proc */
+ for (j = 0; j < maxpidindex; j++)
+ if (pidlist[j].parent == pid)
+ pidlist[j].child = -1;
+ continue; /* don't increment i */
+ }
+ }
+ i++;
+ }
+ /* clean up the list */
+ i = 0;
+ while (i < maxpidindex) {
+ if (pidlist[i].child == -1) {
+ pidlist[i] = pidlist[--maxpidindex];
+ continue; /* don't increment i */
+ }
+ i++;
+ }
+}
+
+long PyThread_start_new_thread(void (*func)(void *), void *arg)
+{
+#ifdef USE_DL
+ long addr, size;
+ static int local_initialized = 0;
+#endif /* USE_DL */
+ int success = 0; /* init not needed when SOLARIS_THREADS and */
+ /* C_THREADS implemented properly */
+
+ dprintf(("PyThread_start_new_thread called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+ switch (ussetlock(count_lock)) {
+ case 0: return 0;
+ case -1: perror("ussetlock (count_lock)");
+ }
+ if (maxpidindex >= MAXPROC)
+ success = -1;
+ else {
+#ifdef USE_DL
+ if (!local_initialized) {
+ if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
+ perror("usconfig - CONF_INITSIZE (check)");
+ if (usconfig(CONF_INITSIZE, size) < 0)
+ perror("usconfig - CONF_INITSIZE (reset)");
+ addr = (long) dl_getrange(size + HDR_SIZE);
+ dprintf(("trying to use addr %p-%p for sproc\n",
+ addr, addr+size));
+ errno = 0;
+ if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
+ errno != 0)
+ perror("usconfig - CONF_ATTACHADDR (set)");
+ }
+#endif /* USE_DL */
+ clean_threads();
+ if ((success = sproc(func, PR_SALL, arg)) < 0)
+ perror("sproc");
+#ifdef USE_DL
+ if (!local_initialized) {
+ if (usconfig(CONF_ATTACHADDR, addr) < 0)
+ /* reset address */
+ perror("usconfig - CONF_ATTACHADDR (reset)");
+ local_initialized = 1;
+ }
+#endif /* USE_DL */
+ if (success >= 0) {
+ nthreads++;
+ pidlist[maxpidindex].parent = getpid();
+ pidlist[maxpidindex++].child = success;
+ dprintf(("pidlist[%d] = %d\n",
+ maxpidindex-1, success));
+ }
+ }
+ if (usunsetlock(count_lock) < 0)
+ perror("usunsetlock (count_lock)");
+ return success;
+}
+
+long PyThread_get_thread_ident(void)
+{
+ return getpid();
+}
+
+void PyThread_exit_thread(void)
+{
+ dprintf(("PyThread_exit_thread called\n"));
+ if (!initialized)
+ exit(0);
+ if (ussetlock(count_lock) < 0)
+ perror("ussetlock (count_lock)");
+ nthreads--;
+ if (getpid() == my_pid) {
+ /* main thread; wait for other threads to exit */
+ exiting = 1;
+ waiting_for_threads = 1;
+ if (ussetlock(wait_lock) < 0)
+ perror("ussetlock (wait_lock)");
+ for (;;) {
+ if (nthreads < 0) {
+ dprintf(("really exit (%d)\n", exit_status));
+ exit(exit_status);
+ }
+ if (usunsetlock(count_lock) < 0)
+ perror("usunsetlock (count_lock)");
+ dprintf(("waiting for other threads (%d)\n", nthreads));
+ if (ussetlock(wait_lock) < 0)
+ perror("ussetlock (wait_lock)");
+ if (ussetlock(count_lock) < 0)
+ perror("ussetlock (count_lock)");
+ }
+ }
+ /* not the main thread */
+ if (waiting_for_threads) {
+ dprintf(("main thread is waiting\n"));
+ if (usunsetlock(wait_lock) < 0)
+ perror("usunsetlock (wait_lock)");
+ }
+ if (usunsetlock(count_lock) < 0)
+ perror("usunsetlock (count_lock)");
+ _exit(0);
+}
+
+/*
+ * Lock support.
+ */
+PyThread_type_lock PyThread_allocate_lock(void)
+{
+ ulock_t lock;
+
+ dprintf(("PyThread_allocate_lock called\n"));
+ if (!initialized)
+ PyThread_init_thread();
+
+ if ((lock = usnewlock(shared_arena)) == NULL)
+ perror("usnewlock");
+ (void) usinitlock(lock);
+ dprintf(("PyThread_allocate_lock() -> %p\n", lock));
+ return (PyThread_type_lock) lock;
+}
+
+void PyThread_free_lock(PyThread_type_lock lock)
+{
+ dprintf(("PyThread_free_lock(%p) called\n", lock));
+ usfreelock((ulock_t) lock, shared_arena);
+}
+
+int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
+{
+ int success;
+
+ dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
+ errno = 0; /* clear it just in case */
+ if (waitflag)
+ success = ussetlock((ulock_t) lock);
+ else
+ success = uscsetlock((ulock_t) lock, 1); /* Try it once */
+ if (success < 0)
+ perror(waitflag ? "ussetlock" : "uscsetlock");
+ dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
+ return success;
+}
+
+void PyThread_release_lock(PyThread_type_lock lock)
+{
+ dprintf(("PyThread_release_lock(%p) called\n", lock));
+ if (usunsetlock((ulock_t) lock) < 0)
+ perror("usunsetlock");
+}