35
35
#include "mq.h"
36
36
#include "msg.h"
37
37
38
+ /************************ Overridable request API ****************************/
39
+ SUPRIVATE void
40
+ suscan_inspector_overridable_request_destroy (
41
+ struct suscan_inspector_overridable_request * self )
42
+ {
43
+ free (self );
44
+ }
45
+
46
+ SUPRIVATE struct suscan_inspector_overridable_request *
47
+ suscan_inspector_overridable_request_new (suscan_inspector_t * insp )
48
+ {
49
+ struct suscan_inspector_overridable_request * new = NULL ;
50
+
51
+ SU_TRYCATCH (
52
+ new = calloc (1 , sizeof (struct suscan_inspector_overridable_request )),
53
+ goto done );
54
+
55
+ new -> insp = insp ;
56
+
57
+ return new ;
58
+
59
+ done :
60
+ if (new != NULL )
61
+ suscan_inspector_overridable_request_destroy (new );
62
+
63
+ return NULL ;
64
+ }
65
+
66
+ struct suscan_inspector_overridable_request *
67
+ suscan_analyzer_acquire_overridable (
68
+ suscan_analyzer_t * self ,
69
+ SUHANDLE handle )
70
+ {
71
+ struct suscan_inspector_overridable_request * req = NULL ;
72
+ struct suscan_inspector_overridable_request * own_req = NULL ;
73
+ suscan_inspector_t * insp = NULL ;
74
+
75
+ /*
76
+ * TODO: Maybe acquire scheduler mutex?
77
+ */
78
+
79
+ SU_TRYCATCH (suscan_analyzer_lock_inspector_list (self ), goto done );
80
+ SU_TRYCATCH (insp = suscan_analyzer_get_inspector (self , handle ), goto done );
81
+ SU_TRYCATCH (insp -> state == SUSCAN_ASYNC_STATE_RUNNING , goto done );
82
+
83
+ if ((req = suscan_inspector_get_userdata (insp )) == NULL ) {
84
+ /* No userdata. Release mutex, create object and lock again. */
85
+ suscan_analyzer_unlock_inspector_list (self );
86
+
87
+ SU_TRYCATCH (
88
+ own_req = suscan_inspector_overridable_request_new (insp ),
89
+ goto done );
90
+
91
+ SU_TRYCATCH (suscan_analyzer_lock_inspector_list (self ), goto done );
92
+
93
+ /* Many things may have happened here */
94
+ SU_TRYCATCH (handle >= 0 && handle < self -> inspector_count , goto done );
95
+ SU_TRYCATCH (insp = suscan_analyzer_get_inspector (self , handle ), goto done );
96
+ SU_TRYCATCH (insp -> state == SUSCAN_ASYNC_STATE_RUNNING , goto done );
97
+
98
+ req = own_req ;
99
+ own_req = NULL ;
100
+
101
+ req -> next = self -> insp_overridable ;
102
+ self -> insp_overridable = req ;
103
+
104
+ suscan_inspector_set_userdata (insp , req );
105
+ }
106
+
107
+ done :
108
+ if (own_req != NULL )
109
+ suscan_inspector_overridable_request_destroy (own_req );
110
+
111
+ return req ;
112
+ }
113
+
114
+ SUBOOL
115
+ suscan_analyzer_release_overridable (
116
+ suscan_analyzer_t * self ,
117
+ struct suscan_inspector_overridable_request * rq )
118
+ {
119
+ suscan_analyzer_unlock_inspector_list (self );
120
+
121
+ return SU_TRUE ;
122
+ }
123
+
38
124
/************************* Baseband filter API *******************************/
39
125
SUPRIVATE struct suscan_analyzer_baseband_filter *
40
126
suscan_analyzer_baseband_filter_new (
@@ -106,7 +192,17 @@ suscan_analyzer_unlock_loop(suscan_analyzer_t *analyzer)
106
192
(void ) pthread_mutex_unlock (& analyzer -> loop_mutex );
107
193
}
108
194
195
+ SUBOOL
196
+ suscan_analyzer_lock_inspector_list (suscan_analyzer_t * analyzer )
197
+ {
198
+ return pthread_mutex_lock (& analyzer -> inspector_list_mutex ) != -1 ;
199
+ }
109
200
201
+ void
202
+ suscan_analyzer_unlock_inspector_list (suscan_analyzer_t * analyzer )
203
+ {
204
+ (void ) pthread_mutex_unlock (& analyzer -> inspector_list_mutex );
205
+ }
110
206
111
207
/************************* Main analyzer thread *******************************/
112
208
void
@@ -347,7 +443,17 @@ suscan_analyzer_thread(void *data)
347
443
goto done );
348
444
349
445
self -> interval_channels = new_params -> channel_update_int ;
350
- self -> interval_psd = new_params -> psd_update_int ;
446
+
447
+ if (SU_ABS (self -> interval_psd - new_params -> psd_update_int ) > 1e-6 ) {
448
+ self -> interval_psd = new_params -> psd_update_int ;
449
+ self -> det_num_psd = 0 ;
450
+ #ifdef __linux__
451
+ clock_gettime (CLOCK_MONOTONIC_COARSE , & self -> last_psd );
452
+ #else
453
+ clock_gettime (CLOCK_MONOTONIC , & self -> last_psd );
454
+ #endif /* __linux__ */
455
+ }
456
+
351
457
/* ^^^^^^^^^^^^^ Source parameters update end ^^^^^^^^^^^^^^^^^ */
352
458
353
459
SU_TRYCATCH (
@@ -456,9 +562,7 @@ suscan_analyzer_init_detector_params(
456
562
* params = self -> params .detector_params ;
457
563
458
564
/* Populate members with source information */
459
- params -> mode = self -> params .mode == SUSCAN_ANALYZER_MODE_CHANNEL
460
- ? SU_CHANNEL_DETECTOR_MODE_DISCOVERY
461
- : SU_CHANNEL_DETECTOR_MODE_SPECTRUM ;
565
+ params -> mode = SU_CHANNEL_DETECTOR_MODE_SPECTRUM ;
462
566
463
567
params -> samp_rate = suscan_analyzer_get_samp_rate (self );
464
568
@@ -628,7 +732,7 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
628
732
{
629
733
uint32_t type ;
630
734
unsigned int i ;
631
-
735
+ struct suscan_inspector_overridable_request * req ;
632
736
void * private ;
633
737
634
738
/* Prevent source from entering in timeout loops */
@@ -690,10 +794,23 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
690
794
if (analyzer -> loop_init )
691
795
pthread_mutex_destroy (& analyzer -> loop_mutex );
692
796
797
+ if (analyzer -> inspector_list_init )
798
+ pthread_mutex_destroy (& analyzer -> inspector_list_mutex );
799
+
693
800
/* Free spectral tuner */
694
801
if (analyzer -> stuner != NULL )
695
802
su_specttuner_destroy (analyzer -> stuner );
696
803
804
+ /* Free all pending overridable requests */
805
+ while (analyzer -> insp_overridable != NULL ) {
806
+ req = analyzer -> insp_overridable -> next ;
807
+
808
+ suscan_inspector_overridable_request_destroy (
809
+ analyzer -> insp_overridable );
810
+
811
+ analyzer -> insp_overridable = req ;
812
+ }
813
+
697
814
/* Free read buffer */
698
815
if (analyzer -> read_buf != NULL )
699
816
free (analyzer -> read_buf );
@@ -798,7 +915,7 @@ suscan_analyzer_new(
798
915
799
916
/* Allocate read buffer */
800
917
801
- new -> read_size = params -> detector_params .window_size ;
918
+ new -> read_size = SUSCAN_ANALYZER_READ_SIZE ; /* params->detector_params.window_size; */
802
919
803
920
if ((new -> read_buf = malloc (
804
921
new -> read_size * sizeof (SUCOMPLEX ))) == NULL ) {
@@ -821,8 +938,15 @@ suscan_analyzer_new(
821
938
/* Periodic updates */
822
939
new -> interval_channels = params -> channel_update_int ;
823
940
new -> interval_psd = params -> psd_update_int ;
824
- clock_gettime (CLOCK_MONOTONIC_RAW , & new -> last_psd );
825
- clock_gettime (CLOCK_MONOTONIC_RAW , & new -> last_channels );
941
+
942
+ #ifdef __linux__
943
+ clock_gettime (CLOCK_MONOTONIC_COARSE , & new -> last_psd );
944
+ clock_gettime (CLOCK_MONOTONIC_COARSE , & new -> last_channels );
945
+ #else
946
+ clock_gettime (CLOCK_MONOTONIC , & new -> last_psd );
947
+ clock_gettime (CLOCK_MONOTONIC , & new -> last_channels );
948
+ #endif
949
+
826
950
827
951
/* Create channel detector */
828
952
(void ) pthread_mutex_init (& new -> loop_mutex , NULL ); /* Always succeeds */
@@ -852,7 +976,7 @@ suscan_analyzer_new(
852
976
new -> gain_req_mutex_init = SU_TRUE ;
853
977
854
978
/* Create spectral tuner, with matching read size */
855
- st_params .window_size = new -> read_size * 4 ;
979
+ st_params .window_size = det_params . window_size ;
856
980
SU_TRYCATCH (new -> stuner = su_specttuner_new (& st_params ), goto fail );
857
981
858
982
/* Create inspector scheduler and barrier */
@@ -875,9 +999,29 @@ suscan_analyzer_new(
875
999
*/
876
1000
SU_TRYCATCH (pthread_mutex_init (& new -> sched_lock , NULL ) == 0 , goto fail );
877
1001
1002
+ /*
1003
+ * This mutex will protect access to the inspector list. It will allow
1004
+ * resolving an inspector handle without blocking an entire callback
1005
+ */
1006
+
1007
+ SU_TRYCATCH (
1008
+ pthread_mutex_init (& new -> inspector_list_mutex , NULL ) == 0 ,
1009
+ goto fail );
1010
+ new -> inspector_list_init = SU_TRUE ;
1011
+
878
1012
new -> mq_out = mq ;
879
1013
880
1014
SU_TRYCATCH (suscan_source_start_capture (new -> source ), goto fail );
1015
+
1016
+ if (new -> read_size < new -> source -> mtu ) {
1017
+ new -> read_size = new -> source -> mtu ;
1018
+ SUCOMPLEX * temp ;
1019
+ SU_TRYCATCH (
1020
+ temp = realloc (new -> read_buf , new -> read_size * sizeof (SUCOMPLEX )),
1021
+ goto fail );
1022
+ new -> read_buf = temp ;
1023
+ }
1024
+
881
1025
new -> effective_samp_rate = suscan_analyzer_get_samp_rate (new );
882
1026
883
1027
/*
0 commit comments