globals.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /***************************************************************************
  2. lib/globals.c
  3. -------------------
  4. begin : Oct 2002
  5. copyright : (C) 2002 by Frank Mori Hess
  6. email : fmhess@users.sourceforge.net
  7. ***************************************************************************/
  8. /***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************/
  16. #include "ib_internal.h"
  17. #include <pthread.h>
  18. #include <stdlib.h>
  19. volatile int iberr = 0;
  20. volatile int ibsta = 0;
  21. volatile int ibcnt = 0;
  22. volatile long ibcntl = 0;
  23. static pthread_key_t ibsta_key;
  24. static pthread_key_t iberr_key;
  25. static pthread_key_t ibcntl_key;
  26. static pthread_once_t global_keys_once = PTHREAD_ONCE_INIT;
  27. static void ibsta_destroy( void *thread_ibsta )
  28. {
  29. if( thread_ibsta )
  30. {
  31. free( thread_ibsta );
  32. thread_ibsta = NULL;
  33. }
  34. }
  35. static void iberr_destroy( void *thread_iberr )
  36. {
  37. if( thread_iberr )
  38. {
  39. free( thread_iberr );
  40. thread_iberr = NULL;
  41. }
  42. }
  43. static void ibcntl_destroy( void *thread_ibcntl )
  44. {
  45. if( thread_ibcntl )
  46. {
  47. free( thread_ibcntl );
  48. thread_ibcntl = NULL;
  49. }
  50. }
  51. static void global_keys_alloc()
  52. {
  53. int retval;
  54. retval = pthread_key_create( &ibsta_key, ibsta_destroy );
  55. if( retval ) fprintf( stderr, "libgpib: failed to allocate TSD key!\n" );
  56. retval = pthread_key_create( &iberr_key, iberr_destroy );
  57. if( retval ) fprintf( stderr, "libgpib: failed to allocate TSD key!\n" );
  58. retval = pthread_key_create( &ibcntl_key, ibcntl_destroy );
  59. if( retval ) fprintf( stderr, "libgpib: failed to allocate TSD key!\n" );
  60. }
  61. void globals_alloc( void )
  62. {
  63. int *ibsta_p, *iberr_p, *ibcntl_p;
  64. pthread_once( &global_keys_once, global_keys_alloc );
  65. if( pthread_getspecific( ibsta_key ) == NULL )
  66. {
  67. ibsta_p = malloc( sizeof( int ) );
  68. if( ibsta_p == NULL )
  69. fprintf( stderr, "libgpib: failed to allocate ibsta!\n" );
  70. iberr_p = malloc( sizeof( int ) );
  71. if( iberr_p == NULL )
  72. fprintf( stderr, "libgpib: failed to allocate iberr!\n" );
  73. ibcntl_p = malloc( sizeof( long ) );
  74. if( ibcntl_p == NULL )
  75. fprintf( stderr, "libgpib: failed to allocate ibcntl!\n" );
  76. *ibsta_p = 0;
  77. *iberr_p = 0;
  78. *ibcntl_p = 0;
  79. pthread_setspecific( ibsta_key, ibsta_p );
  80. pthread_setspecific( iberr_key, iberr_p );
  81. pthread_setspecific( ibcntl_key, ibcntl_p );
  82. }
  83. }
  84. void setIbsta( int status )
  85. {
  86. int *thread_ibsta;
  87. globals_alloc();
  88. thread_ibsta = pthread_getspecific( ibsta_key );
  89. if( thread_ibsta == NULL )
  90. {
  91. fprintf( stderr, "libgpib: failed to set ibsta TSD\n" );
  92. return;
  93. }
  94. *thread_ibsta = status;
  95. }
  96. void setIberr( int error )
  97. {
  98. int *thread_iberr;
  99. globals_alloc();
  100. thread_iberr = pthread_getspecific( iberr_key );
  101. if( thread_iberr == NULL )
  102. {
  103. fprintf( stderr, "libgpib: failed to set iberr TSD\n" );
  104. return;
  105. }
  106. *thread_iberr = error;
  107. }
  108. void setIbcnt( long count )
  109. {
  110. int *thread_ibcntl;
  111. globals_alloc();
  112. thread_ibcntl = pthread_getspecific( ibcntl_key );
  113. if( thread_ibcntl == NULL )
  114. {
  115. fprintf( stderr, "libgpib: failed to set ibcntl TSD\n" );
  116. return;
  117. }
  118. *thread_ibcntl = count;
  119. }
  120. int ThreadIbsta( void )
  121. {
  122. int *thread_ibsta;
  123. globals_alloc();
  124. thread_ibsta = pthread_getspecific( ibsta_key );
  125. if( thread_ibsta == NULL )
  126. {
  127. fprintf( stderr, "libgpib: failed to get ibsta TSD\n" );
  128. return ERR;
  129. }
  130. return *thread_ibsta;
  131. }
  132. int ThreadIberr( void )
  133. {
  134. int *thread_iberr;
  135. globals_alloc();
  136. thread_iberr = pthread_getspecific( iberr_key );
  137. if( thread_iberr == NULL )
  138. {
  139. fprintf( stderr, "libgpib: failed to get iberr TSD\n" );
  140. return EDVR;
  141. }
  142. return *thread_iberr;
  143. }
  144. int ThreadIbcnt( void )
  145. {
  146. return ThreadIbcntl();
  147. }
  148. long ThreadIbcntl( void )
  149. {
  150. int *thread_ibcntl;
  151. globals_alloc();
  152. thread_ibcntl = pthread_getspecific( ibcntl_key );
  153. if( thread_ibcntl == NULL )
  154. {
  155. fprintf( stderr, "libgpib: failed to get ibcntl TSD\n" );
  156. return 0;
  157. }
  158. return *thread_ibcntl;
  159. }
  160. void sync_globals( void )
  161. {
  162. ibsta = ThreadIbsta();
  163. iberr = ThreadIberr();
  164. ibcntl = ThreadIbcnt();
  165. ibcnt = ibcntl;
  166. }