123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- // Copyright (c) 2019-2020 Nordic Semiconductor ASA
- // SPDX-License-Identifer: Apache-2.0
- // Convert legacy integer timeouts to timeout API
- //
- // 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 integer
- // literals and parameters to the desired equivalent
- //
- // A few expressions that are clearly integer values are also
- // converted.
- //
- // 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);
- // ** Handle call sites where a timeout is specified by an expression
- // ** scaled by MSEC_PER_SEC and replace with the corresponding
- // ** K_SECONDS() expression.
- @r_last_timeout_scaled_patch
- extends r_last_timeout
- depends on patch
- @
- // identifier K_MSEC =~ "^K_MSEC$";
- symbol K_MSEC;
- identifier MSEC_PER_SEC =~ "^MSEC_PER_SEC$";
- expression V;
- position p;
- @@
- last_timeout@p(...,
- (
- - MSEC_PER_SEC
- + K_SECONDS(1)
- |
- - V * MSEC_PER_SEC
- + K_SECONDS(V)
- |
- - K_MSEC(MSEC_PER_SEC)
- + K_SECONDS(1)
- |
- - K_MSEC(V * MSEC_PER_SEC)
- + K_SECONDS(V)
- )
- )
- @r_last_timeout_scaled_report_req
- extends r_last_timeout
- depends on report
- @
- identifier MSEC_PER_SEC =~ "^MSEC_PER_SEC$";
- expression V;
- position p;
- @@
- last_timeout@p(...,
- (
- MSEC_PER_SEC
- | V * MSEC_PER_SEC
- )
- )
- @r_last_timeout_scaled_report_opt
- extends r_last_timeout
- depends on report
- @
- identifier MSEC_PER_SEC =~ "^MSEC_PER_SEC$";
- expression V;
- position p;
- @@
- last_timeout@p(...,
- (
- K_MSEC(MSEC_PER_SEC)
- | K_MSEC(V * MSEC_PER_SEC)
- )
- )
- @script:python
- depends on report
- @
- fn << r_last_timeout.last_timeout;
- p << r_last_timeout_scaled_report_req.p;
- @@
- msg = "WARNING: use K_SECONDS() for timeout in {}".format(fn)
- coccilib.report.print_report(p[0], msg);
- @script:python
- depends on report
- @
- fn << r_last_timeout.last_timeout;
- p << r_last_timeout_scaled_report_opt.p;
- @@
- msg = "NOTE: use K_SECONDS() for timeout in {}".format(fn)
- coccilib.report.print_report(p[0], msg);
- // ** Handle call sites where an integer parameter is used in a
- // ** position that requires a timeout value.
- @r_last_timeout_int_param_patch
- extends r_last_timeout
- depends on patch
- @
- identifier FN;
- identifier P;
- typedef int32_t, uint32_t;
- @@
- FN(...,
- (int
- |int32_t
- |uint32_t
- )
- P, ...) {
- ...
- last_timeout(...,
- -P
- +K_MSEC(P)
- )
- ...
- }
- @r_last_timeout_int_param_report
- extends r_last_timeout
- depends on report
- @
- identifier FN;
- identifier P;
- position p;
- typedef int32_t, uint32_t;
- @@
- FN(...,
- (int
- |int32_t
- |uint32_t
- )
- P, ...) {
- ...
- last_timeout@p(..., P)
- ...
- }
- @script:python
- depends on report
- @
- param << r_last_timeout_int_param_report.P;
- fn << r_last_timeout.last_timeout;
- p << r_last_timeout_int_param_report.p;
- @@
- msg = "WARNING: replace integer parameter {} with timeout in {}".format(param, fn)
- coccilib.report.print_report(p[0], msg);
- // ** Convert timeout-valued delays in K_THREAD_DEFINE with durations
- // ** in milliseconds
- // Select declarers where the startup delay is a timeout expression
- // and replace with the corresponding millisecond duration.
- @r_thread_decl_patch
- depends on patch@
- declarer name K_THREAD_DEFINE;
- identifier K_NO_WAIT =~ "^K_NO_WAIT$";
- identifier K_FOREVER =~ "^K_FOREVER$";
- expression E;
- position p;
- @@
- K_THREAD_DEFINE@p(...,
- (
- - K_NO_WAIT
- + 0
- |
- - K_FOREVER
- + -1
- |
- - K_MSEC(E)
- + E
- )
- );
- //
- @r_thread_decl_report
- depends on report@
- declarer name K_THREAD_DEFINE;
- identifier K_NO_WAIT =~ "^K_NO_WAIT$";
- identifier K_FOREVER =~ "^K_FOREVER$";
- expression V;
- position p;
- @@
- K_THREAD_DEFINE@p(...,
- (
- K_NO_WAIT
- |
- K_FOREVER
- |
- K_MSEC(V)
- )
- );
- @script:python
- depends on report
- @
- p << r_thread_decl_report.p;
- @@
- msg = "WARNING: replace timeout-valued delay with millisecond duration".format()
- 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);
|