0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <pthread.h>
0039 #include <unistd.h>
0040 #include <ndrstandard.h>
0041 #include <errno.h>
0042 #include <sys/time.h>
0043
0044 #include <ndebug.h>
0045 #include <sys_unix.h>
0046
0047 #include "test000.h"
0048
0049
0050
0051
0052
0053
0054
0055
0056 exprivate pthread_mutex_t M_mut = PTHREAD_MUTEX_INITIALIZER;
0057 exprivate pthread_cond_t M_cond = PTHREAD_COND_INITIALIZER;
0058
0059
0060 __thread int M_field;
0061
0062 void *M_ptrs[3] = {NULL, NULL, NULL};
0063
0064 void* t1(void *arg)
0065 {
0066 M_ptrs[1] = &M_field;
0067 sleep(1);
0068 return NULL;
0069 }
0070
0071 void* t2(void *arg)
0072 {
0073 M_ptrs[2] = &M_field;
0074 sleep(1);
0075 return NULL;
0076 }
0077
0078 #ifdef EX_OS_DARWIN
0079
0080 void tim(void)
0081 {
0082 time_t timer;
0083 char buffer[26];
0084 struct tm* tm_info;
0085
0086 timer = time(NULL);
0087 tm_info = localtime(&timer);
0088
0089 strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
0090 fprintf(stderr, "%s\n", buffer);
0091
0092 }
0093
0094
0095
0096
0097
0098 void* osx_chk_thread(void *arg)
0099 {
0100 ndrx_osx_pthread_cond_t *p_cond;
0101 p_cond = (ndrx_osx_pthread_cond_t *)&M_cond;
0102
0103
0104 MUTEX_LOCK_V(M_mut);
0105
0106
0107 sleep(1);
0108 if ((char *)p_cond->busy != (char *)&M_mut)
0109 {
0110
0111
0112
0113 fprintf(stderr, "Cannot access busy field of Darwin pthread library for cond var: %p vs %p\n",
0114 p_cond->busy, &M_mut);
0115 exit(-1);
0116 }
0117 else
0118 {
0119 fprintf(stderr, "Cond var: %p vs %p OK\n", p_cond->busy, &M_mut);
0120 }
0121
0122 pthread_cond_signal( &M_cond );
0123 MUTEX_UNLOCK_V( M_mut );
0124
0125 return NULL;
0126 }
0127
0128
0129
0130
0131
0132
0133 int osx_chk_cond_work_around(void)
0134 {
0135 int ret = EXSUCCEED;
0136 ndrx_osx_pthread_cond_t *p_cond;
0137
0138 pthread_t valth={0};
0139 p_cond = (ndrx_osx_pthread_cond_t *)&M_cond;
0140
0141 MUTEX_LOCK_V(M_mut);
0142
0143 if( (ret=pthread_create( &valth, NULL, osx_chk_thread, NULL)) != 0)
0144 {
0145 fprintf(stderr, "Failed to create thread: %d", ret);
0146 return EXFAIL;
0147 }
0148
0149 p_cond->busy = NULL;
0150 ret = pthread_cond_wait(&M_cond, &M_mut);
0151 fprintf(stderr, "pthread_cond_wait 2: ret=%d (%s) mut=%p\n", ret, strerror(ret), &M_mut);
0152
0153 if (EXSUCCEED!=ret)
0154 {
0155 fprintf(stderr, "ret=%d Expected 0\n", ret);
0156 return EXFAIL;
0157 }
0158
0159 MUTEX_UNLOCK_V(M_mut);
0160
0161 pthread_join( valth, NULL );
0162
0163 ret = EXSUCCEED;
0164
0165 out:
0166 return ret;
0167
0168 }
0169 #endif
0170
0171 int main( int argc , char **argv )
0172 {
0173 pthread_t pth1={0}, pth2={0};
0174 void *mb1=0, *mb2 =0;
0175 pthread_attr_t pthrat={0};
0176 pthread_attr_init(&pthrat);
0177 pthread_attr_setstacksize(&pthrat, 1<<20);
0178 unsigned int n_pth=0;
0179
0180
0181 #ifdef EX_OS_DARWIN
0182
0183 if (EXSUCCEED!=osx_chk_cond_work_around())
0184 {
0185 fprintf(stderr, "OSX PTHREAD_PROCESS_SHARED Cond variable work-a-round does not work!\n");
0186 return EXFAIL;
0187 }
0188
0189 #endif
0190
0191 M_ptrs[0] = &M_field;
0192
0193 if( pthread_create( &pth1, &pthrat, t1,&mb1) == 0)
0194 n_pth += 1;
0195 if( pthread_create( &pth2, &pthrat, t2,&mb2) == 0)
0196 n_pth += 1;
0197 if( n_pth > 0 )
0198 pthread_join( pth1, &mb1 );
0199 if( n_pth > 1 )
0200 pthread_join( pth2, &mb2 );
0201 pthread_attr_destroy(&pthrat);
0202
0203 fprintf(stderr,"main : %p %p %p\n", M_ptrs[0], M_ptrs[1], M_ptrs[2]);
0204
0205 if (M_ptrs[0] == M_ptrs[1] || M_ptrs[0] == M_ptrs[2] ||
0206 M_ptrs[1] == M_ptrs[2])
0207 {
0208 fprintf(stderr, "TESTERROR: Thread Local Storage not working!\n");
0209 return -1;
0210 }
0211 else
0212 {
0213 fprintf(stderr, "Thread Local Storage OK!\n");
0214 return 0;
0215 }
0216 }
0217
0218
0219