This source file includes following definitions.
- lock_simh
- unlock_simh
- lock_libuv
- unlock_libuv
- test_libuv_lock
- get_rmw_lock
- lock_rmw
- lock_mem_rd
- lock_mem_wr
- unlock_rmw
- unlock_mem
- unlock_mem_force
- lock_ptr
- unlock_ptr
- lock_scu
- unlock_scu
- lock_iom
- unlock_iom
- lock_tst
- unlock_tst
- test_tst_lock
- pthread_create_with_cpu_policy
- createCPUThread
- stopCPUThread
- cpuRunningWait
- sleepCPU
- wakeCPU
- createIOMThread
- iomInterruptWait
- iomInterruptDone
- iomDoneWait
- setIOMInterrupt
- iomRdyWait
- createChnThread
- chnConnectWait
- chnConnectDone
- setChnConnect
- chnRdyWait
- initThreadz
- setSignals
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <signal.h>
24
25 #include "dps8.h"
26 #include "dps8_sys.h"
27 #include "dps8_cpu.h"
28 #include "dps8_faults.h"
29 #include "dps8_iom.h"
30 #include "dps8_utils.h"
31
32 #include "threadz.h"
33 #if defined(__FreeBSD__) || defined(__OpenBSD__)
34 # include <pthread_np.h>
35 #endif
36
37
38
39
40
41
42
43 #if defined(IO_ASYNC_PAYLOAD_CHAN_THREAD)
44 pthread_cond_t iomCond;
45 pthread_mutex_t iom_start_lock;
46 #endif
47
48 #if !defined(QUIET_UNUSED)
49 void lock_simh (void)
50 {
51 pthread_mutex_lock (& simh_lock);
52 }
53
54 void unlock_simh (void)
55 {
56 pthread_mutex_unlock (& simh_lock);
57 }
58 #endif
59
60
61
62 static pthread_mutex_t libuv_lock;
63
64 void lock_libuv (void)
65 {
66 pthread_mutex_lock (& libuv_lock);
67 }
68
69 void unlock_libuv (void)
70 {
71 pthread_mutex_unlock (& libuv_lock);
72 }
73
74 #if defined(TESTING)
75 bool test_libuv_lock (void)
76 {
77
78 int rc;
79 rc = pthread_mutex_trylock (& libuv_lock);
80 if (rc)
81 {
82
83 return true;
84 }
85
86 rc = pthread_mutex_unlock (& libuv_lock);
87 if (rc)
88 sim_printf ("test_libuv_lock pthread_mutex_lock libuv_lock %d\n", rc);
89 return false;
90 }
91 #endif
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 #if !defined(LOCKLESS)
113 pthread_rwlock_t mem_lock = PTHREAD_RWLOCK_INITIALIZER;
114 static __thread bool have_mem_lock = false;
115 static __thread bool have_rmw_lock = false;
116
117 bool get_rmw_lock (void)
118 {
119 return have_rmw_lock;
120 }
121
122 void lock_rmw (void)
123 {
124 if (have_rmw_lock)
125 {
126 sim_warn ("%s: Already have RMW lock\n", __func__);
127 return;
128 }
129 if (have_mem_lock)
130 {
131 sim_warn ("%s: Already have memory lock\n", __func__);
132 return;
133 }
134 int rc= pthread_rwlock_wrlock (& mem_lock);
135 if (rc)
136 sim_printf ("%s pthread_rwlock_rdlock mem_lock %d\n", __func__, rc);
137 have_mem_lock = true;
138 have_rmw_lock = true;
139 }
140
141 void lock_mem_rd (void)
142 {
143
144 if (have_rmw_lock)
145 return;
146
147 if (have_mem_lock)
148 {
149 sim_warn ("%s: Already have memory lock\n", __func__);
150 return;
151 }
152 int rc= pthread_rwlock_rdlock (& mem_lock);
153 if (rc)
154 sim_printf ("%s pthread_rwlock_rdlock mem_lock %d\n", __func__, rc);
155 have_mem_lock = true;
156 }
157
158 void lock_mem_wr (void)
159 {
160
161 if (have_rmw_lock)
162 return;
163
164 if (have_mem_lock)
165 {
166 sim_warn ("%s: Already have memory lock\n", __func__);
167 return;
168 }
169 int rc= pthread_rwlock_wrlock (& mem_lock);
170 if (rc)
171 sim_printf ("%s pthread_rwlock_wrlock mem_lock %d\n", __func__, rc);
172 have_mem_lock = true;
173 }
174
175 void unlock_rmw (void)
176 {
177 if (! have_mem_lock)
178 {
179 sim_warn ("%s: Don't have memory lock\n", __func__);
180 return;
181 }
182 if (! have_rmw_lock)
183 {
184 sim_warn ("%s: Don't have RMW lock\n", __func__);
185 return;
186 }
187
188 int rc = pthread_rwlock_unlock (& mem_lock);
189 if (rc)
190 sim_printf ("%s pthread_rwlock_ublock mem_lock %d\n", __func__, rc);
191 have_mem_lock = false;
192 have_rmw_lock = false;
193 }
194
195 void unlock_mem (void)
196 {
197 if (have_rmw_lock)
198 return;
199 if (! have_mem_lock)
200 {
201 sim_warn ("%s: Don't have memory lock\n", __func__);
202 return;
203 }
204
205 int rc = pthread_rwlock_unlock (& mem_lock);
206 if (rc)
207 sim_printf ("%s pthread_rwlock_ublock mem_lock %d\n", __func__, rc);
208 have_mem_lock = false;
209 }
210
211 void unlock_mem_force (void)
212 {
213 if (have_mem_lock)
214 {
215 int rc = pthread_rwlock_unlock (& mem_lock);
216 if (rc)
217 sim_printf ("%s pthread_rwlock_unlock mem_lock %d\n", __func__, rc);
218 }
219 have_mem_lock = false;
220 have_rmw_lock = false;
221 }
222 #endif
223
224
225
226 void lock_ptr (pthread_mutex_t * lock)
227 {
228 int rc;
229 rc = pthread_mutex_lock (lock);
230 if (rc)
231 sim_printf ("lock_ptr %d\n", rc);
232 }
233
234 void unlock_ptr (pthread_mutex_t * lock)
235 {
236
237 int rc;
238 rc = pthread_mutex_unlock (lock);
239 if (rc)
240 sim_printf ("unlock_ptr %d\n", rc);
241 }
242
243
244
245 static pthread_mutex_t scu_lock;
246
247 void lock_scu (void)
248 {
249
250 int rc;
251 rc = pthread_mutex_lock (& scu_lock);
252 if (rc)
253 sim_printf ("lock_scu pthread_spin_lock scu %d\n", rc);
254 }
255
256 void unlock_scu (void)
257 {
258
259 int rc;
260 rc = pthread_mutex_unlock (& scu_lock);
261 if (rc)
262 sim_printf ("unlock_scu pthread_spin_lock scu %d\n", rc);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 static pthread_mutex_t iom_lock;
287
288 void lock_iom (void)
289 {
290 int rc;
291 rc = pthread_mutex_lock (& iom_lock);
292 if (rc)
293 sim_printf ("%s pthread_spin_lock iom %d\n", __func__, rc);
294 }
295
296 void unlock_iom (void)
297 {
298 int rc;
299 rc = pthread_mutex_unlock (& iom_lock);
300 if (rc)
301 sim_printf ("%s pthread_spin_lock iom %d\n", __func__, rc);
302 }
303
304
305
306 #if defined(TESTING)
307 static pthread_mutex_t tst_lock = PTHREAD_MUTEX_INITIALIZER;
308
309 void lock_tst (void)
310 {
311
312 int rc;
313 rc = pthread_mutex_lock (& tst_lock);
314 if (rc)
315 sim_printf ("lock_tst pthread_mutex_lock tst_lock %d\n", rc);
316 }
317
318 void unlock_tst (void)
319 {
320
321 int rc;
322 rc = pthread_mutex_unlock (& tst_lock);
323 if (rc)
324 sim_printf ("unlock_tst pthread_mutex_lock tst_lock %d\n", rc);
325 }
326
327
328
329 bool test_tst_lock (void)
330 {
331
332 int rc;
333 rc = pthread_mutex_trylock (& tst_lock);
334 if (rc)
335 {
336
337 return true;
338 }
339
340 rc = pthread_mutex_unlock (& tst_lock);
341 if (rc)
342 sim_printf ("test_tst_lock pthread_mutex_lock tst_lock %d\n", rc);
343 return false;
344 }
345 #endif
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 struct cpuThreadz_t cpuThreadz [N_CPU_UNITS_MAX];
374
375
376
377 #if defined(__APPLE__)
378 int pthread_create_with_cpu_policy(
379 pthread_t *restrict thread,
380 int policy_group,
381 const pthread_attr_t *restrict attr,
382 void *(*start_routine)(void *), void *restrict arg)
383 {
384 # if defined(TESTING)
385 sim_msg ("\rAffinity policy group %d requested for thread.\r\n", policy_group);
386 # endif
387 thread_affinity_policy_data_t policy_data = { policy_group };
388 int rv = pthread_create_suspended_np(thread, attr, start_routine, arg);
389 mach_port_t mach_thread = pthread_mach_thread_np(*thread);
390 if (rv != 0)
391 {
392 return rv;
393 }
394 thread_policy_set(
395 mach_thread,
396 THREAD_AFFINITY_POLICY,
397 (thread_policy_t)&policy_data,
398 THREAD_AFFINITY_POLICY_COUNT);
399 thread_resume(mach_thread);
400 return 0;
401 }
402 #endif
403
404
405
406 void createCPUThread (uint cpuNum)
407 {
408 int rc;
409 struct cpuThreadz_t * p = & cpuThreadz[cpuNum];
410 if (p->run)
411 return;
412 cpu_reset_unit_idx (cpuNum, false);
413 p->cpuThreadArg = (int) cpuNum;
414
415
416 #if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__linux__) && defined(__GLIBC__))
417 pthread_mutexattr_t sleep_attr;
418 pthread_mutexattr_init(&sleep_attr);
419 # if !defined(__OpenBSD__)
420 pthread_mutexattr_settype(&sleep_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
421 # endif
422 rc = pthread_mutex_init (& p->sleepLock, &sleep_attr);
423 #else
424 rc = pthread_mutex_init (& p->sleepLock, NULL);
425 #endif
426 if (rc)
427 sim_printf ("createCPUThread pthread_mutex_init sleepLock %d\n", rc);
428
429 rc = pthread_mutex_init (& p->runLock, NULL);
430 if (rc)
431 sim_printf ("createCPUThread pthread_mutex_init runLock %d\n", rc);
432
433 rc = pthread_cond_init (& p->runCond, NULL);
434 if (rc)
435 sim_printf ("createCPUThread pthread_cond_init runCond %d\n", rc);
436
437 p->run = true;
438 p->sleeping = false;
439
440
441 #if defined(USE_MONOTONIC)
442 # if defined(__APPLE__) || !defined(CLOCK_MONOTONIC)
443 p->sleepClock = CLOCK_REALTIME;
444 rc = pthread_cond_init (& p->sleepCond, NULL);
445 # else
446 rc = pthread_condattr_init (& p->sleepCondAttr);
447 if (rc)
448 sim_printf ("createCPUThread pthread_condattr_init sleepCond %d\n", rc);
449
450 rc = pthread_condattr_setclock (& p->sleepCondAttr, CLOCK_MONOTONIC);
451 if (rc) {
452
453 p->sleepClock = CLOCK_REALTIME;
454 } else {
455 p->sleepClock = CLOCK_MONOTONIC;
456 }
457 # endif
458 rc = pthread_cond_init (& p->sleepCond, & p->sleepCondAttr);
459 #else
460 rc = pthread_cond_init (& p->sleepCond, NULL);
461 #endif
462 if (rc)
463 sim_printf ("createCPUThread pthread_cond_init sleepCond %d\n", rc);
464
465 #if defined(__APPLE__)
466 rc = pthread_create_with_cpu_policy(
467 & p->cpuThread,
468 cpuNum,
469 NULL,
470 cpu_thread_main,
471 & p->cpuThreadArg);
472 #else
473 rc = pthread_create(
474 & p->cpuThread,
475 NULL,
476 cpu_thread_main,
477 & p->cpuThreadArg);
478 #endif
479 if (rc)
480 sim_printf ("createCPUThread pthread_create %d\n", rc);
481
482 #if defined(AFFINITY)
483 if (cpus[cpuNum].set_affinity)
484 {
485 cpu_set_t cpuset;
486 CPU_ZERO (& cpuset);
487 CPU_SET (cpus[cpuNum].affinity, & cpuset);
488 int s = pthread_setaffinity_np (p->cpuThread, sizeof (cpu_set_t), & cpuset);
489 if (s)
490 sim_printf ("pthread_setaffinity_np %u on CPU %u returned %d\n",
491 cpus[cpuNum].affinity, cpuNum, s);
492 }
493 #endif
494 }
495
496 void stopCPUThread(void)
497 {
498 struct cpuThreadz_t * p = & cpuThreadz[current_running_cpu_idx];
499 p->run = false;
500 pthread_exit(NULL);
501 }
502
503
504
505 #if defined(THREADZ)
506 void cpuRunningWait (void)
507 {
508 int rc;
509 struct cpuThreadz_t * p = & cpuThreadz[current_running_cpu_idx];
510 if (p->run)
511 return;
512 rc = pthread_mutex_lock (& p->runLock);
513 if (rc)
514 sim_printf ("cpuRunningWait pthread_mutex_lock %d\n", rc);
515 while (! p->run)
516 {
517 rc = pthread_cond_wait (& p->runCond, & p->runLock);
518 if (rc)
519 sim_printf ("cpuRunningWait pthread_cond_wait %d\n", rc);
520 }
521 rc = pthread_mutex_unlock (& p->runLock);
522 if (rc)
523 sim_printf ("cpuRunningWait pthread_mutex_unlock %d\n", rc);
524 }
525 #endif
526
527
528
529 unsigned long sleepCPU (unsigned long usec) {
530 int rc;
531 struct cpuThreadz_t * p = & cpuThreadz[current_running_cpu_idx];
532 struct timespec startTime, absTime;
533
534 #if defined(USE_MONOTONIC)
535 clock_gettime (p->sleepClock, & startTime);
536 #else
537 clock_gettime (CLOCK_REALTIME, & startTime);
538 #endif
539 absTime = startTime;
540 int64_t nsec = ((int64_t) usec) * 1000L + (int64_t)startTime.tv_nsec;
541 absTime.tv_nsec = nsec % 1000000000L;
542 absTime.tv_sec += nsec / 1000000000L;
543
544 rc = pthread_mutex_lock (& p->sleepLock);
545 if (rc)
546 sim_printf ("sleepCPU pthread_mutex_lock sleepLock %d\n", rc);
547
548 p->sleeping = true;
549 rc = pthread_cond_timedwait (& p->sleepCond, & p->sleepLock, & absTime);
550 p->sleeping = false;
551
552 int rc2 = pthread_mutex_unlock (& p->sleepLock);
553 if (rc2)
554 sim_printf ("sleepCPU pthread_mutex_unlock sleepLock %d\n", rc2);
555
556 if (rc == ETIMEDOUT) {
557 return 0;
558 }
559
560 if (rc) {
561 cpu_state_t * cpup = _cpup;
562 sim_printf ("sleepCPU pthread_cond_timedwait rc %ld usec %ld TR %lu CPU %lu\n",
563 (long) rc, (long) usec, (unsigned long) cpu.rTR,
564 (unsigned long) current_running_cpu_idx);
565 }
566
567 struct timespec newTime;
568 struct timespec delta;
569 #if defined(USE_MONOTONIC)
570 clock_gettime (p->sleepClock, & newTime);
571 #else
572 clock_gettime (CLOCK_REALTIME, & newTime);
573 #endif
574 timespec_diff (& absTime, & newTime, & delta);
575
576 if (delta.tv_nsec < 0)
577 return 0;
578 return (unsigned long) delta.tv_nsec / 1000L;
579 }
580
581
582
583 void wakeCPU (uint cpuNum)
584 {
585 int rc;
586 struct cpuThreadz_t * p = & cpuThreadz[cpuNum];
587
588 rc = pthread_mutex_lock (& p->sleepLock);
589 if (rc)
590 sim_printf ("sleepCPU pthread_mutex_lock sleepLock %d\n", rc);
591
592 if (p->sleeping) {
593 rc = pthread_cond_signal (& p->sleepCond);
594 if (rc)
595 sim_printf ("wakeCPU pthread_cond_signal %d\n", rc);
596 }
597
598 int rc2 = pthread_mutex_unlock (& p->sleepLock);
599 if (rc2)
600 sim_printf ("sleepCPU pthread_mutex_unlock sleepLock %d\n", rc2);
601 }
602
603 #if defined(IO_THREADZ)
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 struct iomThreadz_t iomThreadz [N_IOM_UNITS_MAX];
628
629
630
631 void createIOMThread (uint iomNum)
632 {
633 int rc;
634 struct iomThreadz_t * p = & iomThreadz[iomNum];
635 # if defined(tdbg)
636 p->inCnt = 0;
637 p->outCnt = 0;
638 # endif
639 p->iomThreadArg = (int) iomNum;
640
641 p->ready = false;
642
643 p->intr = false;
644 rc = pthread_mutex_init (& p->intrLock, NULL);
645 if (rc)
646 sim_printf ("createIOMThread pthread_mutex_init intrLock %d\n", rc);
647 rc = pthread_cond_init (& p->intrCond, NULL);
648 if (rc)
649 sim_printf ("createIOMThread pthread_cond_init intrCond %d\n", rc);
650
651 # if defined(__APPLE__)
652 rc = pthread_create_with_cpu_policy(
653 & p->iomThread,
654 iomNum,
655 NULL,
656 iom_thread_main,
657 & p->iomThreadArg);
658 # else
659 rc = pthread_create(
660 & p->iomThread,
661 NULL,
662 iom_thread_main,
663 & p->iomThreadArg);
664 # endif
665 if (rc)
666 sim_printf ("createIOMThread pthread_create %d\n", rc);
667 }
668
669
670
671 void iomInterruptWait (void)
672 {
673 int rc;
674 struct iomThreadz_t * p = & iomThreadz[this_iom_idx];
675 rc = pthread_mutex_lock (& p->intrLock);
676 if (rc)
677 sim_printf ("iomInterruptWait pthread_mutex_lock %d\n", rc);
678 p -> ready = true;
679 while (! p->intr)
680 {
681 rc = pthread_cond_wait (& p->intrCond, & p->intrLock);
682 if (rc)
683 sim_printf ("iomInterruptWait pthread_cond_wait %d\n", rc);
684 }
685 # if defined(tdbg)
686 p->outCnt++;
687 if (p->inCnt != p->outCnt)
688 sim_printf ("iom thread %d in %d out %d\n", this_iom_idx,
689 p->inCnt, p->outCnt);
690 # endif
691 }
692
693
694
695 void iomInterruptDone (void)
696 {
697 int rc;
698 struct iomThreadz_t * p = & iomThreadz[this_iom_idx];
699 p->intr = false;
700 rc = pthread_cond_signal (& p->intrCond);
701 if (rc)
702 sim_printf ("iomInterruptDone pthread_cond_signal %d\n", rc);
703 rc = pthread_mutex_unlock (& p->intrLock);
704 if (rc)
705 sim_printf ("iomInterruptDone pthread_mutex_unlock %d\n", rc);
706 }
707
708
709
710 void iomDoneWait (uint iomNum)
711 {
712 int rc;
713 struct iomThreadz_t * p = & iomThreadz[iomNum];
714 rc = pthread_mutex_lock (& p->intrLock);
715 if (rc)
716 sim_printf ("iomDoneWait pthread_mutex_lock %d\n", rc);
717 while (p->intr)
718 {
719 rc = pthread_cond_wait (& p->intrCond, & p->intrLock);
720 if (rc)
721 sim_printf ("iomDoneWait pthread_cond_wait %d\n", rc);
722 }
723 rc = pthread_mutex_unlock (& p->intrLock);
724 if (rc)
725 sim_printf ("iomDoneWait pthread_mutex_unlock %d\n", rc);
726 }
727
728
729
730 void setIOMInterrupt (uint iomNum)
731 {
732 int rc;
733 struct iomThreadz_t * p = & iomThreadz[iomNum];
734 rc = pthread_mutex_lock (& p->intrLock);
735 if (rc)
736 sim_printf ("setIOMInterrupt pthread_mutex_lock %d\n", rc);
737 while (p->intr)
738 {
739 rc = pthread_cond_wait(&p->intrCond, &p->intrLock);
740 if (rc)
741 sim_printf ("setIOMInterrupt pthread_cond_wait intrLock %d\n", rc);
742 }
743 # if defined(tdbg)
744 p->inCnt++;
745 # endif
746 p->intr = true;
747 rc = pthread_cond_signal (& p->intrCond);
748 if (rc)
749 sim_printf ("setIOMInterrupt pthread_cond_signal %d\n", rc);
750 rc = pthread_mutex_unlock (& p->intrLock);
751 if (rc)
752 sim_printf ("setIOMInterrupt pthread_mutex_unlock %d\n", rc);
753 }
754
755
756
757 void iomRdyWait (uint iomNum)
758 {
759 struct iomThreadz_t * p = & iomThreadz[iomNum];
760 while (! p -> ready)
761 sim_usleep (10000);
762 }
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786 struct chnThreadz_t chnThreadz [N_IOM_UNITS_MAX] [MAX_CHANNELS];
787
788
789
790 void createChnThread (uint iomNum, uint chnNum, const char * devTypeStr)
791 {
792 int rc;
793 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
794 p->chnThreadArg = (int) (chnNum + iomNum * MAX_CHANNELS);
795
796 # if defined(tdbg)
797 p->inCnt = 0;
798 p->outCnt = 0;
799 # endif
800 p->ready = false;
801
802 p->connect = false;
803 rc = pthread_mutex_init (& p->connectLock, NULL);
804 if (rc)
805 sim_printf ("createChnThread pthread_mutex_init connectLock %d\n", rc);
806 rc = pthread_cond_init (& p->connectCond, NULL);
807 if (rc)
808 sim_printf ("createChnThread pthread_cond_init connectCond %d\n", rc);
809
810 # if defined(__APPLE__)
811 rc = pthread_create_with_cpu_policy(
812 & p->chnThread,
813 iomNum
814 NULL,
815 chan_thread_main,
816 & p->chnThreadArg);
817 # else
818 rc = pthread_create(
819 & p->chnThread,
820 NULL,
821 chan_thread_main,
822 & p->chnThreadArg);
823 # endif
824 if (rc)
825 sim_printf ("createChnThread pthread_create %d\n", rc);
826 }
827
828
829
830 void chnConnectWait (void)
831 {
832 int rc;
833 struct chnThreadz_t * p = & chnThreadz[this_iom_idx][this_chan_num];
834
835 rc = pthread_mutex_lock (& p->connectLock);
836 if (rc)
837 sim_printf ("chnConnectWait pthread_mutex_lock %d\n", rc);
838 p -> ready = true;
839 while (! p->connect)
840 {
841 rc = pthread_cond_wait (& p->connectCond, & p->connectLock);
842 if (rc)
843 sim_printf ("chnConnectWait pthread_cond_wait %d\n", rc);
844 }
845 # if defined(tdbg)
846 p->outCnt++;
847 if (p->inCnt != p->outCnt)
848 sim_printf ("chn thread %d in %d out %d\n", this_chan_num,
849 p->inCnt, p->outCnt);
850 # endif
851 }
852
853
854
855 void chnConnectDone (void)
856 {
857 int rc;
858 struct chnThreadz_t * p = & chnThreadz[this_iom_idx][this_chan_num];
859 p->connect = false;
860 rc = pthread_cond_signal (& p->connectCond);
861 if (rc)
862 sim_printf ("chnInterruptDone pthread_cond_signal %d\n", rc);
863 rc = pthread_mutex_unlock (& p->connectLock);
864 if (rc)
865 sim_printf ("chnConnectDone pthread_mutex_unlock %d\n", rc);
866 }
867
868
869
870 void setChnConnect (uint iomNum, uint chnNum)
871 {
872 int rc;
873 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
874 rc = pthread_mutex_lock (& p->connectLock);
875 if (rc)
876 sim_printf ("setChnConnect pthread_mutex_lock %d\n", rc);
877 while (p->connect)
878 {
879 rc = pthread_cond_wait(&p->connectCond, &p->connectLock);
880 if (rc)
881 sim_printf ("setChnInterrupt pthread_cond_wait connectLock %d\n", rc);
882 }
883 # if defined(tdbg)
884 p->inCnt++;
885 # endif
886 p->connect = true;
887 rc = pthread_cond_signal (& p->connectCond);
888 if (rc)
889 sim_printf ("setChnConnect pthread_cond_signal %d\n", rc);
890 rc = pthread_mutex_unlock (& p->connectLock);
891 if (rc)
892 sim_printf ("setChnConnect pthread_mutex_unlock %d\n", rc);
893 }
894
895
896
897 void chnRdyWait (uint iomNum, uint chnNum)
898 {
899 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
900 while (! p -> ready)
901 sim_usleep (10000);
902 }
903 #endif
904
905 void initThreadz (void)
906 {
907 #if defined(IO_THREADZ)
908
909 (void)memset (chnThreadz, 0, sizeof (chnThreadz));
910 #endif
911
912 #if !defined(LOCKLESS)
913
914 have_mem_lock = false;
915 have_rmw_lock = false;
916 #endif
917 #if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__linux__) && defined(__GLIBC__))
918 pthread_mutexattr_t scu_attr;
919 pthread_mutexattr_init(&scu_attr);
920 # if !defined(__OpenBSD__)
921 pthread_mutexattr_settype(&scu_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
922 # endif
923 pthread_mutex_init (& scu_lock, &scu_attr);
924 #else
925 pthread_mutex_init (& scu_lock, NULL);
926 #endif
927 pthread_mutexattr_t iom_attr;
928 pthread_mutexattr_init(& iom_attr);
929 pthread_mutexattr_settype(& iom_attr, PTHREAD_MUTEX_RECURSIVE);
930
931 pthread_mutex_init (& iom_lock, & iom_attr);
932
933 pthread_mutexattr_t libuv_attr;
934 pthread_mutexattr_init(& libuv_attr);
935 pthread_mutexattr_settype(& libuv_attr, PTHREAD_MUTEX_RECURSIVE);
936
937 pthread_mutex_init (& libuv_lock, & libuv_attr);
938
939 #if defined(IO_ASYNC_PAYLOAD_CHAN_THREAD)
940 pthread_cond_init (& iomCond, NULL);
941 pthread_mutex_init (& iom_start_lock, NULL);
942 #endif
943 }
944
945
946
947 void int_handler (int signal);
948
949 void setSignals (void)
950 {
951 #if !defined(__MINGW64__) && !defined(__MINGW32__)
952 struct sigaction act;
953 (void)memset (& act, 0, sizeof (act));
954 act.sa_handler = int_handler;
955 act.sa_flags = 0;
956 sigaction (SIGINT, & act, NULL);
957 sigaction (SIGTERM, & act, NULL);
958 #endif
959 }
960
961
962
963
964
965
966
967
968
969
970