3535#include "mq.h"
3636#include "msg.h"
3737
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+
38124/************************* Baseband filter API *******************************/
39125SUPRIVATE struct suscan_analyzer_baseband_filter *
40126suscan_analyzer_baseband_filter_new (
@@ -106,7 +192,17 @@ suscan_analyzer_unlock_loop(suscan_analyzer_t *analyzer)
106192 (void ) pthread_mutex_unlock (& analyzer -> loop_mutex );
107193}
108194
195+ SUBOOL
196+ suscan_analyzer_lock_inspector_list (suscan_analyzer_t * analyzer )
197+ {
198+ return pthread_mutex_lock (& analyzer -> inspector_list_mutex ) != -1 ;
199+ }
109200
201+ void
202+ suscan_analyzer_unlock_inspector_list (suscan_analyzer_t * analyzer )
203+ {
204+ (void ) pthread_mutex_unlock (& analyzer -> inspector_list_mutex );
205+ }
110206
111207/************************* Main analyzer thread *******************************/
112208void
@@ -347,7 +443,17 @@ suscan_analyzer_thread(void *data)
347443 goto done );
348444
349445 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+
351457 /* ^^^^^^^^^^^^^ Source parameters update end ^^^^^^^^^^^^^^^^^ */
352458
353459 SU_TRYCATCH (
@@ -456,9 +562,7 @@ suscan_analyzer_init_detector_params(
456562 * params = self -> params .detector_params ;
457563
458564 /* 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 ;
462566
463567 params -> samp_rate = suscan_analyzer_get_samp_rate (self );
464568
@@ -628,7 +732,7 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
628732{
629733 uint32_t type ;
630734 unsigned int i ;
631-
735+ struct suscan_inspector_overridable_request * req ;
632736 void * private ;
633737
634738 /* Prevent source from entering in timeout loops */
@@ -690,10 +794,23 @@ suscan_analyzer_destroy(suscan_analyzer_t *analyzer)
690794 if (analyzer -> loop_init )
691795 pthread_mutex_destroy (& analyzer -> loop_mutex );
692796
797+ if (analyzer -> inspector_list_init )
798+ pthread_mutex_destroy (& analyzer -> inspector_list_mutex );
799+
693800 /* Free spectral tuner */
694801 if (analyzer -> stuner != NULL )
695802 su_specttuner_destroy (analyzer -> stuner );
696803
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+
697814 /* Free read buffer */
698815 if (analyzer -> read_buf != NULL )
699816 free (analyzer -> read_buf );
@@ -798,7 +915,7 @@ suscan_analyzer_new(
798915
799916 /* Allocate read buffer */
800917
801- new -> read_size = params -> detector_params .window_size ;
918+ new -> read_size = SUSCAN_ANALYZER_READ_SIZE ; /* params->detector_params.window_size; */
802919
803920 if ((new -> read_buf = malloc (
804921 new -> read_size * sizeof (SUCOMPLEX ))) == NULL ) {
@@ -821,8 +938,15 @@ suscan_analyzer_new(
821938 /* Periodic updates */
822939 new -> interval_channels = params -> channel_update_int ;
823940 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+
826950
827951 /* Create channel detector */
828952 (void ) pthread_mutex_init (& new -> loop_mutex , NULL ); /* Always succeeds */
@@ -852,7 +976,7 @@ suscan_analyzer_new(
852976 new -> gain_req_mutex_init = SU_TRUE ;
853977
854978 /* 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 ;
856980 SU_TRYCATCH (new -> stuner = su_specttuner_new (& st_params ), goto fail );
857981
858982 /* Create inspector scheduler and barrier */
@@ -875,9 +999,29 @@ suscan_analyzer_new(
875999 */
8761000 SU_TRYCATCH (pthread_mutex_init (& new -> sched_lock , NULL ) == 0 , goto fail );
8771001
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+
8781012 new -> mq_out = mq ;
8791013
8801014 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+
8811025 new -> effective_samp_rate = suscan_analyzer_get_samp_rate (new );
8821026
8831027 /*
0 commit comments