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\r\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\r\n", __func__);
127 return;
128 }
129 if (have_mem_lock)
130 {
131 sim_warn ("%s: Already have memory lock\r\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\r\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\r\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\r\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\r\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\r\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\r\n", __func__);
180 return;
181 }
182 if (! have_rmw_lock)
183 {
184 sim_warn ("%s: Don't have RMW lock\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\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\r\n", rc);
428
429 rc = pthread_mutex_init (& p->runLock, NULL);
430 if (rc)
431 sim_printf ("createCPUThread pthread_mutex_init runLock %d\r\n", rc);
432
433 rc = pthread_cond_init (& p->runCond, NULL);
434 if (rc)
435 sim_printf ("createCPUThread pthread_cond_init runCond %d\r\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\r\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\r\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\r\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\r\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\r\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\r\n", rc);
520 }
521 rc = pthread_mutex_unlock (& p->runLock);
522 if (rc)
523 sim_printf ("cpuRunningWait pthread_mutex_unlock %d\r\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\r\n", rc);
547
548 p->sleeping = true;
549
550
551
552
553
554
555
556
557 if (sample_interrupts (& cpus[current_running_cpu_idx])) {
558 p->sleeping = false;
559 rc = pthread_mutex_unlock (& p->sleepLock);
560 if (rc)
561 sim_printf ("sleepCPU pthread_mutex_unlock sleepLock %d\r\n", rc);
562 return usec;
563 }
564 rc = pthread_cond_timedwait (& p->sleepCond, & p->sleepLock, & absTime);
565 p->sleeping = false;
566
567 int rc2 = pthread_mutex_unlock (& p->sleepLock);
568 if (rc2)
569 sim_printf ("sleepCPU pthread_mutex_unlock sleepLock %d\r\n", rc2);
570
571 if (rc == ETIMEDOUT) {
572 return 0;
573 }
574
575 if (rc) {
576 cpu_state_t * cpup = _cpup;
577 sim_printf ("sleepCPU pthread_cond_timedwait rc %ld usec %ld TR %lu CPU %lu\r\n",
578 (long) rc, (long) usec, (unsigned long) cpu.rTR,
579 (unsigned long) current_running_cpu_idx);
580 }
581
582 struct timespec newTime;
583 struct timespec delta;
584 #if defined(USE_MONOTONIC)
585 clock_gettime (p->sleepClock, & newTime);
586 #else
587 clock_gettime (CLOCK_REALTIME, & newTime);
588 #endif
589 timespec_diff (& absTime, & newTime, & delta);
590
591 if (delta.tv_nsec < 0)
592 return 0;
593 return (unsigned long) delta.tv_nsec / 1000L;
594 }
595
596
597
598 void wakeCPU (uint cpuNum)
599 {
600 int rc;
601 struct cpuThreadz_t * p = & cpuThreadz[cpuNum];
602
603
604
605
606
607
608 if (! p->run)
609 return;
610
611 rc = pthread_mutex_lock (& p->sleepLock);
612 if (rc)
613 sim_printf ("sleepCPU pthread_mutex_lock sleepLock %d\r\n", rc);
614
615 if (p->sleeping) {
616 rc = pthread_cond_signal (& p->sleepCond);
617 if (rc)
618 sim_printf ("wakeCPU pthread_cond_signal %d\r\n", rc);
619 }
620
621 int rc2 = pthread_mutex_unlock (& p->sleepLock);
622 if (rc2)
623 sim_printf ("sleepCPU pthread_mutex_unlock sleepLock %d\r\n", rc2);
624 }
625
626 #if defined(IO_THREADZ)
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650 struct iomThreadz_t iomThreadz [N_IOM_UNITS_MAX];
651
652
653
654 void createIOMThread (uint iomNum)
655 {
656 int rc;
657 struct iomThreadz_t * p = & iomThreadz[iomNum];
658 # if defined(tdbg)
659 p->inCnt = 0;
660 p->outCnt = 0;
661 # endif
662 p->iomThreadArg = (int) iomNum;
663
664 p->ready = false;
665
666 p->intr = false;
667 rc = pthread_mutex_init (& p->intrLock, NULL);
668 if (rc)
669 sim_printf ("createIOMThread pthread_mutex_init intrLock %d\r\n", rc);
670 rc = pthread_cond_init (& p->intrCond, NULL);
671 if (rc)
672 sim_printf ("createIOMThread pthread_cond_init intrCond %d\r\n", rc);
673
674 # if defined(__APPLE__)
675 rc = pthread_create_with_cpu_policy(
676 & p->iomThread,
677 iomNum,
678 NULL,
679 iom_thread_main,
680 & p->iomThreadArg);
681 # else
682 rc = pthread_create(
683 & p->iomThread,
684 NULL,
685 iom_thread_main,
686 & p->iomThreadArg);
687 # endif
688 if (rc)
689 sim_printf ("createIOMThread pthread_create %d\r\n", rc);
690 }
691
692
693
694 void iomInterruptWait (void)
695 {
696 int rc;
697 struct iomThreadz_t * p = & iomThreadz[this_iom_idx];
698 rc = pthread_mutex_lock (& p->intrLock);
699 if (rc)
700 sim_printf ("iomInterruptWait pthread_mutex_lock %d\r\n", rc);
701 p -> ready = true;
702 while (! p->intr)
703 {
704 rc = pthread_cond_wait (& p->intrCond, & p->intrLock);
705 if (rc)
706 sim_printf ("iomInterruptWait pthread_cond_wait %d\r\n", rc);
707 }
708 # if defined(tdbg)
709 p->outCnt++;
710 if (p->inCnt != p->outCnt)
711 sim_printf ("iom thread %d in %d out %d\r\n", this_iom_idx,
712 p->inCnt, p->outCnt);
713 # endif
714 }
715
716
717
718 void iomInterruptDone (void)
719 {
720 int rc;
721 struct iomThreadz_t * p = & iomThreadz[this_iom_idx];
722 p->intr = false;
723 rc = pthread_cond_signal (& p->intrCond);
724 if (rc)
725 sim_printf ("iomInterruptDone pthread_cond_signal %d\r\n", rc);
726 rc = pthread_mutex_unlock (& p->intrLock);
727 if (rc)
728 sim_printf ("iomInterruptDone pthread_mutex_unlock %d\r\n", rc);
729 }
730
731
732
733 void iomDoneWait (uint iomNum)
734 {
735 int rc;
736 struct iomThreadz_t * p = & iomThreadz[iomNum];
737 rc = pthread_mutex_lock (& p->intrLock);
738 if (rc)
739 sim_printf ("iomDoneWait pthread_mutex_lock %d\r\n", rc);
740 while (p->intr)
741 {
742 rc = pthread_cond_wait (& p->intrCond, & p->intrLock);
743 if (rc)
744 sim_printf ("iomDoneWait pthread_cond_wait %d\r\n", rc);
745 }
746 rc = pthread_mutex_unlock (& p->intrLock);
747 if (rc)
748 sim_printf ("iomDoneWait pthread_mutex_unlock %d\r\n", rc);
749 }
750
751
752
753 void setIOMInterrupt (uint iomNum)
754 {
755 int rc;
756 struct iomThreadz_t * p = & iomThreadz[iomNum];
757 rc = pthread_mutex_lock (& p->intrLock);
758 if (rc)
759 sim_printf ("setIOMInterrupt pthread_mutex_lock %d\r\n", rc);
760 while (p->intr)
761 {
762 rc = pthread_cond_wait(&p->intrCond, &p->intrLock);
763 if (rc)
764 sim_printf ("setIOMInterrupt pthread_cond_wait intrLock %d\r\n", rc);
765 }
766 # if defined(tdbg)
767 p->inCnt++;
768 # endif
769 p->intr = true;
770 rc = pthread_cond_signal (& p->intrCond);
771 if (rc)
772 sim_printf ("setIOMInterrupt pthread_cond_signal %d\r\n", rc);
773 rc = pthread_mutex_unlock (& p->intrLock);
774 if (rc)
775 sim_printf ("setIOMInterrupt pthread_mutex_unlock %d\r\n", rc);
776 }
777
778
779
780 void iomRdyWait (uint iomNum)
781 {
782 struct iomThreadz_t * p = & iomThreadz[iomNum];
783 while (! p -> ready)
784 sim_usleep (10000);
785 }
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809 struct chnThreadz_t chnThreadz [N_IOM_UNITS_MAX] [MAX_CHANNELS];
810
811
812
813 void createChnThread (uint iomNum, uint chnNum, const char * devTypeStr)
814 {
815 int rc;
816 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
817 p->chnThreadArg = (int) (chnNum + iomNum * MAX_CHANNELS);
818
819 # if defined(tdbg)
820 p->inCnt = 0;
821 p->outCnt = 0;
822 # endif
823 p->ready = false;
824
825 p->connect = false;
826 rc = pthread_mutex_init (& p->connectLock, NULL);
827 if (rc)
828 sim_printf ("createChnThread pthread_mutex_init connectLock %d\r\n", rc);
829 rc = pthread_cond_init (& p->connectCond, NULL);
830 if (rc)
831 sim_printf ("createChnThread pthread_cond_init connectCond %d\r\n", rc);
832
833 # if defined(__APPLE__)
834 rc = pthread_create_with_cpu_policy(
835 & p->chnThread,
836 iomNum
837 NULL,
838 chan_thread_main,
839 & p->chnThreadArg);
840 # else
841 rc = pthread_create(
842 & p->chnThread,
843 NULL,
844 chan_thread_main,
845 & p->chnThreadArg);
846 # endif
847 if (rc)
848 sim_printf ("createChnThread pthread_create %d\r\n", rc);
849 }
850
851
852
853 void chnConnectWait (void)
854 {
855 int rc;
856 struct chnThreadz_t * p = & chnThreadz[this_iom_idx][this_chan_num];
857
858 rc = pthread_mutex_lock (& p->connectLock);
859 if (rc)
860 sim_printf ("chnConnectWait pthread_mutex_lock %d\r\n", rc);
861 p -> ready = true;
862 while (! p->connect)
863 {
864 rc = pthread_cond_wait (& p->connectCond, & p->connectLock);
865 if (rc)
866 sim_printf ("chnConnectWait pthread_cond_wait %d\r\n", rc);
867 }
868 # if defined(tdbg)
869 p->outCnt++;
870 if (p->inCnt != p->outCnt)
871 sim_printf ("chn thread %d in %d out %d\r\n", this_chan_num,
872 p->inCnt, p->outCnt);
873 # endif
874 }
875
876
877
878 void chnConnectDone (void)
879 {
880 int rc;
881 struct chnThreadz_t * p = & chnThreadz[this_iom_idx][this_chan_num];
882 p->connect = false;
883 rc = pthread_cond_signal (& p->connectCond);
884 if (rc)
885 sim_printf ("chnInterruptDone pthread_cond_signal %d\r\n", rc);
886 rc = pthread_mutex_unlock (& p->connectLock);
887 if (rc)
888 sim_printf ("chnConnectDone pthread_mutex_unlock %d\r\n", rc);
889 }
890
891
892
893 void setChnConnect (uint iomNum, uint chnNum)
894 {
895 int rc;
896 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
897 rc = pthread_mutex_lock (& p->connectLock);
898 if (rc)
899 sim_printf ("setChnConnect pthread_mutex_lock %d\r\n", rc);
900 while (p->connect)
901 {
902 rc = pthread_cond_wait(&p->connectCond, &p->connectLock);
903 if (rc)
904 sim_printf ("setChnInterrupt pthread_cond_wait connectLock %d\r\n", rc);
905 }
906 # if defined(tdbg)
907 p->inCnt++;
908 # endif
909 p->connect = true;
910 rc = pthread_cond_signal (& p->connectCond);
911 if (rc)
912 sim_printf ("setChnConnect pthread_cond_signal %d\r\n", rc);
913 rc = pthread_mutex_unlock (& p->connectLock);
914 if (rc)
915 sim_printf ("setChnConnect pthread_mutex_unlock %d\r\n", rc);
916 }
917
918
919
920 void chnRdyWait (uint iomNum, uint chnNum)
921 {
922 struct chnThreadz_t * p = & chnThreadz[iomNum][chnNum];
923 while (! p -> ready)
924 sim_usleep (10000);
925 }
926 #endif
927
928 void initThreadz (void)
929 {
930 #if defined(IO_THREADZ)
931
932 (void)memset (chnThreadz, 0, sizeof (chnThreadz));
933 #endif
934
935 #if !defined(LOCKLESS)
936
937 have_mem_lock = false;
938 have_rmw_lock = false;
939 #endif
940 #if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__linux__) && defined(__GLIBC__))
941 pthread_mutexattr_t scu_attr;
942 pthread_mutexattr_init(&scu_attr);
943 # if !defined(__OpenBSD__)
944 pthread_mutexattr_settype(&scu_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
945 # endif
946 pthread_mutex_init (& scu_lock, &scu_attr);
947 #else
948 pthread_mutex_init (& scu_lock, NULL);
949 #endif
950 pthread_mutexattr_t iom_attr;
951 pthread_mutexattr_init(& iom_attr);
952 pthread_mutexattr_settype(& iom_attr, PTHREAD_MUTEX_RECURSIVE);
953
954 pthread_mutex_init (& iom_lock, & iom_attr);
955
956 pthread_mutexattr_t libuv_attr;
957 pthread_mutexattr_init(& libuv_attr);
958 pthread_mutexattr_settype(& libuv_attr, PTHREAD_MUTEX_RECURSIVE);
959
960 pthread_mutex_init (& libuv_lock, & libuv_attr);
961
962 #if defined(IO_ASYNC_PAYLOAD_CHAN_THREAD)
963 pthread_cond_init (& iomCond, NULL);
964 pthread_mutex_init (& iom_start_lock, NULL);
965 #endif
966 }
967
968
969
970 void int_handler (int signal);
971
972 void setSignals (void)
973 {
974 #if !defined(__MINGW64__) && !defined(__MINGW32__)
975 struct sigaction act;
976 (void)memset (& act, 0, sizeof (act));
977 act.sa_handler = int_handler;
978 act.sa_flags = 0;
979 sigaction (SIGINT, & act, NULL);
980 sigaction (SIGTERM, & act, NULL);
981 #endif
982 }
983
984
985
986
987
988
989
990
991
992
993