@@ -820,11 +820,14 @@ For the details of the interface, look into the 'include/tst_checkpoint.h'.
* Z - zombie process
* T - process is traced
*/
-TST_PROCESS_STATE_WAIT(pid, state)
+TST_PROCESS_STATE_WAIT(pid, state, msec_timeout)
-------------------------------------------------------------------------------
The 'TST_PROCESS_STATE_WAIT()' waits until process 'pid' is in requested
-'state'. The call polls +/proc/pid/stat+ to get this information.
+'state' or timeout is reached. The call polls +/proc/pid/stat+ to get this
+information. A timeout of 0 will wait infinitely.
+
+On timeout -1 is returned and errno set to ETIMEDOUT.
It's mostly used with state 'S' which means that process is sleeping in kernel
for example in 'pause()' or any other blocking syscall.
@@ -47,9 +47,9 @@
*/
#ifdef TST_TEST_H__
-#define TST_PROCESS_STATE_WAIT(pid, state) \
+#define TST_PROCESS_STATE_WAIT(pid, state, msec_timeout) \
tst_process_state_wait(__FILE__, __LINE__, NULL, \
- (pid), (state))
+ (pid), (state), (msec_timeout))
#else
/*
* The same as above but does not use tst_brkm() interface.
@@ -62,11 +62,11 @@ int tst_process_state_wait2(pid_t pid, const char state);
# define TST_PROCESS_STATE_WAIT(cleanup_fn, pid, state) \
tst_process_state_wait(__FILE__, __LINE__, (cleanup_fn), \
- (pid), (state))
+ (pid), (state), 0)
#endif
-void tst_process_state_wait(const char *file, const int lineno,
- void (*cleanup_fn)(void),
- pid_t pid, const char state);
+int tst_process_state_wait(const char *file, const int lineno,
+ void (*cleanup_fn)(void), pid_t pid,
+ const char state, unsigned int msec_timeout);
#endif /* TST_PROCESS_STATE__ */
@@ -28,11 +28,12 @@
#include "test.h"
#include "tst_process_state.h"
-void tst_process_state_wait(const char *file, const int lineno,
- void (*cleanup_fn)(void),
- pid_t pid, const char state)
+int tst_process_state_wait(const char *file, const int lineno,
+ void (*cleanup_fn)(void), pid_t pid,
+ const char state, unsigned int msec_timeout)
{
char proc_path[128], cur_state;
+ unsigned int msecs = 0;
snprintf(proc_path, sizeof(proc_path), "/proc/%i/stat", pid);
@@ -41,10 +42,18 @@ void tst_process_state_wait(const char *file, const int lineno,
"%*i %*s %c", &cur_state);
if (state == cur_state)
- return;
+ break;
- usleep(10000);
+ usleep(1000);
+ msecs += 1;
+
+ if (msecs >= msec_timeout && msec_timeout) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
}
+
+ return 0;
}
int tst_process_state_wait2(pid_t pid, const char state)
@@ -227,7 +227,7 @@ static void mem_test(void)
alloc_maxbytes / 1024, write_msg);
for (i = 0; i < pid_cntr; i++) {
- TST_PROCESS_STATE_WAIT(pid_list[i], 'T');
+ TST_PROCESS_STATE_WAIT(pid_list[i], 'T', 0);
kill(pid_list[i], SIGCONT);
}
}
@@ -159,7 +159,7 @@ static void test_clone_stopped(int t)
child = clone_child(&test_cases[t]);
- TST_PROCESS_STATE_WAIT(child, 'T');
+ TST_PROCESS_STATE_WAIT(child, 'T', 0);
stopped_flag = 0;
@@ -87,7 +87,7 @@ static void verify_futex_cmp_requeue(unsigned int n)
}
for (i = 0; i < tc->num_waiters; i++)
- TST_PROCESS_STATE_WAIT(pid[i], 'S');
+ TST_PROCESS_STATE_WAIT(pid[i], 'S', 0);
tst_res(TINFO, "Test %d: waiters: %d, wakes: %d, requeues: %d",
n, tc->num_waiters, tc->set_wakes, tc->set_requeues);
@@ -80,7 +80,7 @@ static void do_test(unsigned int n)
_exit(0);
}
- TST_PROCESS_STATE_WAIT(pid, 'S');
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
SAFE_KILL(pid, SIGHUP);
tst_reap_children();
}
@@ -57,7 +57,7 @@ static void do_test(void)
_exit(0);
}
- TST_PROCESS_STATE_WAIT(pid, 'S');
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
SAFE_MSGCTL(queue_id, IPC_RMID, NULL);
@@ -38,7 +38,7 @@ static void do_test(void)
do_child();
TST_CHECKPOINT_WAIT(0);
- TST_PROCESS_STATE_WAIT(pid, 'S');
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
kill(pid, SIGINT);
/*
@@ -25,7 +25,7 @@ static void run(void)
pid = SAFE_FORK();
if (!pid) {
- TST_PROCESS_STATE_WAIT(getppid(), 'S');
+ TST_PROCESS_STATE_WAIT(getppid(), 'S', 0);
exit(0);
}
Add a timeout to TST_PROCESS_STATE_WAIT. Timeout can be specified in milliseconds. After timeout it returns -1 and sets errno to ETIMEDOUT. Specifying a timeout of 0 makes it for the most part function like the old TST_PROCESS_STATE_WAIT. Update all existing testcases that used TST_PROCESS_STATE_WAIT and the new test library. Signed-off-by: Jorik Cronenberg <jcronenberg@suse.de> --- v2: removed TST_PROCESS_STATE_WAIT2 change all existing testcases that use TST_PROCESS_STATE_WAIT and new testlib change doc to reflect changes also while going through tests I noticed that my previous implementation was broken and did timeout even with timeout set to 0, that should now also be fixed. doc/test-writing-guidelines.txt | 7 +++++-- include/tst_process_state.h | 12 ++++++------ lib/tst_process_state.c | 19 ++++++++++++++----- testcases/kernel/mem/mtest01/mtest01.c | 2 +- testcases/kernel/syscalls/clone/clone08.c | 2 +- .../syscalls/futex/futex_cmp_requeue01.c | 2 +- .../kernel/syscalls/ipc/msgsnd/msgsnd05.c | 2 +- .../kernel/syscalls/ipc/msgsnd/msgsnd06.c | 2 +- testcases/kernel/syscalls/pause/pause01.c | 2 +- testcases/kernel/syscalls/wait4/wait401.c | 2 +- 10 files changed, 32 insertions(+), 20 deletions(-)