ossource.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions
  7. // are met:
  8. //
  9. // Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. //
  12. // Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following
  14. // disclaimer in the documentation and/or other materials provided
  15. // with the distribution.
  16. //
  17. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  18. // contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  29. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. // POSSIBILITY OF SUCH DAMAGE.
  33. //
  34. //
  35. // This file contains the Linux-specific functions
  36. //
  37. #include "../osinclude.h"
  38. #include "../../../OGLCompilersDLL/InitializeDll.h"
  39. #include <pthread.h>
  40. #include <semaphore.h>
  41. #include <assert.h>
  42. #include <errno.h>
  43. #include <stdint.h>
  44. #include <cstdio>
  45. #include <sys/time.h>
  46. #if !defined(__Fuchsia__)
  47. #include <sys/resource.h>
  48. #endif
  49. namespace glslang {
  50. //
  51. // Thread cleanup
  52. //
  53. //
  54. // Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects
  55. // the cleanup routine to return void.
  56. //
  57. static void DetachThreadLinux(void *)
  58. {
  59. DetachThread();
  60. }
  61. //
  62. // Registers cleanup handler, sets cancel type and state, and executes the thread specific
  63. // cleanup handler. This function will be called in the Standalone.cpp for regression
  64. // testing. When OpenGL applications are run with the driver code, Linux OS does the
  65. // thread cleanup.
  66. //
  67. void OS_CleanupThreadData(void)
  68. {
  69. #if defined(__ANDROID__) || defined(__Fuchsia__)
  70. DetachThreadLinux(NULL);
  71. #else
  72. int old_cancel_state, old_cancel_type;
  73. void *cleanupArg = NULL;
  74. //
  75. // Set thread cancel state and push cleanup handler.
  76. //
  77. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
  78. pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
  79. //
  80. // Put the thread in deferred cancellation mode.
  81. //
  82. pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
  83. //
  84. // Pop cleanup handler and execute it prior to unregistering the cleanup handler.
  85. //
  86. pthread_cleanup_pop(1);
  87. //
  88. // Restore the thread's previous cancellation mode.
  89. //
  90. pthread_setcanceltype(old_cancel_state, NULL);
  91. #endif
  92. }
  93. //
  94. // Thread Local Storage Operations
  95. //
  96. inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key)
  97. {
  98. return (OS_TLSIndex)((uintptr_t)key + 1);
  99. }
  100. inline pthread_key_t TLSIndexToPthreadKey(OS_TLSIndex nIndex)
  101. {
  102. return (pthread_key_t)((uintptr_t)nIndex - 1);
  103. }
  104. OS_TLSIndex OS_AllocTLSIndex()
  105. {
  106. pthread_key_t pPoolIndex;
  107. //
  108. // Create global pool key.
  109. //
  110. if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
  111. assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
  112. return OS_INVALID_TLS_INDEX;
  113. }
  114. else
  115. return PthreadKeyToTLSIndex(pPoolIndex);
  116. }
  117. bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
  118. {
  119. if (nIndex == OS_INVALID_TLS_INDEX) {
  120. assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
  121. return false;
  122. }
  123. if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0)
  124. return true;
  125. else
  126. return false;
  127. }
  128. void* OS_GetTLSValue(OS_TLSIndex nIndex)
  129. {
  130. //
  131. // This function should return 0 if nIndex is invalid.
  132. //
  133. assert(nIndex != OS_INVALID_TLS_INDEX);
  134. return pthread_getspecific(TLSIndexToPthreadKey(nIndex));
  135. }
  136. bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
  137. {
  138. if (nIndex == OS_INVALID_TLS_INDEX) {
  139. assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
  140. return false;
  141. }
  142. //
  143. // Delete the global pool key.
  144. //
  145. if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0)
  146. return true;
  147. else
  148. return false;
  149. }
  150. namespace {
  151. pthread_mutex_t gMutex;
  152. }
  153. void InitGlobalLock()
  154. {
  155. pthread_mutexattr_t mutexattr;
  156. pthread_mutexattr_init(&mutexattr);
  157. pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
  158. pthread_mutex_init(&gMutex, &mutexattr);
  159. }
  160. void GetGlobalLock()
  161. {
  162. pthread_mutex_lock(&gMutex);
  163. }
  164. void ReleaseGlobalLock()
  165. {
  166. pthread_mutex_unlock(&gMutex);
  167. }
  168. // #define DUMP_COUNTERS
  169. void OS_DumpMemoryCounters()
  170. {
  171. #ifdef DUMP_COUNTERS
  172. struct rusage usage;
  173. if (getrusage(RUSAGE_SELF, &usage) == 0)
  174. printf("Working set size: %ld\n", usage.ru_maxrss * 1024);
  175. #else
  176. printf("Recompile with DUMP_COUNTERS defined to see counters.\n");
  177. #endif
  178. }
  179. } // end namespace glslang