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 */ 40int 41uisthread_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} 58EXPORT_SYMBOL_GPL(uisthread_start); 59 60void 61uisthread_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} 86EXPORT_SYMBOL_GPL(uisthread_stop); 87