Yet another reason why you should
subscribe to LWN if you care about kernel internals
The patch is fairly simple:
- Code: Select all
diff -u blackmagic-io-10.9.10a2.orig/bm_util.c blackmagic-io-10.9.10a2/bm_util.c
--- blackmagic-io-10.9.10a2.orig/bm_util.c 2018-01-08 02:46:14.000000000 +0100
+++ blackmagic-io-10.9.10a2/bm_util.c 2018-01-31 23:27:01.543121803 +0100
@@ -411,39 +411,45 @@
return jiffies_to_usecs(jiffies);
}
+static void timer_thunk(struct timer_list* kernel_timer)
+{
+ bm_timer_t* timer = container_of(kernel_timer, bm_timer_t, kernel_timer);
+ (*timer->callback)(timer->data);
+}
+
bm_timer_t* bm_timer_alloc(bm_timer_callback_t callback, void* data)
{
bm_timer_t* timer = bm_kmalloc(sizeof(bm_timer_t));
if (!timer)
return NULL;
- init_timer(timer);
- timer->function = (void(*)(unsigned long))callback;
- timer->data = (long)data;
+ timer->callback = callback;
+ timer->data = data;
+ timer_setup(&timer->kernel_timer, timer_thunk, 0);
return timer;
}
void bm_timer_free(bm_timer_t* timer)
{
- del_timer(timer);
+ del_timer(&timer->kernel_timer);
bm_kfree(timer);
}
void bm_timer_expire_in(bm_timer_t* timer, uint64_t ns)
{
- timer->expires = jiffies + (ns * HZ + NSEC_PER_SEC - 1) / NSEC_PER_SEC;
- add_timer(timer);
+ timer->kernel_timer.expires = jiffies + (ns * HZ + NSEC_PER_SEC - 1) / NSEC_PER_SEC;
+ add_timer(&timer->kernel_timer);
}
void bm_timer_expire_at(bm_timer_t* timer, uint64_t ns)
{
- timer->expires = (ns * HZ + NSEC_PER_SEC - 1) / NSEC_PER_SEC;
- add_timer(timer);
+ timer->kernel_timer.expires = (ns * HZ + NSEC_PER_SEC - 1) / NSEC_PER_SEC;
+ add_timer(&timer->kernel_timer);
}
void bm_timer_cancel(bm_timer_t* timer)
{
- del_timer(timer);
+ del_timer(&timer->kernel_timer);
}
// Event waiting
diff -u blackmagic-io-10.9.10a2.orig/bm_util.h blackmagic-io-10.9.10a2/bm_util.h
--- blackmagic-io-10.9.10a2.orig/bm_util.h 2018-01-08 02:46:14.000000000 +0100
+++ blackmagic-io-10.9.10a2/bm_util.h 2018-01-31 23:27:01.543121803 +0100
@@ -112,8 +112,12 @@
// Timer
struct timer_list;
-typedef struct timer_list bm_timer_t;
typedef void (*bm_timer_callback_t)(void*);
+typedef struct {
+ struct timer_list kernel_timer;
+ bm_timer_callback_t callback;
+ void *data;
+} bm_timer_t;
uint64_t bm_absolute_time_us(void);
Tested with 4.15.0-rc8 only, with simple MediaExpress preview on a Mini Recorder 4K.
(PS: I really do mean it. LWN is awesome.)