• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* uisthread.c
2  *
3  * Copyright (C) 2010 - 2013 UNISYS CORPORATION
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or (at
9  * your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14  * NON INFRINGEMENT.  See the GNU General Public License for more
15  * details.
16  */
17 
18 /* @ALL_INSPECTED */
19 #include <asm/processor.h>
20 #include <linux/signal.h>
21 #include <linux/sched.h>
22 #include <linux/kthread.h>
23 #include "uniklog.h"
24 #include "uisutils.h"
25 #include "uisthread.h"
26 
27 #define KILL(a, b, c) kill_pid(find_vpid(a), b, c)
28 
29 /* this is shorter than using __FILE__ (full path name) in
30  * debug/info/error messages
31  */
32 #define CURRENT_FILE_PC UISLIB_PC_uisthread_c
33 #define __MYFILE__ "uisthread.c"
34 
35 /*****************************************************/
36 /* Exported functions                                */
37 /*****************************************************/
38 
39 /* returns 0 for failure, 1 for success */
40 int
uisthread_start(struct uisthread_info * thrinfo,int (* threadfn)(void *),void * thrcontext,char * name)41 uisthread_start(struct uisthread_info *thrinfo,
42 		int (*threadfn)(void *), void *thrcontext, char *name)
43 {
44 	thrinfo->should_stop = 0;
45 	/* used to stop the thread */
46 	init_completion(&thrinfo->has_stopped);
47 	thrinfo->task = kthread_create(threadfn, thrcontext, name, NULL);
48 	if (IS_ERR(thrinfo->task)) {
49 		thrinfo->id = 0;
50 		return 0;	/* failure */
51 	}
52 	thrinfo->id = thrinfo->task->pid;
53 	wake_up_process(thrinfo->task);
54 	LOGINF("started thread pid:%d\n", thrinfo->id);
55 	return 1;
56 
57 }
58 EXPORT_SYMBOL_GPL(uisthread_start);
59 
60 void
uisthread_stop(struct uisthread_info * thrinfo)61 uisthread_stop(struct uisthread_info *thrinfo)
62 {
63 	int ret;
64 	int stopped = 0;
65 
66 	if (thrinfo->id == 0)
67 		return;		/* thread not running */
68 
69 	LOGINF("uisthread_stop stopping id:%d\n", thrinfo->id);
70 	thrinfo->should_stop = 1;
71 	ret = KILL(thrinfo->id, SIGHUP, 1);
72 	if (ret) {
73 		LOGERR("unable to signal thread %d\n", ret);
74 	} else {
75 		/* give up if the thread has NOT died in 1 minute */
76 		if (wait_for_completion_timeout(&thrinfo->has_stopped, 60 * HZ))
77 			stopped = 1;
78 		else
79 			LOGERR("timed out trying to signal thread\n");
80 	}
81 	if (stopped) {
82 		LOGINF("uisthread_stop stopped id:%d\n", thrinfo->id);
83 		thrinfo->id = 0;
84 	}
85 }
86 EXPORT_SYMBOL_GPL(uisthread_stop);
87