summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/os
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2018-01-08 05:41:34 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2018-01-08 05:41:34 +0000
commitc00801de923e125863aaf8180439d59d610b2517 (patch)
treee2896aa2785f3cf2151aeeb3c95fb5cc09a2fe02 /lib/mesa/src/gallium/auxiliary/os
parentbe30e6efb92db21299b936c0e068e7088941e9c9 (diff)
Revert to Mesa 13.0.6 again.
Corruption has again been reported on Intel hardware running Xorg with the modesetting driver (which uses OpenGL based acceleration instead of SNA acceleration the intel driver defaults to). Reported in various forms on Sandy Bridge (X220), Ivy Bridge (X230) and Haswell (X240). Confirmed to not occur with the intel driver but the xserver was changed to default to the modesetting driver on >= gen4 hardware (except Ironlake). One means of triggering this is to open a large pdf with xpdf on an idle machine and highlight a section of the document. There have been reports of gpu hangs on gen4 intel hardware (T500 with GM45, X61 with 965GM) when starting Xorg as well.
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/os')
-rw-r--r--lib/mesa/src/gallium/auxiliary/os/os_process.c95
-rw-r--r--lib/mesa/src/gallium/auxiliary/os/os_thread.h160
-rw-r--r--lib/mesa/src/gallium/auxiliary/os/os_time.c16
3 files changed, 210 insertions, 61 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/os/os_process.c b/lib/mesa/src/gallium/auxiliary/os/os_process.c
index a6262283d..6622b9b2b 100644
--- a/lib/mesa/src/gallium/auxiliary/os/os_process.c
+++ b/lib/mesa/src/gallium/auxiliary/os/os_process.c
@@ -43,6 +43,10 @@
#warning unexpected platform in os_process.c
#endif
+#if defined(PIPE_OS_LINUX)
+# include <fcntl.h>
+#endif
+
/**
* Return the name of the current process.
@@ -54,37 +58,48 @@ boolean
os_get_process_name(char *procname, size_t size)
{
const char *name;
+
+ /* First, check if the GALLIUM_PROCESS_NAME env var is set to
+ * override the normal process name query.
+ */
+ name = os_get_option("GALLIUM_PROCESS_NAME");
+
+ if (!name) {
+ /* do normal query */
+
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
- char szProcessPath[MAX_PATH];
- char *lpProcessName;
- char *lpProcessExt;
+ char szProcessPath[MAX_PATH];
+ char *lpProcessName;
+ char *lpProcessExt;
- GetModuleFileNameA(NULL, szProcessPath, Elements(szProcessPath));
+ GetModuleFileNameA(NULL, szProcessPath, ARRAY_SIZE(szProcessPath));
- lpProcessName = strrchr(szProcessPath, '\\');
- lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
+ lpProcessName = strrchr(szProcessPath, '\\');
+ lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
- lpProcessExt = strrchr(lpProcessName, '.');
- if (lpProcessExt) {
- *lpProcessExt = '\0';
- }
+ lpProcessExt = strrchr(lpProcessName, '.');
+ if (lpProcessExt) {
+ *lpProcessExt = '\0';
+ }
- name = lpProcessName;
+ name = lpProcessName;
#elif defined(__GLIBC__) || defined(__CYGWIN__)
- name = program_invocation_short_name;
+ name = program_invocation_short_name;
#elif defined(PIPE_OS_BSD) || defined(PIPE_OS_APPLE)
- /* *BSD and OS X */
- name = getprogname();
+ /* *BSD and OS X */
+ name = getprogname();
#elif defined(PIPE_OS_HAIKU)
- image_info info;
- get_image_info(B_CURRENT_TEAM, &info);
- name = info.name;
+ image_info info;
+ get_image_info(B_CURRENT_TEAM, &info);
+ name = info.name;
#else
#warning unexpected platform in os_process.c
- return FALSE;
+ return FALSE;
#endif
+ }
+
assert(size > 0);
assert(procname);
@@ -97,3 +112,47 @@ os_get_process_name(char *procname, size_t size)
return FALSE;
}
}
+
+
+/**
+ * Return the command line for the calling process. This is basically
+ * the argv[] array with the arguments separated by spaces.
+ * \param cmdline returns the command line string
+ * \param size size of the cmdline buffer
+ * \return TRUE or FALSE for success, failure
+ */
+boolean
+os_get_command_line(char *cmdline, size_t size)
+{
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ const char *args = GetCommandLine();
+ if (args) {
+ strncpy(cmdline, args, size);
+ // make sure we terminate the string
+ cmdline[size - 1] = 0;
+ return TRUE;
+ }
+#elif defined(PIPE_OS_LINUX)
+ int f = open("/proc/self/cmdline", O_RDONLY);
+ if (f) {
+ const int n = read(f, cmdline, size - 1);
+ int i;
+ assert(n < size);
+ // The arguments are separated by '\0' chars. Convert them to spaces.
+ for (i = 0; i < n; i++) {
+ if (cmdline[i] == 0) {
+ cmdline[i] = ' ';
+ }
+ }
+ // terminate the string
+ cmdline[n] = 0;
+ close(f);
+ return TRUE;
+ }
+#endif
+
+ /* XXX to-do: implement this function for other operating systems */
+
+ cmdline[0] = 0;
+ return FALSE;
+}
diff --git a/lib/mesa/src/gallium/auxiliary/os/os_thread.h b/lib/mesa/src/gallium/auxiliary/os/os_thread.h
index 10d4695da..ec8adbc75 100644
--- a/lib/mesa/src/gallium/auxiliary/os/os_thread.h
+++ b/lib/mesa/src/gallium/auxiliary/os/os_thread.h
@@ -39,18 +39,92 @@
#include "pipe/p_compiler.h"
#include "util/u_debug.h" /* for assert */
-#include "util/u_thread.h"
+#include "c11/threads.h"
+
+#ifdef HAVE_PTHREAD
+#include <signal.h>
+#endif
+
+
+/* pipe_thread
+ */
+typedef thrd_t pipe_thread;
+
+#define PIPE_THREAD_ROUTINE( name, param ) \
+ int name( void *param )
+
+static inline pipe_thread pipe_thread_create( PIPE_THREAD_ROUTINE((*routine), ), void *param )
+{
+ pipe_thread thread;
+#ifdef HAVE_PTHREAD
+ sigset_t saved_set, new_set;
+ int ret;
+
+ sigfillset(&new_set);
+ pthread_sigmask(SIG_SETMASK, &new_set, &saved_set);
+ ret = thrd_create( &thread, routine, param );
+ pthread_sigmask(SIG_SETMASK, &saved_set, NULL);
+#else
+ int ret;
+ ret = thrd_create( &thread, routine, param );
+#endif
+ if (ret)
+ return 0;
+
+ return thread;
+}
+
+static inline int pipe_thread_wait( pipe_thread thread )
+{
+ return thrd_join( thread, NULL );
+}
+
+static inline int pipe_thread_destroy( pipe_thread thread )
+{
+ return thrd_detach( thread );
+}
+
+static inline void pipe_thread_setname( const char *name )
+{
+#if defined(HAVE_PTHREAD)
+# if defined(__GNU_LIBRARY__) && defined(__GLIBC__) && defined(__GLIBC_MINOR__) && \
+ (__GLIBC__ >= 3 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12))
+ pthread_setname_np(pthread_self(), name);
+# endif
+#endif
+ (void)name;
+}
+
+
+/* pipe_mutex
+ */
+typedef mtx_t pipe_mutex;
+
+#define pipe_static_mutex(mutex) \
+ static pipe_mutex mutex = _MTX_INITIALIZER_NP
+
+#define pipe_mutex_init(mutex) \
+ (void) mtx_init(&(mutex), mtx_plain)
+
+#define pipe_mutex_destroy(mutex) \
+ mtx_destroy(&(mutex))
+
+#define pipe_mutex_lock(mutex) \
+ (void) mtx_lock(&(mutex))
+
+#define pipe_mutex_unlock(mutex) \
+ (void) mtx_unlock(&(mutex))
#define pipe_mutex_assert_locked(mutex) \
__pipe_mutex_assert_locked(&(mutex))
static inline void
-__pipe_mutex_assert_locked(mtx_t *mutex)
+__pipe_mutex_assert_locked(pipe_mutex *mutex)
{
#ifdef DEBUG
/* NOTE: this would not work for recursive mutexes, but
- * mtx_t doesn't support those
+ * pipe_mutex doesn't support those
*/
int ret = mtx_trylock(mutex);
assert(ret == thrd_busy);
@@ -59,12 +133,31 @@ __pipe_mutex_assert_locked(mtx_t *mutex)
#endif
}
+/* pipe_condvar
+ */
+typedef cnd_t pipe_condvar;
+
+#define pipe_condvar_init(cond) \
+ cnd_init(&(cond))
+
+#define pipe_condvar_destroy(cond) \
+ cnd_destroy(&(cond))
+
+#define pipe_condvar_wait(cond, mutex) \
+ cnd_wait(&(cond), &(mutex))
+
+#define pipe_condvar_signal(cond) \
+ cnd_signal(&(cond))
+
+#define pipe_condvar_broadcast(cond) \
+ cnd_broadcast(&(cond))
+
/*
* pipe_barrier
*/
-#if (defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HURD)) && (!defined(PIPE_OS_ANDROID) || ANDROID_API_LEVEL >= 24)
+#if (defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HURD)) && !defined(PIPE_OS_ANDROID)
typedef pthread_barrier_t pipe_barrier;
@@ -90,8 +183,8 @@ typedef struct {
unsigned count;
unsigned waiters;
uint64_t sequence;
- mtx_t mutex;
- cnd_t condvar;
+ pipe_mutex mutex;
+ pipe_condvar condvar;
} pipe_barrier;
static inline void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
@@ -99,20 +192,20 @@ static inline void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
barrier->count = count;
barrier->waiters = 0;
barrier->sequence = 0;
- (void) mtx_init(&barrier->mutex, mtx_plain);
- cnd_init(&barrier->condvar);
+ pipe_mutex_init(barrier->mutex);
+ pipe_condvar_init(barrier->condvar);
}
static inline void pipe_barrier_destroy(pipe_barrier *barrier)
{
assert(barrier->waiters == 0);
- mtx_destroy(&barrier->mutex);
- cnd_destroy(&barrier->condvar);
+ pipe_mutex_destroy(barrier->mutex);
+ pipe_condvar_destroy(barrier->condvar);
}
static inline void pipe_barrier_wait(pipe_barrier *barrier)
{
- mtx_lock(&barrier->mutex);
+ pipe_mutex_lock(barrier->mutex);
assert(barrier->waiters < barrier->count);
barrier->waiters++;
@@ -121,15 +214,15 @@ static inline void pipe_barrier_wait(pipe_barrier *barrier)
uint64_t sequence = barrier->sequence;
do {
- cnd_wait(&barrier->condvar, &barrier->mutex);
+ pipe_condvar_wait(barrier->condvar, barrier->mutex);
} while (sequence == barrier->sequence);
} else {
barrier->waiters = 0;
barrier->sequence++;
- cnd_broadcast(&barrier->condvar);
+ pipe_condvar_broadcast(barrier->condvar);
}
- mtx_unlock(&barrier->mutex);
+ pipe_mutex_unlock(barrier->mutex);
}
@@ -142,8 +235,8 @@ static inline void pipe_barrier_wait(pipe_barrier *barrier)
typedef struct
{
- mtx_t mutex;
- cnd_t cond;
+ pipe_mutex mutex;
+ pipe_condvar cond;
int counter;
} pipe_semaphore;
@@ -151,38 +244,38 @@ typedef struct
static inline void
pipe_semaphore_init(pipe_semaphore *sema, int init_val)
{
- (void) mtx_init(&sema->mutex, mtx_plain);
- cnd_init(&sema->cond);
+ pipe_mutex_init(sema->mutex);
+ pipe_condvar_init(sema->cond);
sema->counter = init_val;
}
static inline void
pipe_semaphore_destroy(pipe_semaphore *sema)
{
- mtx_destroy(&sema->mutex);
- cnd_destroy(&sema->cond);
+ pipe_mutex_destroy(sema->mutex);
+ pipe_condvar_destroy(sema->cond);
}
/** Signal/increment semaphore counter */
static inline void
pipe_semaphore_signal(pipe_semaphore *sema)
{
- mtx_lock(&sema->mutex);
+ pipe_mutex_lock(sema->mutex);
sema->counter++;
- cnd_signal(&sema->cond);
- mtx_unlock(&sema->mutex);
+ pipe_condvar_signal(sema->cond);
+ pipe_mutex_unlock(sema->mutex);
}
/** Wait for semaphore counter to be greater than zero */
static inline void
pipe_semaphore_wait(pipe_semaphore *sema)
{
- mtx_lock(&sema->mutex);
+ pipe_mutex_lock(sema->mutex);
while (sema->counter <= 0) {
- cnd_wait(&sema->cond, &sema->mutex);
+ pipe_condvar_wait(sema->cond, sema->mutex);
}
sema->counter--;
- mtx_unlock(&sema->mutex);
+ pipe_mutex_unlock(sema->mutex);
}
@@ -231,19 +324,4 @@ pipe_tsd_set(pipe_tsd *tsd, void *value)
-/*
- * Thread statistics.
- */
-
-/* Return the time of the current thread's CPU time clock. */
-static inline int64_t
-pipe_current_thread_get_time_nano(void)
-{
-#if defined(HAVE_PTHREAD)
- return u_thread_get_time_nano(pthread_self());
-#else
- return 0;
-#endif
-}
-
#endif /* OS_THREAD_H_ */
diff --git a/lib/mesa/src/gallium/auxiliary/os/os_time.c b/lib/mesa/src/gallium/auxiliary/os/os_time.c
index 3d2e41672..e16913903 100644
--- a/lib/mesa/src/gallium/auxiliary/os/os_time.c
+++ b/lib/mesa/src/gallium/auxiliary/os/os_time.c
@@ -40,6 +40,7 @@
# include <time.h> /* timeval */
# include <sys/time.h> /* timeval */
# include <sched.h> /* sched_yield */
+# include <errno.h>
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# include <windows.h>
#else
@@ -81,19 +82,30 @@ os_time_get_nano(void)
}
-#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
void
os_time_sleep(int64_t usecs)
{
+#if defined(PIPE_OS_LINUX)
+ struct timespec time;
+ time.tv_sec = usecs / 1000000;
+ time.tv_nsec = (usecs % 1000000) * 1000;
+ while (clock_nanosleep(CLOCK_MONOTONIC, 0, &time, &time) == EINTR);
+
+#elif defined(PIPE_OS_UNIX)
+ usleep(usecs);
+
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
DWORD dwMilliseconds = (DWORD) ((usecs + 999) / 1000);
/* Avoid Sleep(O) as that would cause to sleep for an undetermined duration */
if (dwMilliseconds) {
Sleep(dwMilliseconds);
}
+#else
+# error Unsupported OS
+#endif
}
-#endif
int64_t