static int usb_hub_thread(void *__hub) { DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_thread function \n"); lock_kernel(); /* * This thread doesn't need any user-level access, * so get rid of all our resources */ daemonize(); reparent_to_init(); /* Setup a nice name */ strcpy(current->comm, "khubd"); /* Send me a signal to get me die (for debugging) */ do { usb_hub_events(); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); } while (!signal_pending(current)); dbg("usb_hub_thread exiting"); unlock_kernel(); complete_and_exit(&khubd_exited, 0); }
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) daemonize(pThreadName /*"%s",pAd->net_dev->name*/); allow_signal(SIGTERM); allow_signal(SIGKILL); current->flags |= PF_NOFREEZE; #else unsigned long flags; daemonize(); reparent_to_init(); strcpy(current->comm, pThreadName); siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) spin_lock_irqsave(¤t->sigmask_lock, flags); flush_signals(current); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); #endif #endif /* signal that we've started the thread */ complete(pNotify); }
static int usb_hub_thread(void *startup) { lock_kernel(); /* * This thread doesn't need any user-level access, * so get rid of all our resources */ daemonize(); reparent_to_init(); /* Block all signals */ spin_lock_irq(¤t->sigmask_lock); sigfillset(¤t->blocked); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); /* Setup a nice name */ strcpy(current->comm, "khubd"); khubd_terminated = 0; complete((struct completion *)startup); /* Set khubd_terminated=1 to get me die */ do { usb_hub_events(); wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list) || khubd_terminated); } while (!khubd_terminated || !list_empty(&hub_event_list)); dbg("usb_hub_thread exiting"); unlock_kernel(); complete_and_exit(&khubd_exited, 0); }
/* * Thread execution entry point function */ DT_Mdep_Thread_Start_Routine_Return_Type DT_Mdep_Thread_Start_Routine(void *thread_handle) { Thread *thread_ptr; thread_ptr = (Thread *) thread_handle; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) reparent_to_init(); #else daemonize(__func__); #endif thread_ptr->function(thread_ptr->param); return 0; }
int khvcd(void *unused) { int i; daemonize(); reparent_to_init(); strcpy(current->comm, "khvcd"); sigfillset(¤t->blocked); for (;;) { for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i) hvc_poll(i); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(TIMEOUT); } }
static int test_thread(void *x) { reparent_to_init(); /* Setup a nice name */ strcpy(current->comm, "testd_usb"); usbprintk("Thread started\n"); test_usb_init(); do { test_usb_events(); my_wait_ms(50); } while (!signal_pending(current)); usbprintk("hub_thread exiting\n"); complete_and_exit(&testd_exited, 0); }
void parse_cmd_line (int* argc_ptr, char*** argv_ptr) { char*** subargv_ptr = argv_ptr; int subargc = (*argc_ptr); gboolean should_reparent = TRUE; gboolean enable_debug = FALSE; int i=0; for (;i<(*argc_ptr);i++) { if(!g_strcmp0 ((*argv_ptr)[i], "-f")) { should_reparent=FALSE; //(*argv_ptr)[i]=NULL; //(*argc_ptr)--; continue; } if(!g_strcmp0 ((*argv_ptr)[i], "-d")) { enable_debug = TRUE; should_reparent=FALSE; //(*argv_ptr)[i]=NULL; //(*argc_ptr)--; continue; } } //uncomment previous comments //consolidate *argv, remove NULL slots. _consolidate_cmd_line(subargc, subargv_ptr); if (should_reparent) { //FIXME: shall we exit? if (close_std_stream()) return; reparent_to_init(); } if (enable_debug) { g_setenv("G_MESSAGES_DEBUG", "all", FALSE); } }
static int usb_led_probe_task(void *x) { unsigned long flags; daemonize(); reparent_to_init(); strcpy(current->comm, "USBLEDprobe"); do { usb_led_flag = 1; interruptible_sleep_on(&usb_led_queue); usb_led_flag = 0; USB_SET_LED(USB_DISCONNECT); interruptible_sleep_on_timeout(&usb_led_blink_queue, 50); USB_SET_LED(USB_CONNECT); interruptible_sleep_on_timeout(&usb_led_blink_queue, 50); } while (!signal_pending(current)); return 0; }
void ral_task_customize( IN KTHREAD *pTask) { RTBT_OS_TASK *pOSTask = (RTBT_OS_TASK *)pTask->pOSThread; #ifndef KTHREAD_SUPPORT #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) daemonize((PSTRING)&pOSTask->taskName[0]); allow_signal(SIGTERM); allow_signal(SIGKILL); current->flags |= PF_NOFREEZE; #else unsigned long flags; daemonize(); reparent_to_init(); strcpy(current->comm, &pOSTask->taskName[0]); siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) spin_lock_irqsave(¤t->sigmask_lock, flags); flush_signals(current); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); #endif #endif RTMP_GET_OS_PID(pOSTask->taskPID, current->pid); /* signal that we've started the thread */ complete(&pOSTask->taskComplete); #endif }
static int kthread(void *_create) { struct kthread_create_info *create = _create; int (*threadfn)(void *data); void *data; // printk("kthread: create %p\n", create); threadfn = create->threadfn; data = create->data; // printk("kthread: threadfn %p data %p\n", threadfn, data); lock_kernel(); daemonize(); reparent_to_init(); spin_lock_irq(¤t->sigmask_lock); sigfillset(¤t->blocked); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); unlock_kernel(); set_current_state(TASK_INTERRUPTIBLE); complete(&create->started); // printk("kthread: about to call thread function\n"); if (!kthread_should_stop()) threadfn(data); // printk("kthread: thread function done\n"); if (kthread_should_stop()) complete(&kthread_stop_complete); return 0; }
/*! * @brief Implements the kernel thread for KeyV "bottom half" interrupt handling. * * The function that implements the kernel thread for interrupt handling. This * is used to "simulate" a bottom half because the I2C driver only works in task * context, not in interrupt or bottom half context. The function simply executes * the same bottom half function that would normally run in the bottom half tasklet. * * @param unused An unused parameter * * @return 0, but the function will only return upon receiving an abort signal. */ static int interrupt_thread_loop (void *unused) { struct sched_param thread_sched_params = {.sched_priority = (MAX_RT_PRIO - 1)}; unsigned int value; int i; static unsigned int init_start = 0; /* Usual thread setup. */ lock_kernel(); daemonize("kkeyvd"); strcpy(current->comm, "kkeyvd"); reparent_to_init(); /* Ignore all signals, but those which terminate the thread. */ siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)); unlock_kernel(); /* Sets a realtime thread's priority */ sched_setscheduler(current, SCHED_FIFO, &thread_sched_params); /* * Loop unless an abort signal is received. All signals, but the abort signals are * masked off in the common setup. As a result only abort signals can be pending. */ while(!signal_pending(current)) { value = 0; /* Sleep if an interrupt isn't pending again */ if (wait_event_interruptible (interrupt_thread_wait, interrupt_flag) < 0) { break; } /* Reset the interrupt flag */ interrupt_flag = 0; /* Handle the interrupt */ if(keyv_reg_read(&value) != 0) { interrupt_fail = true; /* If a key is previously pressed, and enabled, then report a key release */ for(i = 0; i < KEYV_KEY_MAX; i++) { if((KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i))) { generate_key_event(key_states[i].keycode, KEYUP); } } previous_key = KEYV_KEY_NONE; continue; } /* If the interrupt is for an initialization start of the KeyV part, then set * the variable to monitor */ if((value & KEYV_MODE0) == KEYV_MODE0) { init_start = 1; /* If a key is previously pressed, and enabled, then report a key release */ for(i = 0; i < KEYV_KEY_MAX; i++) { if((KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i))) { generate_key_event(key_states[i].keycode, KEYUP); } } previous_key = KEYV_KEY_NONE; } else { /* If the KeyV part was previously initializing, see if it is done */ if(init_start) { /* If initialization is complete, clear variable and be done */ if((value >> 4) == KEYV_DONE) { init_start = 0; /* Wait at least 100ms for reset and calibration to really finish */ msleep(100); keyv_reg_write(key_value); keyv_mode_set(); } /* If initialization was previously happening but the upper 4 bits do not match * 0x4, then the 4 KeyV keys are not ready to be used. At this point * there would be a mechanical issue so the keys should be disabled and the part * should be placed in the appropriate mode. */ else { /* Wait at least 100ms for reset and calibration to really finish */ msleep(100); key_value = KEYV_KEY_NONE; keyv_mode_set(); } } /* If KeyV part was not previously initializing, start to check key presses */ else { /* If a key is currently released, previously pressed, * and enabled, then report a key release */ for(i = 0; i < KEYV_KEY_MAX; i++) { if(!(KEYV_BITMASK_ISSET(value, i)) && (KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i))) { generate_key_event(key_states[i].keycode, KEYUP); } } /* If a key is currently pressed, previously not pressed, * and enabled, then report keypress */ for(i = 0; i < KEYV_KEY_MAX; i++) { if((KEYV_BITMASK_ISSET(value, i)) && !(KEYV_BITMASK_ISSET(previous_key, i)) && (KEYV_BITMASK_ISSET(key_value, i))) { generate_key_event(key_states[i].keycode, KEYDOWN); } } previous_key = value; } } }
/* * This is the lockd kernel thread */ static void lockd(struct svc_rqst *rqstp) { struct svc_serv *serv = rqstp->rq_server; int err = 0; unsigned long grace_period_expire; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; lock_kernel(); /* * Let our maker know we're running. */ nlmsvc_pid = current->pid; up(&lockd_start); daemonize(); reparent_to_init(); sprintf(current->comm, "lockd"); /* Process request with signals blocked. */ spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* kick rpciod */ rpciod_up(); dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); if (!nlm_timeout) nlm_timeout = LOCKD_DFLT_TIMEO; nlmsvc_timeout = nlm_timeout * HZ; grace_period_expire = set_grace_period(); /* * The main request loop. We don't terminate until the last * NFS mount or NFS daemon has gone away, and we've been sent a * signal, or else another process has taken over our job. */ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { long timeout = MAX_SCHEDULE_TIMEOUT; if (signalled()) { spin_lock_irq(¤t->sighand->siglock); flush_signals(current); spin_unlock_irq(¤t->sighand->siglock); if (nlmsvc_ops) { nlmsvc_ops->detach(); grace_period_expire = set_grace_period(); } } /* * Retry any blocked locks that have been notified by * the VFS. Don't do this during grace period. * (Theoretically, there shouldn't even be blocked locks * during grace period). */ if (!nlmsvc_grace_period) timeout = nlmsvc_retry_blocked(); /* * Find a socket with data available and call its * recvfrom routine. */ err = svc_recv(serv, rqstp, timeout); if (err == -EAGAIN || err == -EINTR) continue; if (err < 0) { printk(KERN_WARNING "lockd: terminating on error %d\n", -err); break; } dprintk("lockd: request from %08x\n", (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr)); /* * Look up the NFS client handle. The handle is needed for * all but the GRANTED callback RPCs. */ rqstp->rq_client = NULL; if (nlmsvc_ops) { nlmsvc_ops->exp_readlock(); rqstp->rq_client = nlmsvc_ops->exp_getclient(&rqstp->rq_addr); } if (nlmsvc_grace_period && time_before(grace_period_expire, jiffies)) nlmsvc_grace_period = 0; svc_process(serv, rqstp); /* Unlock export hash tables */ if (nlmsvc_ops) nlmsvc_ops->exp_unlock(); } /* * Check whether there's a new lockd process before * shutting down the hosts and clearing the slot. */ if (!nlmsvc_pid || current->pid == nlmsvc_pid) { if (nlmsvc_ops) nlmsvc_ops->detach(); nlm_shutdown_hosts(); nlmsvc_pid = 0; } else printk(KERN_DEBUG "lockd: new process, skipping host shutdown\n"); wake_up(&lockd_exit); /* Exit the RPC thread */ svc_exit_thread(rqstp); /* release rpciod */ rpciod_down(); /* Release module */ MOD_DEC_USE_COUNT; }
static int w99685_thread(void *arg) { int ret = 0; UINT32 imglen = 0;; UINT16 blocks = 0; UINT8 choice = 0; w685cf_t *priv = arg; ImageContainer_t *imgcontainerp = priv->images; /* * This thread doesn't need any user-level access, * so get rid of all our resources.. */ daemonize(); reparent_to_init(); // exit_files(current); // current->files = init_task.files; // atomic_inc(¤t->files->count); // daemonize(); // reparent_to_init(); /* avoid getting signals */ // spin_lock_irq(¤t->sigmask_lock); // flush_signals(current); // sigfillset(¤t->blocked); // recalc_sigpending(current); // spin_unlock_irq(¤t->sigmask_lock); /* set our name for identification purposes */ sprintf(current->comm, "W99685CFI_thread"); //Get Image Data, :P for(;;) { if(priv->user) { // Someone open the camera, get the data. W99685CMD_GetImageLen(&imglen); TDEBUG("imagelen: %d", imglen); if(imglen > 0&& imglen <= W685BUF_SIZE) { blocks = (imglen-1+DATABLOCKSIZE)/DATABLOCKSIZE; if(blocks < W685BUF_SIZE/DATABLOCKSIZE) { choice = imgcontainerp->which; TDEBUG("Write choice: %d, and choicelen: %d", choice, IMAGELEN(imgcontainerp, choice)); down( &((IMAGEHOLD(imgcontainerp, choice)).ilock) ); if(IMAGELEN(imgcontainerp, choice) > 0) //Have had data, don't overwrite it. goto do_next; W99685_GetData(IMAGEDATA(imgcontainerp, choice) ,blocks); (IMAGEHOLD(imgcontainerp, choice)).len = imglen; do_next: imgcontainerp->which = (++(imgcontainerp->which))%IMGCONTAINERSIZE; up( &((IMAGEHOLD(imgcontainerp, choice)).ilock) ); } TDEBUG("Sleep..."); wait_ms(20); } else if(imglen < 0) //can't recover, it crazy :( { W685_ERR("Get image length error: %d\n", imglen); break; } else { wait_ms(500); continue; } } else sleep_on_timeout(&priv->waitq, 10); } out: return ret; }
/* * This task waits until at least one touchscreen is touched. It then loops * digitizing and generating events until no touchscreens are being touched. */ static int xts_thread(void *arg) { int any_pens_down; struct xts_dev *dev; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); xts_task = tsk; daemonize(); reparent_to_init(); strcpy(xts_task->comm, XTS_NAME); xts_task->tty = NULL; /* only want to receive SIGKILL */ spin_lock_irq(&xts_task->sigmask_lock); siginitsetinv(&xts_task->blocked, sigmask(SIGKILL)); recalc_sigpending(xts_task); spin_unlock_irq(&xts_task->sigmask_lock); complete(&task_sync); add_wait_queue(&irq_wait, &wait); any_pens_down = 0; for (;;) { /* * Block waiting for interrupt or if any pens are down, either * an interrupt or timeout to sample again. */ set_current_state(TASK_INTERRUPTIBLE); if (any_pens_down) schedule_timeout(HZ / 100); while (signal_pending(tsk)) { siginfo_t info; /* Only honor the signal if we're cleaning up */ if (task_shutdown) goto exit; /* * Someone else sent us a kill (probably the * shutdown scripts "Sending all processes the * KILL signal"). Just dequeue it and ignore * it. */ spin_lock_irq(¤t->sigmask_lock); (void)dequeue_signal(¤t->blocked, &info); spin_unlock_irq(¤t->sigmask_lock); } schedule(); any_pens_down = 0; for (dev = dev_list; dev; dev = dev->next_dev) { if (dev->pen_is_down) { u32 x, y; XTouchscreen_GetPosition_2D(&dev->Touchscreen, &x, &y); event_add(dev, 255, (u16) x, (u16) y); dev->pen_was_down = 1; any_pens_down = 1; } else if (dev->pen_was_down) { event_add(dev, 0, 0, 0); dev->pen_was_down = 0; } } } exit: remove_wait_queue(&irq_wait, &wait); xts_task = NULL; complete_and_exit(&task_sync, 0); }