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