33 #ifndef NIDAS_LINUX_NIDAS_UTIL_H
34 #define NIDAS_LINUX_NIDAS_UTIL_H
36 #if defined(__KERNEL__)
40 #include <linux/wait.h>
43 #include <linux/circ_buf.h>
44 #include <linux/ktime.h>
45 #include <linux/version.h>
87 #define READ_ONCE(x) ACCESS_ONCE(x)
90 #define READ_ONCE(x) (*(volatile typeof(x) *)&(x))
96 #define WRITE_ONCE(x,val) ACCESS_ONCE(x) = (val)
98 #define WRITE_ONCE(x,val) (*(volatile typeof(x) *)&(x)) = (val)
116 struct dsm_sample_circ_buf {
138 #define GET_HEAD(cbuf,size) \
140 (CIRC_SPACE((cbuf).head,READ_ONCE((cbuf).tail),(size)) > 0 ? \
141 (cbuf).buf[(cbuf).head] : 0);\
152 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
153 #define INCREMENT_HEAD(cbuf,size) \
154 smp_store_release(&(cbuf).head, ((cbuf).head + 1) & ((size) - 1))
156 #define INCREMENT_HEAD(cbuf,size) \
157 do { smp_wmb(); (cbuf).head = ((cbuf).head + 1) & ((size) - 1); } while (0)
160 #define NEXT_HEAD(cbuf,size) \
161 (INCREMENT_HEAD(cbuf,size), GET_HEAD(cbuf,size))
190 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
191 #define GET_TAIL(cbuf,size) \
193 int tmp = CIRC_CNT(smp_load_acquire(&(cbuf).head),(cbuf).tail,size);\
194 (tmp > 0 ? (cbuf).buf[(cbuf).tail] : 0);\
197 #define GET_TAIL(cbuf,size) \
199 int tmp = CIRC_CNT(READ_ONCE((cbuf).head),(cbuf).tail,size);\
200 smp_read_barrier_depends();\
201 (tmp > 0 ? (cbuf).buf[(cbuf).tail] : 0);\
215 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
216 #define INCREMENT_TAIL(cbuf,size) \
217 smp_store_release(&(cbuf).tail, ((cbuf).tail + 1) & ((size) - 1))
220 #define INCREMENT_TAIL(cbuf,size) \
221 do { smp_mb(); (cbuf).tail = ((cbuf).tail + 1) & ((size) - 1); } while(0)
227 #define EMPTY_CIRC_BUF(cbuf) \
228 do { (cbuf).tail = (cbuf).head = 0; smp_mb(); } while(0)
280 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
281 typedef struct timespec thiskernel_timespec_t;
283 typedef struct timespec64 thiskernel_timespec_t;
290 inline void getSystemTimeTs(thiskernel_timespec_t *ts)
292 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
293 ktime_get_real_ts(ts);
295 ktime_get_real_ts64(ts);
304 thiskernel_timespec_t ts;
305 getSystemTimeTs(&ts);
309 #if BITS_PER_LONG == 32 && LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
324 thiskernel_timespec_t ts;
325 getSystemTimeTs(&ts);
326 #if BITS_PER_LONG == 32 && LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
336 struct sample_read_state
339 unsigned int bytesLeft;
345 inline int sample_remains(
const struct sample_read_state* state)
347 return state->bytesLeft != 0;
374 struct dsm_sample_circ_buf* cbuf,
struct sample_read_state* state,
375 wait_queue_head_t* readq);
379 struct dsm_sample_circ_buf* cbuf,
struct sample_read_state* state);
385 struct screen_timetag_data
390 unsigned int dtTmsec;
404 unsigned int nptsCalc;
422 unsigned int samplesPerDay;
424 #ifdef DO_TIMETAG_ERROR_AVERAGE
457 int deltaT_Usec,
int adjustUsec);
#define SECS_PER_DAY
Definition: pc104sg.c:552
void free_dsm_circ_buf(struct dsm_sample_circ_buf *c)
Definition: nidas_util.c:132
dsm_sample_time_t screen_timetag(struct screen_timetag_data *td, dsm_sample_time_t tt)
Adjust time tags in a series which should have a fixed delta-T, such as from an A2D.
Definition: nidas_util.c:260
ssize_t nidas_circbuf_read(struct file *filp, char __user *buf, size_t count, struct dsm_sample_circ_buf *cbuf, struct sample_read_state *state, wait_queue_head_t *readq)
Definition: nidas_util.c:196
#define TMSECS_PER_SEC
Definition: types.h:135
ssize_t nidas_circbuf_read_nowait(struct file *filp, char __user *buf, size_t count, struct dsm_sample_circ_buf *cbuf, struct sample_read_state *state)
Definition: nidas_util.c:162
int dsm_sample_time_t
Depending on the module, either tenths of milliseconds, or milliseconds since 00:00 UTC today...
Definition: types.h:48
void init_dsm_circ_buf(struct dsm_sample_circ_buf *c)
Definition: nidas_util.c:155
#define NSECS_PER_TMSEC
Definition: types.h:107
int alloc_dsm_circ_buf(struct dsm_sample_circ_buf *c, size_t dlen, int blen)
Definition: nidas_util.c:62
int realloc_dsm_circ_buf(struct dsm_sample_circ_buf *c, size_t dlen, int blen)
Definition: nidas_util.c:149
#define NSECS_PER_MSEC
Definition: types.h:102
#define MSECS_PER_SEC
Definition: ublox.cc:58
void screen_timetag_init(struct screen_timetag_data *td, int deltaT_Usec, int adjustUsec)
Definition: nidas_util.c:221