Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
// Copyright (c) 2019 Nordic Semiconductor ASA
// SPDX-License-Identifer: Apache-2.0

// Replace integer constant timeouts with K_MSEC variants
//
// Some existing code assumes that timeout parameters are provided as
// integer milliseconds, when they were intended to be timeout values
// produced by specific constants and macros.  Convert the integer
// literals to the desired equivalent.
//
// Options: --include-headers

virtual patch
virtual report

// ** Handle timeouts at the last position of kernel API arguments

// Base rule provides the complex identifier regular expression
@r_last_timeout@
identifier last_timeout =~ "(?x)^k_
( delayed_work_submit(|_to_queue)
| futex_wait
| mbox_data_block_get
| (mbox|msgq)_get
| mem_(pool|slab)_alloc
| mutex_lock
| pipe_(get|put)
| poll
| queue_get
| sem_take
| sleep
| stack_pop
| thread_create
| timer_start
| work_poll_submit(|_to_queue)
)$";
@@
last_timeout(...)

// Identify call sites where an identifier is used for the timeout
@r_last_timeout_id
 extends r_last_timeout
@
identifier D;
position p;
@@
last_timeout@p(..., D)

// Select call sites where a constant literal (not identifier) is used
// for the timeout and replace the constant with the appropriate macro

@r_last_timeout_const_patch
 extends r_last_timeout
 depends on patch
@
constant C;
position p != r_last_timeout_id.p;
@@
last_timeout@p(...,
(
- 0
+ K_NO_WAIT
|
- -1
+ K_FOREVER
|
- C
+ K_MSEC(C)
)
 )

@r_last_timeout_const_report
 extends r_last_timeout
 depends on report
@
constant C;
position p != r_last_timeout_id.p;
@@
last_timeout@p(..., C)

@script:python
 depends on report
@
fn << r_last_timeout.last_timeout;
p << r_last_timeout_const_report.p;
C << r_last_timeout_const_report.C;
@@
msg = "WARNING: replace constant {} with timeout in {}".format(C, fn)
coccilib.report.print_report(p[0], msg);

// ** Convert integer delays in K_THREAD_DEFINE to the appropriate macro

// Identify declarers where an identifier is used for the delay
@r_thread_decl_id@
declarer name K_THREAD_DEFINE;
identifier C;
position p;
@@
K_THREAD_DEFINE@p(..., C);

// Select declarers with constant literal delay and replace with
// appropriate macro
@depends on patch@
declarer name K_THREAD_DEFINE;
constant C;
position p != r_thread_decl_id.p;
@@
K_THREAD_DEFINE@p(...,
(
- 0
+ K_NO_WAIT
|
- -1
+ K_FOREVER
|
- C
+ K_MSEC(C)
)
 );

// Identify declarers where an identifier is used for the delay
@r_thread_decl_const
 depends on report@
declarer name K_THREAD_DEFINE;
constant C;
position p != r_thread_decl_id.p;
@@
K_THREAD_DEFINE@p(..., C);


@script:python
 depends on report
@
C << r_thread_decl_const.C;
p << r_thread_decl_const.p;
@@
msg = "WARNING: replace constant {} with timeout in K_THREAD_DEFINE".format(C)
coccilib.report.print_report(p[0], msg);

// ** Handle k_timer_start where the second (not last) argument is a
// ** constant literal.

// Select call sites where an identifier is used for the duration timeout
@r_timer_duration@
expression T;
identifier D;
expression I;
position p;
@@
k_timer_start@p(T, D, I)

// Select call sites where a constant literal (not identifier) is used
// for the timeout and replace the constant with the appropriate macro
@depends on patch@
expression T;
constant C;
expression I;
position p != r_timer_duration.p;
@@
k_timer_start@p(T,
(
- 0
+ K_NO_WAIT
|
- -1
+ K_FOREVER
|
- C
+ K_MSEC(C)
)
, I)

@r_timer_duration_report
 depends on report
@
expression T;
constant C;
expression I;
position p != r_timer_duration.p;
@@
k_timer_start@p(T, C, I)

@script:python
 depends on report
@
p << r_timer_duration_report.p;
C << r_timer_duration_report.C;
@@
msg = "WARNING: replace constant {} with duration timeout in k_timer_start".format(C)
coccilib.report.print_report(p[0], msg);