ref: c097de83fa9cd345861315805ff8a973ebf07cc3
parent: ba69433c1981471d93e528f933b245157fca3aa8
author: Sigrid Haflínudóttir <sigrid@gloot.com>
date: Mon Sep 21 11:37:21 EDT 2020
plan 9: dirty multithreading (need to link with dav1d until this is moved somewhere else)
--- a/mkfile
+++ b/mkfile
@@ -60,7 +60,7 @@
detokenize.$O\
# error_concealment.$O\
onyxd_if.$O\
-# threading.$O\
+ threading.$O\
# vp8/encoder \
bitstream.$O\
boolhuff.$O\
--- a/plan9/pthread.h
+++ b/plan9/pthread.h
@@ -1,0 +1,75 @@
+#ifndef __pthread_h__
+#define __pthread_h__
+
+typedef struct pthread_t pthread_t;
+typedef struct pthread_cond_t pthread_cond_t;
+typedef struct pthread_once_t pthread_once_t;
+typedef struct pthread_mutex_t pthread_mutex_t;
+
+struct pthread_cond_t {
+ Rendez;
+ QLock lock;
+};
+
+struct pthread_once_t {
+ QLock;
+ int done;
+};
+
+struct pthread_mutex_t {
+ QLock;
+};
+
+#define PTHREAD_ONCE_INIT {0}
+
+struct pthread_t {
+ void *waitchan;
+ void *(*func)(void*);
+ void *arg;
+ int pid;
+};
+
+typedef struct {
+ unsigned stack_size;
+} pthread_attr_t;
+
+void dav1d_set_thread_name(const char *const name);
+int dav1d_pthread_join(pthread_t *thread, void **res);
+#define pthread_join(thread, res) dav1d_pthread_join(&(thread), res)
+
+static int pthread_attr_init(pthread_attr_t *const attr) {
+ attr->stack_size = 0;
+ return 0;
+}
+
+static int pthread_attr_destroy(pthread_attr_t *const attr) {
+ USED(attr);
+ return 0;
+}
+
+static int pthread_attr_setstacksize(pthread_attr_t *const attr,
+ const int stack_size)
+{
+ attr->stack_size = stack_size;
+ return 0;
+}
+
+static int
+pthread_mutex_trylock(pthread_mutex_t *const mutex)
+{
+ return canqlock(mutex) ? 0 : -1;
+}
+
+int pthread_mutex_init(pthread_mutex_t *const mutex, const void *const attr);
+int pthread_mutex_destroy(pthread_mutex_t *const mutex);
+int pthread_mutex_lock(pthread_mutex_t *const mutex);
+int pthread_mutex_unlock(pthread_mutex_t *const mutex);
+int pthread_cond_init(pthread_cond_t *const cond, const void *const attr);
+int pthread_cond_destroy(pthread_cond_t *const cond);
+int pthread_cond_wait(pthread_cond_t *const cond, pthread_mutex_t *const mutex);
+int pthread_cond_signal(pthread_cond_t *const cond);
+int pthread_cond_broadcast(pthread_cond_t *const cond);
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*func)(void*), void *arg);
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
+
+#endif
--- /dev/null
+++ b/plan9/semaphore.h
@@ -1,0 +1,50 @@
+#ifndef __semaphore_h__
+#define __semaphore_h__
+
+typedef struct sem_t sem_t;
+
+struct sem_t {
+ Channel *c;
+};
+
+static int
+sem_post(sem_t *s)
+{
+ void *p;
+
+ if(s == nil || s->c == nil)
+ return -1;
+ nbrecv(s->c, &p);
+
+ return 0;
+}
+
+static int
+sem_wait(sem_t *s)
+{
+ void *p;
+
+ if(s == nil || s->c == nil)
+ return -1;
+ sendp(s->c, nil);
+
+ return 0;
+}
+
+static int
+sem_init(sem_t *s, int pshared, unsigned int value)
+{
+ s->c = chancreate(sizeof(void*), value);
+
+ return 0;
+}
+
+static int
+sem_destroy(sem_t *s)
+{
+ chanclose(s->c);
+
+ return 0;
+}
+
+#endif
--- a/plan9/vpx_config.h
+++ b/plan9/vpx_config.h
@@ -11,6 +11,7 @@
#include <u.h>
#include <libc.h>
+#include <thread.h>
#include </sys/include/stdio.h>
typedef u8int uint8_t;
typedef u16int uint16_t;
@@ -59,6 +60,14 @@
double round(double);
#define logf log
+#define sched_yield() yield()
+#define __atomic_load_n(p,o) *(p)
+#define __atomic_store_n(p,v,x) do { *(p) = (v); } while(0)
+#define __has_builtin(x) 1
+
+#define __ATOMIC_RELEASE 0
+#define __ATOMIC_ACQUIRE 1
+
#define RESTRICT
#define INLINE inline
#define VPX_ARCH_ARM 0
@@ -84,7 +93,7 @@
#define HAVE_VSX 0
#define HAVE_MMI 0
#define HAVE_VPX_PORTS 0
-#define HAVE_PTHREAD_H 0
+#define HAVE_PTHREAD_H 1
#define HAVE_UNISTD_H 1
#define CONFIG_DEPENDENCY_TRACKING 1
#define CONFIG_EXTERNAL_BUILD 0
@@ -107,7 +116,7 @@
#define CONFIG_RUNTIME_CPU_DETECT 1
#define CONFIG_POSTPROC 0
#define CONFIG_VP9_POSTPROC 0
-#define CONFIG_MULTITHREAD 0
+#define CONFIG_MULTITHREAD 1
#define CONFIG_INTERNAL_STATS 0
#define CONFIG_VP8_ENCODER 1
#define CONFIG_VP8_DECODER 1
@@ -122,12 +131,12 @@
#define CONFIG_REALTIME_ONLY 0
#define CONFIG_ONTHEFLY_BITPACKING 0
#define CONFIG_ERROR_CONCEALMENT 0
-#define CONFIG_SHARED 1
+#define CONFIG_SHARED 0
#define CONFIG_STATIC 1
#define CONFIG_SMALL 0
#define CONFIG_POSTPROC_VISUALIZER 0
#define CONFIG_OS_SUPPORT 1
-#define CONFIG_UNIT_TESTS 1
+#define CONFIG_UNIT_TESTS 0
#define CONFIG_WEBM_IO 0
#define CONFIG_LIBYUV 0
#define CONFIG_DECODE_PERF_TESTS 0
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -36,7 +36,7 @@
#endif
#if CONFIG_MULTITHREAD
-static int get_cpu_count() {
+static int get_cpu_count(void) {
int core_count = 16;
#if HAVE_UNISTD_H && !defined(__OS2__)
@@ -78,6 +78,12 @@
if (status == PROC_ONLINE) core_count++;
}
+ }
+#elif defined(__plan9__)
+ {
+ char *s = getenv("NPROC");
+ core_count = atoi(s ? s : "1");
+ fprint(2, "core count: %d\n", core_count);
}
#else
/* other platforms */
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -11,6 +11,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include "vpx_config.h"
#include "./vp8_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
--- a/vpx_util/endian_inl.h
+++ b/vpx_util/endian_inl.h
@@ -48,6 +48,7 @@
#define HToBE32(X) BSwap32(X)
#endif
+#ifndef __plan9__
#if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16)
#define HAVE_BUILTIN_BSWAP16
#endif
@@ -58,6 +59,7 @@
#if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64)
#define HAVE_BUILTIN_BSWAP64
+#endif
#endif
#if HAVE_MIPS32 && defined(__mips__) && !defined(__mips64) && \
--- a/vpx_util/vpx_thread.h
+++ b/vpx_util/vpx_thread.h
@@ -383,6 +383,7 @@
// Platform-dependent implementation details for the worker.
typedef struct VPxWorkerImpl VPxWorkerImpl;
+#pragma incomplete VPxWorkerImpl
// Synchronization object used to launch job in the worker thread
typedef struct {
@@ -393,6 +394,7 @@
void *data2; // second argument passed to 'hook'
int had_error; // return value of the last call to 'hook'
} VPxWorker;
+#pragma incomplete VPxWorker
// The interface for all thread-worker related functions. All these functions
// must be implemented.
@@ -418,6 +420,7 @@
// must call reset() again.
void (*end)(VPxWorker *const worker);
} VPxWorkerInterface;
+#pragma incomplete VPxWorkerInterface
// Install a new set of threading functions, overriding the defaults. This
// should be done before any workers are started, i.e., before any encoding or