1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22
23 #if DARWIN == 1
24 // include something here.......
25 #else
26 #if (defined(__unix__) || defined(unix)) && !defined(USG)
27 #include <sys/param.h>
28 #endif
29 #ifdef BSD
30 #include <sys/cdefs.h>
31 #include <sys/types.h>
32 #include <sys/sysctl.h>
33 #include <machine/cpufunc.h>
34 #include <machine/sysarch.h>
35 #else
36 #include <sys/io.h>
37 #endif
38 #endif
39
40
41 #include <unistd.h>
42 #include <sys/mman.h>
43 #include <sys/resource.h>
44 #include <pthread.h>
45 #include <sched.h>
46 #include <sys/time.h>
47 #include <fcntl.h>
48 #include <termios.h>
49 #include <string.h>
50 #include "globdef.h"
51 #include "rusage.h"
52 #include "thrdef.h"
53 #include "uidef.h"
54 #include "lconf.h"
55 #include "xdef.h"
56 #include "ldef.h"
57 #include "hwaredef.h"
58 #include "options.h"
59 #include "sdrdef.h"
60
61
62 int open_USB2LPT(void);
63
64 struct termios old_options;
65 #ifdef BSD
66 char serport_name[]="/dev/ttyu....";
67 #else
68 char serport_name[]="/dev/ttyS....?";
69 #endif
70
print_procerr(int xxprint)71 void print_procerr(int xxprint)
72 {
73 int i;
74 if( (xxprint&1) != 0)
75 {
76 i=0;
77 if( (xxprint&2)==0)
78 {
79 i=1;
80 printf("\nMMX supported by hardware");
81 }
82 if( (xxprint&4)==0 && simd_present != 0)
83 {
84 i=1;
85 printf("\nSIMD (=sse) supported by hardware");
86 }
87 if(i!=0)
88 {
89 printf("\n/proc/cpuinfo says LINUX core is not compatible.");
90 printf("\n\nLinrad will allow you to select routines that may be illegal");
91 printf("\non your system.");
92 printf("\nAny illegal instruction will cause a program crasch!!");
93 printf("\nSeems just the sse flag in /proc/cpuinfo is missing.");
94 printf("\nTo use fast routines with an older core, recompile LINUX");
95 printf("\nwith appropriate patches.\n\n");
96 }
97 }
98 }
99
mmxerr(void)100 void mmxerr(void)
101 {
102 printf("\n\nCould not read file /proc/cpuinfo (flags:)");
103 printf("\nSetting MMX and SIMD flags from hardware");
104 printf("\nProgram may fail if kernel support is missing and modes");
105 printf("\nneeding MMX or SIMD are selected.");
106 printf("\n\n%s",press_enter);
107 fflush(stdout);
108 getchar();
109 }
110
investigate_cpu(void)111 int investigate_cpu(void)
112 {
113 int i;
114 #ifndef BSD
115 int k, maxproc, maxproc_flag;
116 FILE *file;
117 char s[256];
118 char *flags="flags";
119 char *fmmx=" mmx";
120 char *fsse=" sse";
121 char *fht=" ht";
122 char *fprocessor="processor";
123 #endif
124 int xxprint;
125 // If there is no mmx, do not use simd either.
126 tickspersec = sysconf(_SC_CLK_TCK);
127 xxprint=0;
128 #if CPU == CPU_INTEL
129 #if IA64 == 0
130 i=check_mmx();
131 #else
132 // We do not use assembly on 64 bit systems (yet??)
133 i=0;
134 i=2; // simd is OK, but not MMX.
135 #endif
136 mmx_present=i&1;
137 simd_present=i>>1;
138 #else
139 mmx_present=0;
140 simd_present=0;
141 #endif
142 #ifdef BSD
143 size_t len=sizeof(no_of_processors);
144 int err;
145 if((err=sysctlbyname("hw.ncpu", &no_of_processors,
146 &len, NULL, 0)) < 0)no_of_processors=1;
147 #else
148 no_of_processors=1;
149 no_of_ht=0;
150 maxproc=0;
151 maxproc_flag=0;
152 file = fopen("/proc/cpuinfo", "r");
153 if (file == NULL)
154 {
155 mmxerr();
156 return 0;
157 }
158 else
159 {
160 no_of_processors=0;
161 nxline:;
162 if(fgets(s,256,file)==NULL)
163 {
164 if(no_of_processors>0)goto cpuinfo_ok;
165 fclose(file);
166 #if CPU == CPU_INTEL
167 mmxerr();
168 #endif
169 no_of_processors=1;
170 return 0;
171 }
172 else
173 {
174 for(i=0; i<9; i++) if(s[i]!=fprocessor[i])goto nxt;
175 k=8;
176 while(s[k+1] == ' ' || s[k+1] == ':' || s[k+1] == 9)k++;
177 i=atoi(&s[k]);
178 if(i != no_of_processors)maxproc_flag++;
179 no_of_processors++;
180 if(i > maxproc)maxproc=i;
181 nxt:;
182 k=0;
183 while(s[k] != flags[0] && k < 10)k++;
184 for(i=0; i<5; i++) if(s[i+k]!=flags[i])goto nxline;
185 k+=5;
186 nxbln:
187 while(s[k]!=0 && s[k]!=' ')k++;
188 while(s[k]!=0 && s[k]==' ')k++;
189 if(s[k]!=0)
190 {
191 k--;
192 for(i=0; i<4; i++)if(s[i+k]!=fmmx[i])goto notmmx;
193 if(s[k+4] != ' ' && s[k+4] != 10)goto notmmx;
194 xxprint|=2;
195 notmmx:;
196 for(i=0; i<4; i++)if(s[i+k]!=fsse[i])goto notsse;
197 if(s[k+4] != ' ' && s[k+4] != 10)goto notsse;
198 xxprint|=4;
199 notsse:;
200 for(i=0; i<3; i++)if(s[i+k]!=fht[i])goto notht;
201 if(s[k+3] != ' ' && s[k+3] != 10)goto notht;
202 no_of_ht++;
203 notht:;
204 k++;
205 goto nxbln;
206 }
207 xxprint|=1;
208 }
209 goto nxline;
210 cpuinfo_ok:;
211 fclose(file);
212 }
213 if(maxproc_flag != 0)
214 {
215 // If something went wrong, better underestimate the number of CPUs.
216 maxproc++;
217 if(no_of_processors > maxproc)no_of_processors=maxproc;
218 }
219 if(no_of_processors == no_of_ht)
220 {
221 // This is incorrect. In e.g. Ubuntu Studio 13.10 the hyperthreaded
222 // cores are not listed, but nevertheless the ht flag is set.
223 // In case it turns out to be interesting to control cpu affinities
224 // it will be necessary do something else here.
225 // Look for 'core id' and 'cpu cores'
226 hyperthread_flag=TRUE;
227 }
228 else
229 {
230 hyperthread_flag=FALSE;
231 }
232 #endif
233 return xxprint;
234 }
235
236
237
238 // Old versions of Linux have a special implementation of getrusage
239 // that returns the timing for the calling thread and not the timing for
240 // the process as prescribed by POSIX
241 // The configure script will set RESAGE_OLD=TRUE for those old linux
242 // kernels.
243 #if RUSAGE_OLD != TRUE
244 #include <sys/syscall.h>
245
lir_system_times(double * cpu_time,double * total_time)246 void lir_system_times(double *cpu_time, double *total_time)
247 {
248 cpu_time[0]=lir_get_cpu_time();
249 total_time[0]=current_time();
250 }
251
clear_thread_times(int no)252 void clear_thread_times(int no)
253 {
254 #ifdef BSD
255 thread_pid[no]=no;
256 #else
257 thread_pid[no]=syscall(SYS_gettid);
258 #endif
259 thread_tottim1[no]=current_time();
260 thread_cputim1[no]=lir_get_cpu_time();
261 thread_workload[no]=0;
262 }
263
make_thread_times(int no)264 void make_thread_times(int no)
265 {
266 float t1,t2;
267 thread_tottim2[no]=current_time();
268 thread_cputim2[no]=lir_get_thread_time(no);
269 t1=100*(thread_cputim2[no]-thread_cputim1[no]);
270 t2=thread_tottim2[no]-thread_tottim1[no];
271 if(t1>0 && t2>0)
272 {
273 thread_workload[no]=t1/t2;
274 }
275 else
276 {
277 thread_workload[no]=0;
278 }
279 }
280
lir_get_cpu_time(void)281 double lir_get_cpu_time(void)
282 {
283 double tm;
284 struct rusage rudat;
285 getrusage(RUSAGE_SELF,&rudat);
286 tm=0.000001*(rudat.ru_utime.tv_usec + rudat.ru_stime.tv_usec)+
287 rudat.ru_utime.tv_sec + rudat.ru_stime.tv_sec;
288 return tm;
289 }
290
lir_get_thread_time(int no)291 double lir_get_thread_time(int no)
292 {
293 #ifdef BSD
294 return 0*no;
295 #else
296 char fnam[80], info[512];
297 FILE *pidstat;
298 int j,k,m;
299 long long int ii1, ii2;
300 sprintf(fnam,"/proc/%d/task/%d/stat",thread_pid[no],thread_pid[no]);
301 pidstat=fopen(fnam,"r");
302 if(pidstat==NULL)return 0;
303 #if VALGRIND == TRUE
304 memset(info, 0, 512);
305 #endif
306 m=fread(info,1,512,pidstat);
307 fclose(pidstat);
308 j=0;
309 k=0;
310 while(k<13)
311 {
312 while(info[j]!= ' ' && j<m)j++;
313 while(info[j]== ' ' && j<m)j++;
314 k++;
315 }
316 if(j>=m)return 0;
317 sscanf(&info[j], "%lld %lld", &ii1, &ii2);
318 return (double)(ii1+ii2)/tickspersec;
319 #endif
320 }
321 #endif
322
323 // Old versions of Linux have a special implementation of getrusage
324 // that returns the timing for the calling thread and not the timing for
325 // the process as prescribed by POSIX
326 // The configure script will set RESAGE_OLD=TRUE for those old linux
327 // kernels.
328 #if RUSAGE_OLD == TRUE
329
make_thread_times(int no)330 void make_thread_times(int no)
331 {
332 float t1,t2;
333 thread_tottim2[no]=current_time();
334 thread_cputim2[no]=lir_get_thread_time();
335 t1=100*(thread_cputim2[no]-thread_cputim1[no]);
336 t2=thread_tottim2[no]-thread_tottim1[no];
337 if(t1>0 && t2>0)
338 {
339 thread_workload[no]=t1/t2;
340 }
341 else
342 {
343 thread_workload[no]=0;
344 }
345 }
346
clear_thread_times(int no)347 void clear_thread_times(int no)
348 {
349 thread_tottim1[no]=current_time();
350 thread_cputim1[no]=lir_get_cpu_time();
351 thread_workload[no]=0;
352 }
353
lir_get_cpu_time(void)354 double lir_get_cpu_time(void)
355 {
356 int i;
357 float t1;
358 t1=0;
359 for(i=0; i<THREAD_MAX; i++)
360 {
361 if(thread_command_flag[i]!=THRFLAG_NOT_ACTIVE)
362 {
363 t1+=thread_workload[i];
364 }
365 }
366 return t1;
367 }
368
lir_get_thread_time(void)369 double lir_get_thread_time(void)
370 {
371 double tm;
372 struct rusage rudat;
373 getrusage(RUSAGE_SELF,&rudat);
374 tm=0.000001*(rudat.ru_utime.tv_usec + rudat.ru_stime.tv_usec)+
375 rudat.ru_utime.tv_sec + rudat.ru_stime.tv_sec;
376 return tm;
377 }
378
379 #endif
380
381
lir_init_event(int i)382 void lir_init_event(int i)
383 {
384 pthread_mutex_init(&lir_event_mutex[i],NULL);
385 lir_event_flag[i]=FALSE;
386 pthread_cond_init(&lir_event_cond[i], NULL);
387 }
388
lir_close_event(int i)389 void lir_close_event(int i)
390 {
391 pthread_mutex_destroy(&lir_event_mutex[i]);
392 pthread_cond_destroy(&lir_event_cond[i]);
393 }
394
395
lir_set_event(int no)396 void lir_set_event(int no)
397 {
398 while(pthread_mutex_lock(&lir_event_mutex[no]) != 0)lir_sleep(10);
399 lir_event_flag[no]=TRUE;
400 pthread_cond_signal(&lir_event_cond[no]);
401 pthread_mutex_unlock(&lir_event_mutex[no]);
402 }
403
lir_await_event(int no)404 void lir_await_event(int no)
405 {
406 while(pthread_mutex_lock(&lir_event_mutex[no]) != 0)lir_sleep(10);
407 if(lir_event_flag[no] != TRUE)
408 {
409 pthread_cond_wait(&lir_event_cond[no], &lir_event_mutex[no]);
410 }
411 lir_event_flag[no]=FALSE;
412 while(pthread_mutex_unlock(&lir_event_mutex[no]) != 0)lir_sleep(10);
413 }
414
415
416
417
418
lir_noisegen(int level)419 float lir_noisegen(int level)
420 {
421 // Return a number distributed following a gaussian
422 // Mean value is 0 and sigma pow(2,level)
423 float x, y, z;
424 y = (float)(random()+0.5)/(float)RAND_MAX;
425 z = (float)(random()+0.5)/(float)RAND_MAX;
426 x = z * 2*PI_L;
427 return sin(x)*sqrt(-2*log(y))*pow(2.,level);
428 }
429
lir_mutex_init(void)430 void lir_mutex_init(void)
431 {
432 int i;
433 for(i=0; i<MAX_LIRMUTEX; i++)
434 {
435 pthread_mutex_init(&linux_mutex[i],NULL);
436 }
437 }
438
lir_mutex_destroy(void)439 void lir_mutex_destroy(void)
440 {
441 int i;
442 for(i=0; i<MAX_LIRMUTEX; i++)
443 {
444 pthread_mutex_destroy(&linux_mutex[i]);
445 }
446 }
447
lir_mutex_lock(int no)448 void lir_mutex_lock(int no)
449 {
450 pthread_mutex_lock(&linux_mutex[no]);
451 }
452
lir_mutex_unlock(int no)453 void lir_mutex_unlock(int no)
454 {
455 pthread_mutex_unlock(&linux_mutex[no]);
456 }
457
lirerr(int errcod)458 void lirerr(int errcod)
459 {
460 fprintf(STDERR,"\nlir error %d",errcod);
461 if(kill_all_flag) return;
462 DEB"\nlirerr(%d)",errcod);
463 if(dmp != 0)fflush(dmp);
464 lir_errcod=errcod;
465 lir_set_event(EVENT_KILL_ALL);
466 while(!kill_all_flag)lir_sleep(10000);
467 }
468
lir_open_serport(int serport_number,int baudrate,int stopbit_flag,int rts_mode)469 int lir_open_serport(int serport_number, int baudrate,int stopbit_flag, int rts_mode)
470 {
471 int rte;
472 int rc;
473 struct termios options;
474 rc=0;
475 if(serport != -1)return rc ;
476 if(serport_number < 1 || serport_number > 8)
477 {
478 rc=1279;
479 return rc;
480 }
481 if(serport_number <= 4)
482 {
483 sprintf(&serport_name[0],"%s","/dev/ttyS");
484 sprintf(&serport_name[9],"%d",serport_number-1);
485 }
486 else
487 {
488 sprintf(&serport_name[0],"%s","/dev/ttyUSB");
489 sprintf(&serport_name[11],"%d",serport_number-5);
490 }
491 serport=open(serport_name,O_RDWR | O_NOCTTY | O_NDELAY);
492 if (serport == -1)
493 {
494 rc=1244;
495 return rc;
496 }
497 fcntl(serport,F_SETFL,0); //blocking I/O
498 //fcntl(serport, F_SETFL, FNDELAY); //non blocking I/O
499 if(tcgetattr(serport,&options) != 0)
500 {
501 rc=1277;
502 goto close_x;
503 }
504 switch ( baudrate )
505 {
506 case 110:
507 rte=B110;
508 break;
509
510 case 300:
511 rte=B300;
512 break;
513
514 case 600:
515 rte=B600;
516 break;
517
518 case 1200:
519 rte=B1200;
520 break;
521
522 case 2400:
523 rte=B2400;
524 break;
525
526 case 4800:
527 rte=B4800;
528 break;
529
530 case 9600:
531 rte=B9600;
532 break;
533
534 case 19200:
535 rte=B19200;
536 break;
537
538 case 38400:
539 rte=B38400;
540 break;
541
542 case 57600:
543 rte=B57600;
544 break;
545
546 default:
547 rc=1280;
548 goto close_x;
549 }
550 old_options=options;
551 cfsetispeed(&options,rte);
552 cfsetospeed(&options,rte);
553 //CLOCAL means don’t allow
554 //control of the port to be changed
555 //CREAD says to enable the receiver
556 options.c_cflag|= (CLOCAL | CREAD);
557 // no parity, 2 or 1 stopbits, 8 bits per word
558 options.c_cflag&= ~PARENB; // no parity=>disable the "enable parity bit" PARENB
559 if(stopbit_flag)
560 {
561 options.c_cflag|= CSTOPB;// =>2 stopbits
562 }
563 else
564 {
565 options.c_cflag&= ~CSTOPB;//=> 1 stopbit
566 }
567 options.c_cflag&= ~CSIZE; // clear size-bit by anding with negation
568 options.c_cflag|= CS8; // =>set size to 8 bits per word
569 // raw input /output
570 options.c_oflag &= ~OPOST;
571 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
572 //Set the timeouts:
573 //VMIN is the minimum amount characters to read
574 options.c_cc[VMIN]=0;
575 //The amount of time to wait
576 //for the amount of data
577 //specified by VMIN in tenths
578 //of a second.
579 options.c_cc[VTIME] = 1;
580 // Select flow control mode
581 switch (rts_mode)
582 {
583 case 0:
584 options.c_cflag &= ~CRTSCTS; // no handshaking
585 options.c_iflag &= ~IXON;
586 break;
587
588 case 1:
589 options.c_cflag &= ~CRTSCTS; // Enable Xon/Xoff software handshaking
590 options.c_iflag |= IXON;
591 break;
592
593 case 2:
594 options.c_cflag |= CRTSCTS; // Enable Hardware RTS handshaking
595 options.c_iflag &= ~IXON;
596 break;
597 }
598 //flush I/O buffers and apply the settings
599 if(tcsetattr(serport, TCSAFLUSH,&options) != 0)
600 {
601 rc=1278;
602 close_x:
603 close(serport);
604 serport=-1;
605 }
606 return rc;
607 }
608
lir_close_serport(void)609 void lir_close_serport(void)
610 {
611 if(serport == -1)return;
612 if(tcsetattr(serport, TCSAFLUSH,&old_options) != 0)lirerr(1278);
613 close(serport);
614 serport=-1;
615 }
616
lir_write_serport(void * s,int bytes)617 int lir_write_serport(void *s, int bytes)
618 {
619 return write(serport,s,bytes);
620 }
621
lir_read_serport(void * s,int bytes)622 int lir_read_serport(void *s, int bytes)
623 {
624 int retnum, nread = 0;
625 while (bytes > 0) {
626 retnum = read (serport, (char *)(s + nread), bytes);
627 if (retnum <= 0) return -1;
628 nread += retnum;
629 bytes -= retnum;
630 }
631 return nread;
632 }
633
lir_parport_permission(int portno)634 int lir_parport_permission(int portno)
635 {
636 int i;
637 // If the user selected USB2LPT16_PORT_NUMBER we will use USB for
638 // the 25 pin parallel port. It may not be permitted in case
639 // the user does not have privileges.
640 // verify that we can open the device.
641 if (wse.parport == USB2LPT16_PORT_NUMBER)
642 {
643 if(!usb2lpt_flag)usb2lpt_flag=open_USB2LPT();
644 return usb2lpt_flag;
645 }
646 #if DARWIN == 0
647 // Get permission to write to the parallel port
648 #ifdef BSD
649 #ifdef i386_set_ioperm
650 i=i386_set_ioperm(portno,4,1);
651 #else
652 i=portno;
653 return FALSE;
654 #endif
655 #else
656 if(portno < 0x400-4)
657 {
658 i=ioperm(portno,4,1);
659 }
660 else
661 {
662 i=iopl(3);
663 }
664 #endif
665 if(i != 0)
666 {
667 lir_text(2,2,"Access to parallel port denied.");
668 lir_text(2,4,"Use sudo or run as root");
669 lir_text(2,6,press_any_key);
670 await_keyboard();
671 clear_screen();
672 return FALSE;
673 }
674 return TRUE;
675 #else
676 i=portno;
677 i=FALSE;
678 return i;
679 #endif
680 }
681
lir_sched_yield(void)682 void lir_sched_yield(void)
683 {
684 sched_yield();
685 }
686
win_global_uiparms(int n)687 void win_global_uiparms(int n)
688 {
689 (void) n;
690 // Dummy routine. Not used under Linux.
691 }
692
linrad_thread_create(int no)693 void linrad_thread_create(int no)
694 {
695 thread_status_flag[no]=THRFLAG_INIT;
696 thread_command_flag[no]=THRFLAG_ACTIVE;
697 pthread_create(&thread_identifier[no],NULL,(void*)thread_routine[no], NULL);
698 threads_running=TRUE;
699 }
700
fix_prio(int thread)701 void fix_prio(int thread)
702 {
703 #if OSNUM == OSNUM_LINUX
704 int policy;
705 int i, k;
706 if(ui.process_priority != 0)
707 {
708 struct sched_param parms;
709 pthread_getschedparam(thread_identifier[thread],&policy,&parms);
710 policy=SCHED_FIFO;
711 i=sched_get_priority_max(policy);
712 switch (ui.process_priority)
713 {
714 case 3:
715 k=i-1;
716 break;
717
718 case 2:
719 k=(i+parms.sched_priority)/2;
720 break;
721
722 default:
723 k=parms.sched_priority+1;
724 if(k > i) k=i;
725 }
726 parms.sched_priority=k;
727 pthread_setschedparam(thread_identifier[thread],policy,&parms);
728 }
729 #endif
730 }
731
732
thread_rx_output(void)733 void thread_rx_output(void)
734 {
735 fix_prio(THREAD_RX_OUTPUT);
736 rx_output();
737 thread_status_flag[THREAD_RX_OUTPUT]=THRFLAG_RETURNED;
738 }
739
thread_kill_all(void)740 void thread_kill_all(void)
741 {
742 // Wait until the event is set.
743 // Then stop all processing threads so main can write any
744 // error code/message and exit.
745 lir_await_event(EVENT_KILL_ALL);
746 kill_all();
747 }
748
current_time(void)749 double current_time(void)
750 {
751 struct timeval t;
752 gettimeofday(&t,NULL);
753 recent_time=0.000001*t.tv_usec+t.tv_sec;
754 return recent_time;
755 }
756
ms_since_midnight(int set)757 int ms_since_midnight(int set)
758 {
759 int i;
760 double dt1;
761 dt1=current_time();
762 if(set)netstart_time=dt1;
763 i=dt1/(24*3600);
764 dt1-=24*3600*i;
765 i=1000*dt1;
766 return i%(24*3600000);
767 }
768
lir_sync(void)769 void lir_sync(void)
770 {
771 // This routine is called to force a write to the hard disk
772 sync();
773 }
774
775
lir_get_epoch_seconds(void)776 int lir_get_epoch_seconds(void)
777 {
778 struct timeval tim;
779 gettimeofday(&tim,NULL);
780 return tim.tv_sec;
781 }
782
lir_join(int no)783 void lir_join(int no)
784 {
785 lir_sched_yield();
786 if(thread_command_flag[no]==THRFLAG_NOT_ACTIVE)return;
787 pthread_join(thread_identifier[no],0);
788 thread_status_flag[no]=THRFLAG_NOT_ACTIVE;
789 }
790
lir_sleep(int us)791 void lir_sleep(int us)
792 {
793 usleep(us);
794 }
795
lir_outb(char byte,int port)796 void lir_outb(char byte, int port)
797 {
798 int i;
799 if(libusb1_library_flag == TRUE || libusb0_library_flag == TRUE)
800 {
801 if(wse.parport==USB2LPT16_PORT_NUMBER)
802 {
803 out_USB2LPT(byte,(port-wse.parport));
804 }
805 }
806 else
807 {
808 #if DARWIN == 0
809 #ifdef BSD
810 #ifdef i386_set_ioperm
811 i=i386_set_ioperm(port,4,1);
812 #else
813 return;
814 #endif
815 #else
816 if(port < 0x400-4)
817 {
818 i=ioperm(port,4,1);
819 }
820 else
821 {
822 i=iopl(3);
823 }
824 #endif
825 if(i!=0)lirerr(764921);
826 #ifdef BSD
827 {
828 int k;
829 k=byte;
830 outb(k,port);
831 }
832 #else
833 outb(byte,port);
834 #endif
835 #else
836 i=byte+port;
837 #endif
838 }
839 i=1000;
840 while(i>0)i--;
841 }
842
lir_inb(int port)843 char lir_inb(int port)
844 {
845 #if DARWIN == 0
846 int i;
847 #endif
848 if(wse.parport==USB2LPT16_PORT_NUMBER)
849 {
850 if(libusb1_library_flag == TRUE || libusb0_library_flag == TRUE)
851 {
852 return in_USB2LPT((port-wse.parport));
853 }
854 else
855 {
856 lirerr(7211332);
857 return 0;
858 }
859 }
860 else
861 {
862 #ifdef BSD
863 #ifdef i386_set_ioperm
864 i=i386_set_ioperm(port,4,1);
865 #else
866 return 0;
867 #endif
868 #else
869 #if DARWIN == 0
870 if(port < 0x400-4)
871 {
872 i=ioperm(port,4,1);
873 }
874 else
875 {
876 i=iopl(3);
877 }
878 #endif
879 #endif
880 #if DARWIN == 0
881 if(i!=0)lirerr(764921);
882 return inb(port);
883 #endif
884 }
885 return port;
886 }
887
lir_random(void)888 float lir_random(void)
889 {
890 return (float)(random())/(float)RAND_MAX;
891 }
892
lir_srandom(void)893 void lir_srandom(void)
894 {
895 unsigned int seed;
896 seed=current_time();
897 srandom(seed);
898 }
899
900 // *********************************************************************
901 // Thread entries for Linux
902 // *********************************************************************
903
thread_main_menu(void)904 void thread_main_menu(void)
905 {
906 main_menu();
907 }
908
thread_tune(void)909 void thread_tune(void)
910 {
911 tune();
912 }
913
thread_sdr14_input(void)914 void thread_sdr14_input(void)
915 {
916 fix_prio(THREAD_SDR14_INPUT);
917 sdr14_input();
918 }
919
thread_radar(void)920 void thread_radar(void)
921 {
922 fix_prio(THREAD_RADAR);
923 run_radar();
924 }
925
thread_blocking_rxout(void)926 void thread_blocking_rxout(void)
927 {
928 fix_prio(THREAD_BLOCKING_RXOUT);
929 blocking_rxout();
930 }
931
thread_write_raw_file(void)932 void thread_write_raw_file(void)
933 {
934 write_raw_file();
935 }
936
thread_perseus_input(void)937 void thread_perseus_input(void)
938 {
939 fix_prio(THREAD_PERSEUS_INPUT);
940 perseus_input();
941 }
942
thread_rtl2832_input(void)943 void thread_rtl2832_input(void)
944 {
945 fix_prio(THREAD_RTL2832_INPUT);
946 rtl2832_input();
947 }
948
thread_mirics_input(void)949 void thread_mirics_input(void)
950 {
951 fix_prio(THREAD_MIRISDR_INPUT);
952 mirics_input();
953 }
954
thread_bladerf_input(void)955 void thread_bladerf_input(void)
956 {
957 fix_prio(THREAD_BLADERF_INPUT);
958 bladerf_input();
959 }
960
thread_pcie9842_input(void)961 void thread_pcie9842_input(void)
962 {
963 fix_prio(THREAD_PCIE9842_INPUT);
964 pcie9842_input();
965 }
966
thread_openhpsdr_input(void)967 void thread_openhpsdr_input(void)
968 {
969 fix_prio(THREAD_OPENHPSDR_INPUT);
970 openhpsdr_input();
971 }
972
thread_hware_command(void)973 void thread_hware_command(void)
974 {
975 hware_command();
976 }
977
thread_sdrip_input(void)978 void thread_sdrip_input(void)
979 {
980 fix_prio(THREAD_SDRIP_INPUT);
981 sdrip_input();
982 }
983
thread_netafedri_input(void)984 void thread_netafedri_input(void)
985 {
986 fix_prio(THREAD_NETAFEDRI_INPUT);
987 netafedri_input();
988 }
989
thread_excalibur_input(void)990 void thread_excalibur_input(void)
991 {
992 fix_prio(THREAD_EXCALIBUR_INPUT);
993 excalibur_input();
994 }
995
thread_cal_filtercorr(void)996 void thread_cal_filtercorr(void)
997 {
998 cal_filtercorr();
999 }
1000
thread_cal_interval(void)1001 void thread_cal_interval(void)
1002 {
1003 do_cal_interval();
1004 }
1005
thread_user_command(void)1006 void thread_user_command(void)
1007 {
1008 user_command();
1009 }
1010
thread_narrowband_dsp(void)1011 void thread_narrowband_dsp(void)
1012 {
1013 fix_prio(THREAD_NARROWBAND_DSP);
1014 narrowband_dsp();
1015 }
1016
thread_do_fft1c(void)1017 void thread_do_fft1c(void)
1018 {
1019 fix_prio(THREAD_DO_FFT1C);
1020 do_fft1c();
1021 }
1022
thread_fft1b(void)1023 void thread_fft1b(void)
1024 {
1025 do_fft1b();
1026 }
1027
thread_wideband_dsp(void)1028 void thread_wideband_dsp(void)
1029 {
1030 fix_prio(THREAD_WIDEBAND_DSP);
1031 wideband_dsp();
1032 }
1033
thread_second_fft(void)1034 void thread_second_fft(void)
1035 {
1036 fix_prio(THREAD_SECOND_FFT);
1037 second_fft();
1038 }
1039
thread_timf2(void)1040 void thread_timf2(void)
1041 {
1042 fix_prio(THREAD_TIMF2);
1043 timf2_routine();
1044 }
1045
thread_tx_input(void)1046 void thread_tx_input(void)
1047 {
1048 fix_prio(THREAD_TX_INPUT);
1049 tx_input();
1050 }
1051
thread_tx_output(void)1052 void thread_tx_output(void)
1053 {
1054 fix_prio(THREAD_TX_OUTPUT);
1055 run_tx_output();
1056 }
1057
thread_screen(void)1058 void thread_screen(void)
1059 {
1060 screen_routine();
1061 }
1062
thread_rx_file_input(void)1063 void thread_rx_file_input(void)
1064 {
1065 fix_prio(THREAD_RX_FILE_INPUT);
1066 rx_file_input();
1067 }
1068
thread_cal_iqbalance(void)1069 void thread_cal_iqbalance(void)
1070 {
1071 cal_iqbalance();
1072 }
1073
thread_rx_adtest(void)1074 void thread_rx_adtest(void)
1075 {
1076 rx_adtest();
1077 }
1078
thread_powtim(void)1079 void thread_powtim(void)
1080 {
1081 powtim();
1082 }
1083
thread_txtest(void)1084 void thread_txtest(void)
1085 {
1086 txtest();
1087 }
1088
thread_syscall(void)1089 void thread_syscall(void)
1090 {
1091 do_syscall();
1092 }
1093
thread_extio_input(void)1094 void thread_extio_input(void)
1095 {
1096 fix_prio(THREAD_EXTIO_INPUT);
1097 extio_input();
1098 }
1099
thread_rtl_starter(void)1100 void thread_rtl_starter(void)
1101 {
1102 rtl_starter();
1103 }
1104
thread_mirisdr_starter(void)1105 void thread_mirisdr_starter(void)
1106 {
1107 mirisdr_starter();
1108 }
1109
thread_bladerf_starter(void)1110 void thread_bladerf_starter(void)
1111 {
1112 bladerf_starter();
1113 }
1114
thread_html_server(void)1115 void thread_html_server(void)
1116 {
1117 #if SERVER == 1
1118 html_server();
1119 #endif
1120 }
1121
1122