]> O.S.I.I.S - jp/vkvg.git/commitdiff
vkvg_device_set_queue_guards
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 25 Jan 2022 23:22:46 +0000 (00:22 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 25 Jan 2022 23:25:54 +0000 (00:25 +0100)
include/vkvg.h
src/deps/tinycthread.c [deleted file]
src/deps/tinycthread.h [deleted file]
src/vkvg_device.c
src/vkvg_device_internal.c
src/vkvg_device_internal.h
src/vkvg_internal.h
tests/multithreading/multithreaded.c

index 47540f162fe77e20937a7a063946fc9f67a07460..6357d98261ee291ff369748b707f4e68e061cfb5 100644 (file)
@@ -90,7 +90,7 @@ extern "C" {
 #define VKVG_LOG_INFO_IBO      0x00000040
 #define VKVG_LOG_INFO_VAO      (VKVG_LOG_INFO_VBO|VKVG_LOG_INFO_IBO)
 #define VKVG_LOG_DBG_ARRAYS    0x00001000
-#define VKVG_LOG_THREADING     0x00000080
+//#define VKVG_LOG_THREADING   0x00000080
 #define VKVG_LOG_FULL          0xffffffff
 
 #define VKVG_LOG_INFO          0x00008000//(VKVG_LOG_INFO_PTS|VKVG_LOG_INFO_PATH|VKVG_LOG_INFO_CMD|VKVG_LOG_INFO_VAO)
@@ -535,6 +535,9 @@ void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy);
  * Device holds the font cache so that each time a context draws text, the same cache is used.
  *
  * @{ */
+typedef void (*vkvg_queue_guard)(void* user_data);
+vkvg_public
+void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data);
 
 /**
  * @brief Create a new vkvg device.
diff --git a/src/deps/tinycthread.c b/src/deps/tinycthread.c
deleted file mode 100644 (file)
index f9cea2e..0000000
+++ /dev/null
@@ -1,594 +0,0 @@
-/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
-Copyright (c) 2012 Marcus Geelnard
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-    1. The origin of this software must not be misrepresented; you must not
-    claim that you wrote the original software. If you use this software
-    in a product, an acknowledgment in the product documentation would be
-    appreciated but is not required.
-
-    2. Altered source versions must be plainly marked as such, and must not be
-    misrepresented as being the original software.
-
-    3. This notice may not be removed or altered from any source
-    distribution.
-*/
-
-/* 2013-01-06 Camilla Löwy <elmindreda@glfw.org>
- *
- * Added casts from time_t to DWORD to avoid warnings on VC++.
- * Fixed time retrieval on POSIX systems.
- */
-
-#include "tinycthread.h"
-#include <stdlib.h>
-
-/* Platform specific includes */
-#if defined(_TTHREAD_POSIX_)
-  #include <signal.h>
-  #include <sched.h>
-  #include <unistd.h>
-  #include <sys/time.h>
-  #include <errno.h>
-#elif defined(_TTHREAD_WIN32_)
-  #include <process.h>
-  #include <sys/timeb.h>
-#endif
-
-/* Standard, good-to-have defines */
-#ifndef NULL
-  #define NULL (void*)0
-#endif
-#ifndef TRUE
-  #define TRUE 1
-#endif
-#ifndef FALSE
-  #define FALSE 0
-#endif
-
-int mtx_init(mtx_t *mtx, int type)
-{
-#if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  mtx->mRecursive = type & mtx_recursive;
-  InitializeCriticalSection(&mtx->mHandle);
-  return thrd_success;
-#else
-  int ret;
-  pthread_mutexattr_t attr;
-  pthread_mutexattr_init(&attr);
-  if (type & mtx_recursive)
-  {
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-  }
-  ret = pthread_mutex_init(mtx, &attr);
-  pthread_mutexattr_destroy(&attr);
-  return ret == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-void mtx_destroy(mtx_t *mtx)
-{
-#if defined(_TTHREAD_WIN32_)
-  DeleteCriticalSection(&mtx->mHandle);
-#else
-  pthread_mutex_destroy(mtx);
-#endif
-}
-
-int mtx_lock(mtx_t *mtx)
-{
-#if defined(_TTHREAD_WIN32_)
-  EnterCriticalSection(&mtx->mHandle);
-  if (!mtx->mRecursive)
-  {
-    while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
-    mtx->mAlreadyLocked = TRUE;
-  }
-  return thrd_success;
-#else
-  return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
-{
-  /* FIXME! */
-  (void)mtx;
-  (void)ts;
-  return thrd_error;
-}
-
-int mtx_trylock(mtx_t *mtx)
-{
-#if defined(_TTHREAD_WIN32_)
-  int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
-  if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
-  {
-    LeaveCriticalSection(&mtx->mHandle);
-    ret = thrd_busy;
-  }
-  return ret;
-#else
-  return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
-#endif
-}
-
-int mtx_unlock(mtx_t *mtx)
-{
-#if defined(_TTHREAD_WIN32_)
-  mtx->mAlreadyLocked = FALSE;
-  LeaveCriticalSection(&mtx->mHandle);
-  return thrd_success;
-#else
-  return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
-#endif
-}
-
-#if defined(_TTHREAD_WIN32_)
-#define _CONDITION_EVENT_ONE 0
-#define _CONDITION_EVENT_ALL 1
-#endif
-
-int cnd_init(cnd_t *cond)
-{
-#if defined(_TTHREAD_WIN32_)
-  cond->mWaitersCount = 0;
-
-  /* Init critical section */
-  InitializeCriticalSection(&cond->mWaitersCountLock);
-
-  /* Init events */
-  cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
-  {
-    cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
-    return thrd_error;
-  }
-  cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
-  if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-    cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
-    return thrd_error;
-  }
-
-  return thrd_success;
-#else
-  return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-void cnd_destroy(cnd_t *cond)
-{
-#if defined(_TTHREAD_WIN32_)
-  if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
-  }
-  if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
-  {
-    CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
-  }
-  DeleteCriticalSection(&cond->mWaitersCountLock);
-#else
-  pthread_cond_destroy(cond);
-#endif
-}
-
-int cnd_signal(cnd_t *cond)
-{
-#if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
-    {
-      return thrd_error;
-    }
-  }
-
-  return thrd_success;
-#else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-int cnd_broadcast(cnd_t *cond)
-{
-#if defined(_TTHREAD_WIN32_)
-  int haveWaiters;
-
-  /* Are there any waiters? */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  haveWaiters = (cond->mWaitersCount > 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we have any waiting threads, send them a signal */
-  if(haveWaiters)
-  {
-    if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
-    }
-  }
-
-  return thrd_success;
-#else
-  return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-#if defined(_TTHREAD_WIN32_)
-static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
-{
-  int result, lastWaiter;
-
-  /* Increment number of waiters */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  ++ cond->mWaitersCount;
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* Release the mutex while waiting for the condition (will decrease
-     the number of waiters when done)... */
-  mtx_unlock(mtx);
-
-  /* Wait for either event to become signaled due to cnd_signal() or
-     cnd_broadcast() being called */
-  result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
-  if (result == WAIT_TIMEOUT)
-  {
-    return thrd_timeout;
-  }
-  else if (result == (int)WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-
-  /* Check if we are the last waiter */
-  EnterCriticalSection(&cond->mWaitersCountLock);
-  -- cond->mWaitersCount;
-  lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
-               (cond->mWaitersCount == 0);
-  LeaveCriticalSection(&cond->mWaitersCountLock);
-
-  /* If we are the last waiter to be notified to stop waiting, reset the event */
-  if (lastWaiter)
-  {
-    if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
-    {
-      return thrd_error;
-    }
-  }
-
-  /* Re-acquire the mutex */
-  mtx_lock(mtx);
-
-  return thrd_success;
-}
-#endif
-
-int cnd_wait(cnd_t *cond, mtx_t *mtx)
-{
-#if defined(_TTHREAD_WIN32_)
-  return _cnd_timedwait_win32(cond, mtx, INFINITE);
-#else
-  return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
-{
-#if defined(_TTHREAD_WIN32_)
-  struct timespec now;
-  if (clock_gettime(CLOCK_REALTIME, &now) == 0)
-  {
-    DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
-                           (ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
-    return _cnd_timedwait_win32(cond, mtx, delta);
-  }
-  else
-    return thrd_error;
-#else
-  int ret;
-  ret = pthread_cond_timedwait(cond, mtx, ts);
-  if (ret == ETIMEDOUT)
-  {
-    return thrd_timeout;
-  }
-  return ret == 0 ? thrd_success : thrd_error;
-#endif
-}
-
-
-/** Information to pass to the new thread (what to run). */
-typedef struct {
-  thrd_start_t mFunction; /**< Pointer to the function to be executed. */
-  void * mArg;            /**< Function argument for the thread function. */
-} _thread_start_info;
-
-/* Thread wrapper function. */
-#if defined(_TTHREAD_WIN32_)
-static unsigned WINAPI _thrd_wrapper_function(void * aArg)
-#elif defined(_TTHREAD_POSIX_)
-static void * _thrd_wrapper_function(void * aArg)
-#endif
-{
-  thrd_start_t fun;
-  void *arg;
-  int  res;
-#if defined(_TTHREAD_POSIX_)
-  void *pres;
-#endif
-
-  /* Get thread startup information */
-  _thread_start_info *ti = (_thread_start_info *) aArg;
-  fun = ti->mFunction;
-  arg = ti->mArg;
-
-  /* The thread is responsible for freeing the startup information */
-  free((void *)ti);
-
-  /* Call the actual client thread function */
-  res = fun(arg);
-
-#if defined(_TTHREAD_WIN32_)
-  return res;
-#else
-  pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  return pres;
-#endif
-}
-
-int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
-{
-  /* Fill out the thread startup information (passed to the thread wrapper,
-     which will eventually free it) */
-  _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
-  if (ti == NULL)
-  {
-    return thrd_nomem;
-  }
-  ti->mFunction = func;
-  ti->mArg = arg;
-
-  /* Create the thread */
-#if defined(_TTHREAD_WIN32_)
-  *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
-#elif defined(_TTHREAD_POSIX_)
-  if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
-  {
-    *thr = 0;
-  }
-#endif
-
-  /* Did we fail to create the thread? */
-  if(!*thr)
-  {
-    free(ti);
-    return thrd_error;
-  }
-
-  return thrd_success;
-}
-
-thrd_t thrd_current(void)
-{
-#if defined(_TTHREAD_WIN32_)
-  return GetCurrentThread();
-#else
-  return pthread_self();
-#endif
-}
-
-int thrd_detach(thrd_t thr)
-{
-  /* FIXME! */
-  (void)thr;
-  return thrd_error;
-}
-
-int thrd_equal(thrd_t thr0, thrd_t thr1)
-{
-#if defined(_TTHREAD_WIN32_)
-  return thr0 == thr1;
-#else
-  return pthread_equal(thr0, thr1);
-#endif
-}
-
-void thrd_exit(int res)
-{
-#if defined(_TTHREAD_WIN32_)
-  ExitThread(res);
-#else
-  void *pres = malloc(sizeof(int));
-  if (pres != NULL)
-  {
-    *(int*)pres = res;
-  }
-  pthread_exit(pres);
-#endif
-}
-
-int thrd_join(thrd_t thr, int *res)
-{
-#if defined(_TTHREAD_WIN32_)
-  if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
-  {
-    return thrd_error;
-  }
-  if (res != NULL)
-  {
-    DWORD dwRes;
-    GetExitCodeThread(thr, &dwRes);
-    *res = dwRes;
-  }
-#elif defined(_TTHREAD_POSIX_)
-  void *pres;
-  int ires = 0;
-  if (pthread_join(thr, &pres) != 0)
-  {
-    return thrd_error;
-  }
-  if (pres != NULL)
-  {
-    ires = *(int*)pres;
-    free(pres);
-  }
-  if (res != NULL)
-  {
-    *res = ires;
-  }
-#endif
-  return thrd_success;
-}
-
-int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
-{
-  struct timespec now;
-#if defined(_TTHREAD_WIN32_)
-  DWORD delta;
-#else
-  long delta;
-#endif
-
-  /* Get the current time */
-  if (clock_gettime(CLOCK_REALTIME, &now) != 0)
-    return -2;  // FIXME: Some specific error code?
-
-#if defined(_TTHREAD_WIN32_)
-  /* Delta in milliseconds */
-  delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
-                   (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
-  if (delta > 0)
-  {
-    Sleep(delta);
-  }
-#else
-  /* Delta in microseconds */
-  delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
-          (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
-
-  /* On some systems, the usleep argument must be < 1000000 */
-  while (delta > 999999L)
-  {
-    usleep(999999);
-    delta -= 999999L;
-  }
-  if (delta > 0L)
-  {
-    usleep((useconds_t)delta);
-  }
-#endif
-
-  /* We don't support waking up prematurely (yet) */
-  if (remaining)
-  {
-    remaining->tv_sec = 0;
-    remaining->tv_nsec = 0;
-  }
-  return 0;
-}
-
-void thrd_yield(void)
-{
-#if defined(_TTHREAD_WIN32_)
-  Sleep(0);
-#else
-  sched_yield();
-#endif
-}
-
-int tss_create(tss_t *key, tss_dtor_t dtor)
-{
-#if defined(_TTHREAD_WIN32_)
-  /* FIXME: The destructor function is not supported yet... */
-  if (dtor != NULL)
-  {
-    return thrd_error;
-  }
-  *key = TlsAlloc();
-  if (*key == TLS_OUT_OF_INDEXES)
-  {
-    return thrd_error;
-  }
-#else
-  if (pthread_key_create(key, dtor) != 0)
-  {
-    return thrd_error;
-  }
-#endif
-  return thrd_success;
-}
-
-void tss_delete(tss_t key)
-{
-#if defined(_TTHREAD_WIN32_)
-  TlsFree(key);
-#else
-  pthread_key_delete(key);
-#endif
-}
-
-void *tss_get(tss_t key)
-{
-#if defined(_TTHREAD_WIN32_)
-  return TlsGetValue(key);
-#else
-  return pthread_getspecific(key);
-#endif
-}
-
-int tss_set(tss_t key, void *val)
-{
-#if defined(_TTHREAD_WIN32_)
-  if (TlsSetValue(key, val) == 0)
-  {
-    return thrd_error;
-  }
-#else
-  if (pthread_setspecific(key, val) != 0)
-  {
-    return thrd_error;
-  }
-#endif
-  return thrd_success;
-}
-
-#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
-int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
-{
-#if defined(_TTHREAD_WIN32_)
-  struct _timeb tb;
-  _ftime(&tb);
-  ts->tv_sec = (time_t)tb.time;
-  ts->tv_nsec = 1000000L * (long)tb.millitm;
-#else
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  ts->tv_sec = (time_t)tv.tv_sec;
-  ts->tv_nsec = 1000L * (long)tv.tv_usec;
-#endif
-  return 0;
-}
-#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
-
diff --git a/src/deps/tinycthread.h b/src/deps/tinycthread.h
deleted file mode 100644 (file)
index 42958c3..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
-Copyright (c) 2012 Marcus Geelnard
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-    1. The origin of this software must not be misrepresented; you must not
-    claim that you wrote the original software. If you use this software
-    in a product, an acknowledgment in the product documentation would be
-    appreciated but is not required.
-
-    2. Altered source versions must be plainly marked as such, and must not be
-    misrepresented as being the original software.
-
-    3. This notice may not be removed or altered from any source
-    distribution.
-*/
-
-#ifndef _TINYCTHREAD_H_
-#define _TINYCTHREAD_H_
-
-/**
-* @file
-* @mainpage TinyCThread API Reference
-*
-* @section intro_sec Introduction
-* TinyCThread is a minimal, portable implementation of basic threading
-* classes for C.
-*
-* They closely mimic the functionality and naming of the C11 standard, and
-* should be easily replaceable with the corresponding standard variants.
-*
-* @section port_sec Portability
-* The Win32 variant uses the native Win32 API for implementing the thread
-* classes, while for other systems, the POSIX threads API (pthread) is used.
-*
-* @section misc_sec Miscellaneous
-* The following special keywords are available: #_Thread_local.
-*
-* For more detailed information, browse the different sections of this
-* documentation. A good place to start is:
-* tinycthread.h.
-*/
-
-/* Which platform are we on? */
-#if !defined(_TTHREAD_PLATFORM_DEFINED_)
-  #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
-    #define _TTHREAD_WIN32_
-  #else
-    #define _TTHREAD_POSIX_
-  #endif
-  #define _TTHREAD_PLATFORM_DEFINED_
-#endif
-
-/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
-#if defined(_TTHREAD_POSIX_)
-  #undef _FEATURES_H
-  #if !defined(_GNU_SOURCE)
-    #define _GNU_SOURCE
-  #endif
-  #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
-    #undef _POSIX_C_SOURCE
-    #define _POSIX_C_SOURCE 199309L
-  #endif
-  #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
-    #undef _XOPEN_SOURCE
-    #define _XOPEN_SOURCE 500
-  #endif
-#endif
-
-/* Generic includes */
-#include <time.h>
-
-/* Platform specific includes */
-#if defined(_TTHREAD_POSIX_)
-  #include <sys/time.h>
-  #include <pthread.h>
-#elif defined(_TTHREAD_WIN32_)
-  #ifndef WIN32_LEAN_AND_MEAN
-    #define WIN32_LEAN_AND_MEAN
-    #define __UNDEF_LEAN_AND_MEAN
-  #endif
-  #include <windows.h>
-  #ifdef __UNDEF_LEAN_AND_MEAN
-    #undef WIN32_LEAN_AND_MEAN
-    #undef __UNDEF_LEAN_AND_MEAN
-  #endif
-#endif
-
-/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
-   it's quite likely that libc does not support it either. Hence, fall back to
-   the only other supported time specifier: CLOCK_REALTIME (and if that fails,
-   we're probably emulating clock_gettime anyway, so anything goes). */
-#ifndef TIME_UTC
-  #ifdef CLOCK_REALTIME
-    #define TIME_UTC CLOCK_REALTIME
-  #else
-    #define TIME_UTC 0
-  #endif
-#endif
-
-/* Workaround for missing clock_gettime (most Windows compilers, afaik) */
-#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__)
-#define _TTHREAD_EMULATE_CLOCK_GETTIME_
-/* Emulate struct timespec */
-#if defined(_TTHREAD_WIN32_)
-struct _ttherad_timespec {
-  time_t tv_sec;
-  long   tv_nsec;
-};
-#define timespec _ttherad_timespec
-#endif
-
-/* Emulate clockid_t */
-typedef int _tthread_clockid_t;
-#define clockid_t _tthread_clockid_t
-
-/* Emulate clock_gettime */
-int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
-#define clock_gettime _tthread_clock_gettime
-#ifndef CLOCK_REALTIME
-  #define CLOCK_REALTIME 0
-#endif
-#endif
-
-
-/** TinyCThread version (major number). */
-#define TINYCTHREAD_VERSION_MAJOR 1
-/** TinyCThread version (minor number). */
-#define TINYCTHREAD_VERSION_MINOR 1
-/** TinyCThread version (full version). */
-#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
-
-/**
-* @def _Thread_local
-* Thread local storage keyword.
-* A variable that is declared with the @c _Thread_local keyword makes the
-* value of the variable local to each thread (known as thread-local storage,
-* or TLS). Example usage:
-* @code
-* // This variable is local to each thread.
-* _Thread_local int variable;
-* @endcode
-* @note The @c _Thread_local keyword is a macro that maps to the corresponding
-* compiler directive (e.g. @c __declspec(thread)).
-* @note This directive is currently not supported on Mac OS X (it will give
-* a compiler error), since compile-time TLS is not supported in the Mac OS X
-* executable format. Also, some older versions of MinGW (before GCC 4.x) do
-* not support this directive.
-* @hideinitializer
-*/
-
-/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
-#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
- #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-  #define _Thread_local __thread
- #else
-  #define _Thread_local __declspec(thread)
- #endif
-#endif
-
-/* Macros */
-#define TSS_DTOR_ITERATIONS 0
-
-/* Function return values */
-#define thrd_error    0 /**< The requested operation failed */
-#define thrd_success  1 /**< The requested operation succeeded */
-#define thrd_timeout  2 /**< The time specified in the call was reached without acquiring the requested resource */
-#define thrd_busy     3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
-#define thrd_nomem    4 /**< The requested operation failed because it was unable to allocate memory */
-
-/* Mutex types */
-#define mtx_plain     1
-#define mtx_timed     2
-#define mtx_try       4
-#define mtx_recursive 8
-
-/* Mutex */
-#if defined(_TTHREAD_WIN32_)
-typedef struct {
-  CRITICAL_SECTION mHandle;   /* Critical section handle */
-  int mAlreadyLocked;         /* TRUE if the mutex is already locked */
-  int mRecursive;             /* TRUE if the mutex is recursive */
-} mtx_t;
-#else
-typedef pthread_mutex_t mtx_t;
-#endif
-
-/** Create a mutex object.
-* @param mtx A mutex object.
-* @param type Bit-mask that must have one of the following six values:
-*   @li @c mtx_plain for a simple non-recursive mutex
-*   @li @c mtx_timed for a non-recursive mutex that supports timeout
-*   @li @c mtx_try for a non-recursive mutex that supports test and return
-*   @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
-*   @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
-*   @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int mtx_init(mtx_t *mtx, int type);
-
-/** Release any resources used by the given mutex.
-* @param mtx A mutex object.
-*/
-void mtx_destroy(mtx_t *mtx);
-
-/** Lock the given mutex.
-* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
-* the calling thread already has a lock on the mutex, this call will block
-* forever.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int mtx_lock(mtx_t *mtx);
-
-/** NOT YET IMPLEMENTED.
-*/
-int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
-
-/** Try to lock the given mutex.
-* The specified mutex shall support either test and return or timeout. If the
-* mutex is already locked, the function returns without blocking.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_busy if the resource
-* requested is already in use, or @ref thrd_error if the request could not be
-* honored.
-*/
-int mtx_trylock(mtx_t *mtx);
-
-/** Unlock the given mutex.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int mtx_unlock(mtx_t *mtx);
-
-/* Condition variable */
-#if defined(_TTHREAD_WIN32_)
-typedef struct {
-  HANDLE mEvents[2];                  /* Signal and broadcast event HANDLEs. */
-  unsigned int mWaitersCount;         /* Count of the number of waiters. */
-  CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
-} cnd_t;
-#else
-typedef pthread_cond_t cnd_t;
-#endif
-
-/** Create a condition variable object.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int cnd_init(cnd_t *cond);
-
-/** Release any resources used by the given condition variable.
-* @param cond A condition variable object.
-*/
-void cnd_destroy(cnd_t *cond);
-
-/** Signal a condition variable.
-* Unblocks one of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int cnd_signal(cnd_t *cond);
-
-/** Broadcast a condition variable.
-* Unblocks all of the threads that are blocked on the given condition variable
-* at the time of the call. If no threads are blocked on the condition variable
-* at the time of the call, the function does nothing and return success.
-* @param cond A condition variable object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int cnd_broadcast(cnd_t *cond);
-
-/** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
-* before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int cnd_wait(cnd_t *cond, mtx_t *mtx);
-
-/** Wait for a condition variable to become signaled.
-* The function atomically unlocks the given mutex and endeavors to block until
-* the given condition variable is signaled by a call to cnd_signal or to
-* cnd_broadcast, or until after the specified time. When the calling thread
-* becomes unblocked it locks the mutex before it returns.
-* @param cond A condition variable object.
-* @param mtx A mutex object.
-* @param xt A point in time at which the request will time out (absolute time).
-* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
-* specified in the call was reached without acquiring the requested resource, or
-* @ref thrd_error if the request could not be honored.
-*/
-int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
-
-/* Thread */
-#if defined(_TTHREAD_WIN32_)
-typedef HANDLE thrd_t;
-#else
-typedef pthread_t thrd_t;
-#endif
-
-/** Thread start function.
-* Any thread that is started with the @ref thrd_create() function must be
-* started through a function of this type.
-* @param arg The thread argument (the @c arg argument of the corresponding
-*        @ref thrd_create() call).
-* @return The thread return value, which can be obtained by another thread
-* by using the @ref thrd_join() function.
-*/
-typedef int (*thrd_start_t)(void *arg);
-
-/** Create a new thread.
-* @param thr Identifier of the newly created thread.
-* @param func A function pointer to the function that will be executed in
-*        the new thread.
-* @param arg An argument to the thread function.
-* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
-* be allocated for the thread requested, or @ref thrd_error if the request
-* could not be honored.
-* @note A thread’s identifier may be reused for a different thread once the
-* original thread has exited and either been detached or joined to another
-* thread.
-*/
-int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
-
-/** Identify the calling thread.
-* @return The identifier of the calling thread.
-*/
-thrd_t thrd_current(void);
-
-/** NOT YET IMPLEMENTED.
-*/
-int thrd_detach(thrd_t thr);
-
-/** Compare two thread identifiers.
-* The function determines if two thread identifiers refer to the same thread.
-* @return Zero if the two thread identifiers refer to different threads.
-* Otherwise a nonzero value is returned.
-*/
-int thrd_equal(thrd_t thr0, thrd_t thr1);
-
-/** Terminate execution of the calling thread.
-* @param res Result code of the calling thread.
-*/
-void thrd_exit(int res);
-
-/** Wait for a thread to terminate.
-* The function joins the given thread with the current thread by blocking
-* until the other thread has terminated.
-* @param thr The thread to join with.
-* @param res If this pointer is not NULL, the function will store the result
-*        code of the given thread in the integer pointed to by @c res.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int thrd_join(thrd_t thr, int *res);
-
-/** Put the calling thread to sleep.
-* Suspend execution of the calling thread.
-* @param time_point A point in time at which the thread will resume (absolute time).
-* @param remaining If non-NULL, this parameter will hold the remaining time until
-*                  time_point upon return. This will typically be zero, but if
-*                  the thread was woken up by a signal that is not ignored before
-*                  time_point was reached @c remaining will hold a positive
-*                  time.
-* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
-*/
-int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
-
-/** Yield execution to another thread.
-* Permit other threads to run, even if the current thread would ordinarily
-* continue to run.
-*/
-void thrd_yield(void);
-
-/* Thread local storage */
-#if defined(_TTHREAD_WIN32_)
-typedef DWORD tss_t;
-#else
-typedef pthread_key_t tss_t;
-#endif
-
-/** Destructor function for a thread-specific storage.
-* @param val The value of the destructed thread-specific storage.
-*/
-typedef void (*tss_dtor_t)(void *val);
-
-/** Create a thread-specific storage.
-* @param key The unique key identifier that will be set if the function is
-*        successful.
-* @param dtor Destructor function. This can be NULL.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-* @note The destructor function is not supported under Windows. If @c dtor is
-* not NULL when calling this function under Windows, the function will fail
-* and return @ref thrd_error.
-*/
-int tss_create(tss_t *key, tss_dtor_t dtor);
-
-/** Delete a thread-specific storage.
-* The function releases any resources used by the given thread-specific
-* storage.
-* @param key The key that shall be deleted.
-*/
-void tss_delete(tss_t key);
-
-/** Get the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @return The value for the current thread held in the given thread-specific
-* storage.
-*/
-void *tss_get(tss_t key);
-
-/** Set the value for a thread-specific storage.
-* @param key The thread-specific storage identifier.
-* @param val The value of the thread-specific storage to set for the current
-*        thread.
-* @return @ref thrd_success on success, or @ref thrd_error if the request could
-* not be honored.
-*/
-int tss_set(tss_t key, void *val);
-
-
-#endif /* _TINYTHREAD_H_ */
-
index 89ee96227ea57771534d9260e521c1ead08da706..da5820dcd5f39c2f38856311a6e4c5e6730928da 100644 (file)
@@ -57,7 +57,7 @@ void _device_init (VkvgDevice dev, VkInstance inst, VkPhysicalDevice phy, VkDevi
 
        dev->phyMemProps = phyInfos->memProps;
        dev->gQueue = vkh_queue_create ((VkhDevice)dev, qFamIdx, qIndex);
-       mtx_init (&dev->gQMutex, mtx_plain);
+       //mtx_init (&dev->gQMutex, mtx_plain);
 
        vkh_phyinfo_destroy (phyInfos);
 
@@ -67,8 +67,6 @@ void _device_init (VkvgDevice dev, VkInstance inst, VkPhysicalDevice phy, VkDevi
        };
        vmaCreateAllocator(&allocatorInfo, &dev->allocator);
 
-       //dev->lastCtx= NULL;
-
        dev->cmdPool= vkh_cmd_pool_create               ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
        dev->cmd        = vkh_cmd_buff_create           ((VkhDevice)dev, dev->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
        dev->fence      = vkh_fence_create_signaled ((VkhDevice)dev);
@@ -300,8 +298,6 @@ void vkvg_device_destroy (VkvgDevice dev)
 
        vmaDestroyAllocator (dev->allocator);
 
-       mtx_destroy (&dev->gQMutex);
-
        if (dev->vkhDev) {
                VkhApp app = vkh_device_get_app (dev->vkhDev);
                vkh_device_destroy (dev->vkhDev);
@@ -331,6 +327,11 @@ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy) {
        *hdpy = dev->hdpi;
        *vdpy = dev->vdpi;
 }
+void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data) {
+       dev->gQBeforeSubmitGuard = before_submit;
+       dev->gQAfterSubmitGuard = after_submit;
+       dev->gQGuardUserData = user_data;
+}
 #if VKVG_DBG_STATS
 vkvg_debug_stats_t vkvg_device_get_stats (VkvgDevice dev) {
        return dev->debug_stats;
index f52c35d2a0c2d9ef1c3a47d0b4fd70724698cc17..d66df4c74bca88e231ec34418246c2d61adee041 100644 (file)
@@ -428,12 +428,11 @@ void _wait_and_reset_device_fence (VkvgDevice dev) {
 }
 
 void _submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) {
-       mtx_lock (&dev->gQMutex);
-       LOG(VKVG_LOG_THREADING, "[THREADING]start vk_cmd_submit  %16lx\n", (unsigned long)thrd_current());
+       if (dev->gQBeforeSubmitGuard)
+               dev->gQBeforeSubmitGuard (dev->gQGuardUserData);
        vkh_cmd_submit (dev->gQueue, cmd, fence);
-       vkDeviceWaitIdle(dev->vkDev);
-       LOG(VKVG_LOG_THREADING, "[THREADING]end vk_cmd_submit    %16lx\n", (unsigned long)thrd_current());
-       mtx_unlock (&dev->gQMutex);
+       if (dev->gQAfterSubmitGuard)
+               dev->gQAfterSubmitGuard (dev->gQGuardUserData);
 }
 
 bool _init_function_pointers (VkvgDevice dev) {
index e40f39cb96d6ef64653daafeeb2f72082cae288e..376b9c28ae125f73af71c786b8d22b94a38c34ea 100644 (file)
@@ -63,8 +63,11 @@ typedef struct _vkvg_device_t{
        VkFormat                                pngStagFormat;                  /**< Supported vulkan image format png write staging img */
        VkImageTiling                   pngStagTiling;                  /**< tiling for the blit operation */
 
+       vkvg_queue_guard                gQBeforeSubmitGuard;
+       vkvg_queue_guard                gQAfterSubmitGuard;
+       void*                                   gQGuardUserData;
        VkhQueue                                gQueue;                                 /**< Vulkan Queue with Graphic flag */
-       mtx_t                                   gQMutex;                                /**< queue submission has to be externally syncronized */
+
        VkRenderPass                    renderPass;                             /**< Vulkan render pass, common for all surfaces */
        VkRenderPass                    renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */
        VkRenderPass                    renderPass_ClearAll;    /**< Vulkan render pass for new surface, clear all attacments*/
index 01bb7a9b100fa31dafe2e33b82f47f9f9e1c8f5a..b22396b0110343d5784e4e5c68e6e6bd0bdf5fe1 100644 (file)
@@ -73,7 +73,6 @@
 #endif
 
 #include "cross_os.h"
-#include "deps/tinycthread.h"
 //width of the stencil buffer will determine the number of context saving/restore layers
 //the two first bits of the stencil are the FILL and the CLIP bits, all other bits are
 //used to store clipping bit on context saving. 8 bit stencil will allow 6 save/restore layer
index 99c4d35f6da74feb2580cc3e84603620866c45b6..cc4aa0a35ac33d3d4245fd8de0a2802d2ece5296 100644 (file)
@@ -17,7 +17,18 @@ void drawRandomRect (VkvgContext ctx, float s) {
 
        vkvg_rectangle(ctx, x, y, s, s);
 }
+void _before_submit (void* data) {
+       mtx_lock((mtx_t*)data);
+}
+void _after_submit (void* data) {
+       mtx_unlock((mtx_t*)data);
+}
+
 int drawRectsThread () {
+       mtx_t gQMutex;
+       mtx_init (&gQMutex, mtx_plain);
+       vkvg_device_set_queue_guards (device, _before_submit, _after_submit, &gQMutex);
+
        VkvgSurface s = vkvg_surface_create(device, test_width, test_height);
        VkvgContext ctx = vkvg_create(s);
        for (uint32_t i=0; i<test_size; i++) {
@@ -37,7 +48,9 @@ int drawRectsThread () {
 
        mtx_unlock(&mutex);
 
-       vkvg_surface_destroy(s);
+       vkvg_surface_destroy (s);
+       vkvg_device_set_queue_guards (device, NULL, NULL, NULL);
+       mtx_destroy (&gQMutex);
        return 0;
 }
 void fixedSizeRects(){
@@ -56,8 +69,6 @@ void fixedSizeRects(){
 }
 
 int main(int argc, char *argv[]) {
-       vkvg_log_level = VKVG_LOG_THREADING;
-
        PERFORM_TEST (fixedSizeRects, argc, argv);
        return 0;
 }