-
Notifications
You must be signed in to change notification settings - Fork 0
/
thread.c
165 lines (133 loc) · 3.11 KB
/
thread.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
_ _ _ _ _ _
__| (_) __ _(_) |_ __ _| | ___ ___ __| | __ _
/ _` | |/ _` | | __/ _` | | / __|/ _ \ / _` |/ _` |
| (_| | | (_| | | || (_| | | \__ \ (_) | (_| | (_| |
\__,_|_|\__, |_|\__\__,_|_| |___/\___/ \__,_|\__,_|
|___/ written by Ondra Havel
*/
#define _POSIX_C_SOURCE 201001L
#include <time.h>
#include <string.h>
#include "thread.h"
#include "io.h"
#include "local.h"
static volatile int fl_terminate = 0;
static volatile int fl_running = 0;
volatile unsigned int dso_period_usec;
volatile int dso_trigger_mode = TRIGGER_AUTO;
pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static
void __nsleep(const struct timespec *req)
{
struct timespec rem;
if(nanosleep(req,&rem)==-1) {
while(nanosleep(&rem,&rem)==-1);
}
}
static
void myusleep(unsigned long usec)
{
struct timespec req;
time_t sec = usec / 1000000;
usec -= sec * 1000000;
req.tv_sec = sec;
req.tv_nsec = usec * 1000;
__nsleep(&req);
}
cb_fn my_cb = 0;
void dso_thread_set_cb(cb_fn cb)
{ // TODO: mutex
if(!my_cb)
my_cb = cb;
}
static
void *dso_thread(void *ptr)
{
DMSG("DSO thread started\n");
while(!fl_terminate) {
if(!fl_running) {
pthread_mutex_lock(&thread_mutex); // wait on signal
pthread_mutex_unlock(&thread_mutex);
if(fl_terminate)
return 0;
}
//DMSG("period = %d\n", dso_period_usec);
if(my_cb) {
my_cb();
my_cb = 0;
}
dso_capture_start();
myusleep(dso_period_usec);
dso_trigger_enabled();
int fl_complete = 0;
int trPoint = 0;
int nr_empty = 0;
while(!fl_complete) {
int cs = dso_get_capture_state(&trPoint);
if (cs < 0) {
DMSG("dso_get_capture_state io error\n");
continue;
}
switch(cs) {
case 0: // empty
if(nr_empty == 3) {
dso_capture_start();
nr_empty = 0;
}
nr_empty++;
dso_trigger_enabled();
dso_force_trigger();
myusleep(dso_period_usec);
break;
case 1: // in progress
myusleep(dso_period_usec >> 1);
myusleep(dso_period_usec >> 1);
break;
case 2: // full
pthread_mutex_lock(&buffer_mutex);
if (dso_get_channel_data(dso_buffer, dso_buffer_size) < 0) {
DMSG("Error in command GetChannelData\n");
}
dso_buffer_dirty = 1;
dso_trigger_point = trPoint;
pthread_mutex_unlock(&buffer_mutex);
/*FORMERLEY UPDATE_GUI */
fl_complete = 1;
break;
default:
DMSG("unknown capture state %i\n", cs);
break;
}
}
}
return 0;
}
#include <pthread.h>
static pthread_t my_thread;
void dso_thread_terminate()
{
if(!fl_running)
dso_thread_resume();
fl_terminate = 1;
pthread_join(my_thread, 0);
DMSG("DSO thread terminated\n");
}
void dso_thread_init()
{
if(dso_buffer)
memset(dso_buffer, 0, sizeof(dso_buffer));
pthread_mutex_lock(&thread_mutex);
pthread_create(&my_thread, 0, &dso_thread, 0);
}
void dso_thread_resume()
{
fl_running = 1;
pthread_mutex_unlock(&thread_mutex);
}
void dso_thread_pause()
{
pthread_mutex_lock(&thread_mutex);
fl_running = 0;
}