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