Beispiel #1
0
/*
 * wait for a lock to be granted
 */
static inline struct rw_semaphore *rwsem_down_failed_common(struct rw_semaphore *sem,
                         struct rwsem_waiter *waiter,
                         signed long adjustment)
{
   struct task_struct *tsk = current;
   signed long count;

   set_task_state(tsk,TASK_UNINTERRUPTIBLE);

   /* set up my own style of waitqueue */
   spin_lock(&sem->wait_lock);
   waiter->task = tsk;

   list_add_tail(&waiter->list,&sem->wait_list);

   /* note that we're now waiting on the lock, but no longer actively read-locking */
   count = rwsem_atomic_update(adjustment,sem);

   /* if there are no longer active locks, wake the front queued process(es) up
    * - it might even be this process, since the waker takes a more active part
    */
   if (!(count & RWSEM_ACTIVE_MASK))
      sem = __rwsem_do_wake(sem,1);

   spin_unlock(&sem->wait_lock);

   /* wait to be given the lock */
   for (;;) {
      if (!waiter->flags)
         break;
      schedule();
      set_task_state(tsk, TASK_UNINTERRUPTIBLE);
   }

   tsk->state = TASK_RUNNING;

   return sem;
}
Beispiel #2
0
void wq_wait(struct waitqueue_head *q)
{
	unsigned irqflag;
	DEFINE_WAIT(wait);

	spin_lock_irqsave(q->lock, irqflag);
	if (list_empty(&wait.link))
		list_add(&wait.link, q->list.prev);

	set_task_state(current, TASK_WAITING);
	spin_unlock_irqrestore(q->lock, irqflag);

	schedule();
}
Beispiel #3
0
void my_timer(unsigned long data)
{
	struct task_struct * task = (struct task_struct *)data;
	printk("Kernel Timer Time-Out Function Doing...\n");
	printk(KERN_WARNING "[SK_DD]my_timer=>proc_state_%d:%lx!!\n", task->pid, task->state);

	set_task_state(task, EXIT_DEAD);	//include/linux/sched.h
	//set_task_state(task, EXIT_ZOMBIE);	//include/linux/sched.h
	
	//set_task_state(task, TASK_RUNNING);	//include/linux/sched.h
	//__activate_task(task, rq);

	printk(KERN_WARNING "[SK_DD]my_timer=>proc_state_%d:%lx!!\n", task->pid, task->state);
	printk("Kernel Timer Time-Out Function Done!!!\n");
}
Beispiel #4
0
int ACTIVE_TASK::resume_or_start(bool first_time) {
    if (log_flags.task) {
        msg_printf(result->project, MSG_INFO,
            "[task] %s task %s: FLOPS left %.2fG",
            first_time?"Starting":"Resuming",
            result->name, result->sim_flops_left/1e9
        );
    }
    set_task_state(PROCESS_EXECUTING, "start");
    char buf[256];
    sprintf(buf, "Starting %s<br>&nbsp;&nbsp;%s<br>&nbsp;&nbsp;deadline %s<br>",
        result->name, result->project->get_project_name(),
        sim_time_string(result->report_deadline)
    );
    html_msg += buf;
    return 0;
}
Beispiel #5
0
int task_kill_self(struct task_struct *task)
{
	struct task_struct *system_killer = pid_get_task(0);

	if (!system_killer)
		return -EINVAL;
	
	/*
	 * when a task try to kill himself, need to
	 * wake up system_killer process to help doing
	 * this
	 */
	kernel_debug("Kill self\n");
	set_task_state(task, PROCESS_STATE_IDLE);
	wakeup_task(system_killer);
	sched();
	return 0;
}
Beispiel #6
0
void wq_wake(struct waitqueue_head *q, int nr_task)
{
	struct list *p = q->list.next;
	struct task *task;
	unsigned irqflag;

	spin_lock_irqsave(q->lock, irqflag);
	while (p != &q->list && nr_task) {
		task = get_container_of(p, struct waitqueue, link)->task;
		set_task_state(task, TASK_RUNNING);
		runqueue_add(task);
		list_del(p);

		p = q->list.next;
		nr_task--;
	}
	spin_unlock_irqrestore(q->lock, irqflag);
}
Beispiel #7
0
void down_read_failed_biased(struct rw_semaphore *sem)
{
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);

	add_wait_queue(&sem->wait, &wait);	/* put ourselves at the head of the list */

	for (;;) {
		if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
			break;
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
		if (!sem->read_bias_granted)
			schedule();
	}

	remove_wait_queue(&sem->wait, &wait);
	tsk->state = TASK_RUNNING;
}
Beispiel #8
0
static void psnedf_task_wake_up(struct task_struct *task)
{
	unsigned long		flags;
	psnedf_domain_t* 	pedf = task_pedf(task);
	rt_domain_t* 		edf  = task_edf(task);
	lt_t			now;

	TRACE_TASK(task, "wake_up at %llu\n", litmus_clock());
	raw_readyq_lock_irqsave(&pedf->slock, flags);

	set_task_state(task, TASK_RUNNING);

	BUG_ON(is_queued(task));
	now = litmus_clock();
	if (is_sporadic(task) && is_tardy(task, now)
#ifdef CONFIG_LITMUS_LOCKING
	/* We need to take suspensions because of semaphores into
	 * account! If a job resumes after being suspended due to acquiring
	 * a semaphore, it should never be treated as a new job release.
	 */
	    && !is_priority_boosted(task)
#endif
		) {
		/* new sporadic release */
		release_at(task, now);
		sched_trace_task_release(task);
	}

	budget_state_machine(task,on_wakeup);

	/* Only add to ready queue if it is not the currently-scheduled
	 * task. This could be the case if a task was woken up concurrently
	 * on a remote CPU before the executing CPU got around to actually
	 * de-scheduling the task, i.e., wake_up() raced with schedule()
	 * and won.
	 */
	if (pedf->scheduled != task) {
		requeue(task, edf);
		psnedf_preempt_check(pedf);
	}

	raw_readyq_unlock_irqrestore(&pedf->slock, flags);
	TRACE_TASK(task, "wake up done\n");
}
Beispiel #9
0
/* coverity[+kill] */
void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *msgdata)
{
	libcfs_catastrophe = 1;
	libcfs_debug_msg(msgdata, "LBUG\n");

	if (in_interrupt()) {
		panic("LBUG in interrupt.\n");
		/* not reached */
	}

	dump_stack();
	if (!libcfs_panic_on_lbug)
		libcfs_debug_dumplog();
	if (libcfs_panic_on_lbug)
		panic("LBUG");
	set_task_state(current, TASK_UNINTERRUPTIBLE);
	while (1)
		schedule();
}
Beispiel #10
0
/* Wait for the lock to become unbiased. Since we're
 * a writer, we'll make ourselves exclusive.
 */
void down_write_failed(struct rw_semaphore *sem)
{
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);

	up_write(sem);	/* this takes care of granting the lock */

	add_wait_queue_exclusive(&sem->wait, &wait);

	while (atomic_read(&sem->count) < 0) {
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
		if (atomic_read(&sem->count) >= 0)
			break;	/* we must attempt to acquire or bias the lock */
		schedule();
	}

	remove_wait_queue(&sem->wait, &wait);
	tsk->state = TASK_RUNNING;
}
Beispiel #11
0
int __sched
__down_failed_interruptible(struct semaphore *sem)
{
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);
	long ret = 0;

#ifdef CONFIG_DEBUG_SEMAPHORE
	printk("%s(%d): down failed(%p)\n",
	       tsk->comm, tsk->pid, sem);
#endif

	tsk->state = TASK_INTERRUPTIBLE;
	wmb();
	add_wait_queue_exclusive(&sem->wait, &wait);

	while (__sem_update_count(sem, -1) <= 0) {
		if (signal_pending(current)) {
			/*
			 * A signal is pending - give up trying.
			 * Set sem->count to 0 if it is negative,
			 * since we are no longer sleeping.
			 */
			__sem_update_count(sem, 0);
			ret = -EINTR;
			break;
		}
		schedule();
		set_task_state(tsk, TASK_INTERRUPTIBLE);
	}

	remove_wait_queue(&sem->wait, &wait);
	tsk->state = TASK_RUNNING;
	wake_up(&sem->wait);

#ifdef CONFIG_DEBUG_SEMAPHORE
	printk("%s(%d): down %s(%p)\n",
	       current->comm, current->pid,
	       (ret < 0 ? "interrupted" : "acquired"), sem);
#endif
	return ret;
}
Beispiel #12
0
int wake_up_process(struct task_struct *tsk)
{
	int need_resched = 0;

	if (tsk->state == TASK_UNINTERRUPTIBLE)
		return -1;

	if (!pri_bitmap)
		need_resched = 1;

	struct task_struct *next = pick_next_task();
	if (next->prio >= tsk->prio)
		need_resched = 1;

	set_task_state(tsk, TASK_RUNNING);

	if (need_resched)
		set_tsk_need_resched(current);

	return 0;
}
Beispiel #13
0
void __sched
__down_failed(struct semaphore *sem)
{
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);

#ifdef CONFIG_DEBUG_SEMAPHORE
	printk("%s(%d): down failed(%p)\n",
	       tsk->comm, tsk->pid, sem);
#endif

	tsk->state = TASK_UNINTERRUPTIBLE;
	wmb();
	add_wait_queue_exclusive(&sem->wait, &wait);

	/*
	 * Try to get the semaphore.  If the count is > 0, then we've
	 * got the semaphore; we decrement count and exit the loop.
	 * If the count is 0 or negative, we set it to -1, indicating
	 * that we are asleep, and then sleep.
	 */
	while (__sem_update_count(sem, -1) <= 0) {
		schedule();
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
	}
	remove_wait_queue(&sem->wait, &wait);
	tsk->state = TASK_RUNNING;

	/*
	 * If there are any more sleepers, wake one of them up so
	 * that it can either get the semaphore, or set count to -1
	 * indicating that there are still processes sleeping.
	 */
	wake_up(&sem->wait);

#ifdef CONFIG_DEBUG_SEMAPHORE
	printk("%s(%d): down acquired(%p)\n",
	       tsk->comm, tsk->pid, sem);
#endif
}
Beispiel #14
0
/* Wait for the lock to become unbiased.  Readers
 * are non-exclusive. =)
 */
struct rw_semaphore *down_read_failed(struct rw_semaphore *sem)
{
	struct task_struct *tsk = current;
	DECLARE_WAITQUEUE(wait, tsk);

	/* this takes care of granting the lock */
	__up_op_read(sem, __rwsem_wake);

	add_wait_queue(&sem->wait, &wait);

	while (atomic_read(&sem->count) < 0) {
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
		if (atomic_read(&sem->count) >= 0)
			break;
		schedule();
	}

	remove_wait_queue(&sem->wait, &wait);
	tsk->state = TASK_RUNNING;

	return sem;
}
Beispiel #15
0
static int __init make_init_task()
{
	extern void idle(); /* becomes init task */

	/* stack must be allocated first. and to build root relationship
	 * properly `current` must be set to `init`. */
	current = &init;

	if (alloc_mm(&init, NULL, 0))
		return -ERR_ALLOC;

	set_task_dressed(&init, TASK_STATIC | TASK_KERNEL, idle);
	set_task_context_hard(&init, wrapper);
	set_task_pri(&init, LOW_PRIORITY);
	set_task_state(&init, TASK_RUNNING);

	/* make it the sole */
	list_link_init(&init.children);
	list_link_init(&init.sibling);

	return 0;
}
/*
 * get a write lock on the semaphore
 */
void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
{
	struct rwsem_waiter waiter;
	struct task_struct *tsk;
	unsigned long flags;

	raw_spin_lock_irqsave(&sem->wait_lock, flags);
#ifdef CONFIG_BRCM_DEBUG_RWSEM
		sem->wr_owner = current;
#endif

	/* set up my own style of waitqueue */
	tsk = current;
	waiter.task = tsk;
	waiter.type = RWSEM_WAITING_FOR_WRITE;
	list_add_tail(&waiter.list, &sem->wait_list);

	/* wait for someone to release the lock */
	for (;;) {
		/*
		 * That is the key to support write lock stealing: allows the
		 * task already on CPU to get the lock soon rather than put
		 * itself into sleep and waiting for system woke it or someone
		 * else in the head of the wait list up.
		 */
		if (sem->activity == 0)
			break;
		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
		raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
		schedule();
		raw_spin_lock_irqsave(&sem->wait_lock, flags);
	}
	/* got the lock */
	sem->activity = -1;
	list_del(&waiter.list);

	raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}
Beispiel #17
0
void event_configure_notify(Window win) {
    // change in root window (xrandr)
    if (win == server.root_win) {
        signal_pending = SIGUSR1;
        return;
    }

    // 'win' is a trayer icon
    TrayWindow* traywin;
    GSList* l;
    for (l = systray.list_icons; l; l = l->next) {
        traywin = (TrayWindow*)l->data;
        if (traywin->tray_id == win) {
            XMoveResizeWindow(server.dsp, traywin->id, traywin->x, traywin->y,
                              traywin->width, traywin->height);
            XResizeWindow(server.dsp, traywin->tray_id, traywin->width,
                          traywin->height);
            panel_refresh = 1;
            return;
        }
    }

    // 'win' move in another monitor
    if (nb_panel == 1) return;
    Task* tsk = task_get_task(win);
    if (!tsk) return;

    Panel* p = tsk->area.panel;
    if (p->monitor != window_get_monitor(win)) {
        remove_task(tsk);
        tsk = add_task(win);
        if (win == window_get_active()) {
            set_task_state(tsk, TASK_ACTIVE);
            task_active = tsk;
        }
        panel_refresh = 1;
    }
}
Beispiel #18
0
static int
dispose_iface(struct device *dev)
{
	struct keywest_iface *iface = dev_get_drvdata(dev);
	int i, rc;
	
	/* Make sure we stop all activity */
	down(&iface->sem);

	spin_lock_irq(&iface->lock);
	while (iface->state != state_idle) {
		spin_unlock_irq(&iface->lock);
		set_task_state(current,TASK_UNINTERRUPTIBLE);
		schedule_timeout(HZ/10);
		spin_lock_irq(&iface->lock);
	}
	iface->state = state_dead;
	spin_unlock_irq(&iface->lock);
	free_irq(iface->irq, iface);
	up(&iface->sem);

	/* Release all channels */
	for (i=0; i<iface->chan_count; i++) {
		struct keywest_chan* chan = &iface->channels[i];
		if (i2c_get_adapdata(&chan->adapter) == NULL)
			continue;
		rc = i2c_del_adapter(&chan->adapter);
		i2c_set_adapdata(&chan->adapter, NULL);
		/* We aren't that prepared to deal with this... */
		if (rc)
			printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n");
	}
	iounmap((void *)iface->base);
	dev_set_drvdata(dev, NULL);
	kfree(iface);

	return 0;
}
static ssize_t wup_read(struct file *file, char __user *buf,
			size_t count, loff_t *pos)
{
	int want_to_sleep = 0;

	spin_lock(&lock);
	if (!p) {
		p = current;
		want_to_sleep = 1;
	}
	spin_unlock(&lock);

	if (want_to_sleep) {
		set_task_state(current, TASK_UNINTERRUPTIBLE);
		schedule();
		/* wake_up_process が呼ばれるまで眠る */

		spin_lock(&lock);
		p = NULL;
		spin_unlock(&lock);
	}

	return 0;
}
Beispiel #20
0
static void __init load_user_task()
{
	extern char _user_task_list;
	struct task *p;
	unsigned int pri;

	for (p = (struct task *)&_user_task_list; *(unsigned int *)p; p++) {
		if (p->addr == NULL)
			continue;

		/* share the init kernel stack to save memory */
		if (alloc_mm(p, &init, STACK_SHARED))
			continue;

		pri = get_task_pri(p);
		set_task_dressed(p, p->flags | STACK_SHARED, p->addr);
		set_task_pri(p, pri);
		set_task_context(p, wrapper);

		/* make it runnable, and add into runqueue */
		set_task_state(p, TASK_RUNNING);
		runqueue_add(p);
	}
}
Beispiel #21
0
Task *add_task (Window win)
{
	if (!win) return 0;
	if (window_is_hidden(win)) return 0;

	int monitor;
	if (nb_panel > 1) {
		monitor = window_get_monitor (win);
		if (monitor >= nb_panel) monitor = 0;
	}
	else monitor = 0;

	Task new_tsk;
	new_tsk.win = win;
	new_tsk.desktop = window_get_desktop (win);
	new_tsk.area.panel = &panel1[monitor];
	new_tsk.current_state = window_is_iconified(win) ? TASK_ICONIFIED : TASK_NORMAL;

  window_get_coordinates (win, &new_tsk.geometry);

	// allocate only one title and one icon
	// even with task_on_all_desktop and with task_on_all_panel
	new_tsk.title = 0;
	int k;
	for (k=0; k<TASK_STATE_COUNT; ++k) {
		new_tsk.icon[k] = 0;
		new_tsk.state_pix[k] = 0;
	}
	get_title(&new_tsk);
	get_icon(&new_tsk);

	//printf("task %s : desktop %d, monitor %d\n", new_tsk->title, desktop, monitor);
	XSelectInput (server.dsp, new_tsk.win, PropertyChangeMask|StructureNotifyMask);

	GPtrArray* task_group = g_ptr_array_new();
	Taskbar *tskbar;
	Task *new_tsk2=0;

	for (uint32_t j=0, desktop_count = panel1[monitor].nb_desktop; j < desktop_count ; j++) {
		if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;

		tskbar = &panel1[monitor].taskbar[j];
		new_tsk2 = calloc(1, sizeof(Task));
		memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
		new_tsk2->area.parent = tskbar;
		new_tsk2->win = new_tsk.win;
		new_tsk2->desktop = new_tsk.desktop;
		/* new_tsk2->win_x = new_tsk.win_x; */
		/* new_tsk2->win_y = new_tsk.win_y; */
		/* new_tsk2->win_w = new_tsk.win_w; */
		/* new_tsk2->win_h = new_tsk.win_h; */
    new_tsk2->geometry = new_tsk.geometry;
		new_tsk2->current_state = -1;  // to update the current state later in set_task_state...
		if (new_tsk2->desktop == ALLDESKTOP && server.desktop != (int)j) {
			// hide ALLDESKTOP task on non-current desktop
			new_tsk2->area.visible = 0;
		}
		new_tsk2->title = new_tsk.title;
		if (panel1[monitor].g_task.tooltip_enabled)
			new_tsk2->area._get_tooltip_text = task_get_tooltip;
		for (k=0; k<TASK_STATE_COUNT; ++k) {
			new_tsk2->icon[k] = new_tsk.icon[k];
			new_tsk2->state_pix[k] = 0;
		}
		new_tsk2->icon_width = new_tsk.icon_width;
		new_tsk2->icon_height = new_tsk.icon_height;
		tskbar->area.children = g_slist_append(tskbar->area.children, new_tsk2);
		tskbar->area.resize = 1;
		g_ptr_array_add(task_group, new_tsk2);
		//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
	}
	Window* key = calloc(1, sizeof(Window));
	*key = new_tsk.win;
	g_hash_table_insert(win_to_task_table, key, task_group);
	set_task_state(new_tsk2, new_tsk.current_state);

	sort_taskbar_for_win(win);

	if (panel_mode == MULTI_DESKTOP) {
		Panel *panel = new_tsk2->area.panel;
		panel->area.resize = 1;
	}

	if (window_is_urgent(win)) {
		add_urgent(new_tsk2);
	}

	return new_tsk2;
}
Beispiel #22
0
void event_property_notify(XEvent* e) {
    int i;
    Task* tsk;
    Window win = e->xproperty.window;
    Atom at = e->xproperty.atom;

    if (xsettings_client) xsettings_client_process_event(xsettings_client, e);
    if (win == server.root_win) {
        if (!server.got_root_win) {
            XSelectInput(server.dsp, server.root_win,
                         PropertyChangeMask | StructureNotifyMask);
            server.got_root_win = 1;
        }

        // Change name of desktops
        else if (at == server.atom._NET_DESKTOP_NAMES) {
            if (!taskbarname_enabled) return;
            GSList* l, *list = server_get_name_of_desktop();
            gchar* name;
            Taskbar* tskbar;
            for (i = 0; i < nb_panel; i++) {
                l = list;
                for (uint8_t j = 0; j < panel1[i].desktop_count; j++) {
                    if (l) {
                        name = g_strdup(l->data);
                        l = l->next;
                    } else
                        name = g_strdup_printf("%d", j + 1);
                    tskbar = &panel1[i].taskbar[j];
                    if (strcmp(name, tskbar->bar_name.name) != 0) {
                        g_free(tskbar->bar_name.name);
                        tskbar->bar_name.name = name;
                        tskbar->bar_name.area.resize = 1;
                    } else
                        g_free(name);
                }
            }
            for (l = list; l; l = l->next) g_free(l->data);
            g_slist_free(list);
            panel_refresh = 1;
        }
        // Change number of desktops
        else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) {
            if (!taskbar_enabled) return;
            server.nb_desktop = server_get_number_of_desktop();
            if (server.nb_desktop <= server.desktop) {
                server.desktop = server.nb_desktop - 1;
            }
            cleanup_taskbar();
            init_taskbar();
            for (i = 0; i < nb_panel; i++) {
                init_taskbar_panel(&panel1[i]);
                set_panel_items_order(&panel1[i]);
                visible_taskbar(&panel1[i]);
                panel1[i].area.resize = 1;
            }
            task_refresh_tasklist();
            active_task();
            panel_refresh = 1;
        }
        // Change desktop
        else if (at == server.atom._NET_CURRENT_DESKTOP) {
            if (!taskbar_enabled) return;
            int old_desktop = server.desktop;
            server.desktop = server_get_current_desktop();
            for (i = 0; i < nb_panel; i++) {
                Panel* panel = &panel1[i];
                set_taskbar_state(&panel->taskbar[old_desktop], TASKBAR_NORMAL);
                set_taskbar_state(&panel->taskbar[server.desktop], TASKBAR_ACTIVE);
                // check ALLDESKTOP task => resize taskbar
                Taskbar* tskbar;
                Task* tsk;
                GSList* l;
                if (server.nb_desktop > old_desktop) {
                    tskbar = &panel->taskbar[old_desktop];
                    l = tskbar->area.list;
                    if (taskbarname_enabled) l = l->next;
                    for (; l; l = l->next) {
                        tsk = l->data;
                        if (tsk->desktop == ALLDESKTOP) {
                            tsk->area.on_screen = 0;
                            tskbar->area.resize = 1;
                            panel_refresh = 1;
                        }
                    }
                }
                tskbar = &panel->taskbar[server.desktop];
                l = tskbar->area.list;
                if (taskbarname_enabled) l = l->next;
                for (; l; l = l->next) {
                    tsk = l->data;
                    if (tsk->desktop == ALLDESKTOP) {
                        tsk->area.on_screen = 1;
                        tskbar->area.resize = 1;
                    }
                }
            }
        }
        // Window list
        else if (at == server.atom._NET_CLIENT_LIST) {
            task_refresh_tasklist();
            panel_refresh = 1;
        }
        // Change active
        else if (at == server.atom._NET_ACTIVE_WINDOW) {
            active_task();
            panel_refresh = 1;
        } else if (at == server.atom._XROOTPMAP_ID ||
                   at == server.atom._XROOTMAP_ID) {
            // change Wallpaper
            for (i = 0; i < nb_panel; i++) {
                set_panel_background(&panel1[i]);
            }
            panel_refresh = 1;
        }
    } else {
        tsk = task_get_task(win);
        if (!tsk) {
            if (at != server.atom._NET_WM_STATE)
                return;
            else {
                // xfce4 sends _NET_WM_STATE after minimized to tray, so we need to
                // check if window is mapped
                // if it is mapped and not set as skip_taskbar, we must add it to our
                // task list
                XWindowAttributes wa;
                XGetWindowAttributes(server.dsp, win, &wa);
                if (wa.map_state == IsViewable && !window_is_skip_taskbar(win)) {
                    if ((tsk = add_task(win)))
                        panel_refresh = 1;
                    else
                        return;
                } else
                    return;
            }
        }

        // Window title changed
        if (at == server.atom._NET_WM_VISIBLE_NAME ||
                at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) {
            if (get_title(tsk)) {
                if (g_tooltip.mapped && (g_tooltip.area == (Area*)tsk)) {
                    tooltip_copy_text((Area*)tsk);
                    tooltip_update();
                }
                panel_refresh = 1;
            }
        }
        // Demand attention
        else if (at == server.atom._NET_WM_STATE) {
            if (window_is_urgent(win)) {
                add_urgent(tsk);
            }
            if (window_is_skip_taskbar(win)) {
                remove_task(tsk);
                panel_refresh = 1;
            }
        } else if (at == server.atom.WM_STATE) {
            // Iconic state
            int state = (task_active && tsk->win == task_active->win ? TASK_ACTIVE
                         : TASK_NORMAL);
            if (window_is_iconified(win)) state = TASK_ICONIFIED;
            set_task_state(tsk, state);
            panel_refresh = 1;
        }
        // Window icon changed
        else if (at == server.atom._NET_WM_ICON) {
            get_icon(tsk);
            panel_refresh = 1;
        }
        // Window desktop changed
        else if (at == server.atom._NET_WM_DESKTOP) {
            uint32_t desktop = window_get_desktop(win);
            // bug in windowmaker : send unecessary 'desktop changed' when focus
            // changed
            if (desktop != tsk->desktop) {
                remove_task(tsk);
                tsk = add_task(win);
                active_task();
                panel_refresh = 1;
            }
        } else if (at == server.atom.WM_HINTS) {
            XWMHints* wmhints = XGetWMHints(server.dsp, win);
            if (wmhints && wmhints->flags & XUrgencyHint) {
                add_urgent(tsk);
            }
            XFree(wmhints);
        }

        if (!server.got_root_win)
            server.root_win = RootWindow(server.dsp, server.screen);
    }
}
Beispiel #23
0
/// Start a task in a slot directory.
/// This includes setting up soft links,
/// passing preferences, and starting the process.
///
/// Current dir is top-level Synecdoche dir.
///
/// \post
/// - If any error occurs
///   - #task_state is #PROCESS_COULDNT_START
///   - CLIENT_STATE::report_result_error() is called
/// - else
///   - #task_state is #PROCESS_EXECUTING
///
/// \return 0 on success, nonzero otherwise.
int ACTIVE_TASK::start() {
    char exec_name[256], exec_path[256];
    unsigned int i;
    FILE_REF fref;
    int retval;
    // F*** goto, need to define some variables here instead of where they are used!
    std::ostringstream err_stream;
#ifdef _WIN32
    std::string cmd_line;
    std::string slotdirpath;
#else
    // Needs to be defined here because those gotos would skip the
    // initialization of 'cmdline' and 'argv' if it would be defined later.
    std::ostringstream cmdline;
    std::list<std::string> argv;
#endif
    if ((!full_init_done) && (log_flags.task)) {
        msg_printf(wup->project, MSG_INFO,
            "Starting %s", result->name
        );
    }
    if (log_flags.cpu_sched) {
        msg_printf(wup->project, MSG_INFO,
            "[cpu_sched] Starting %s%s", result->name, (full_init_done) ? " (resume)" : " (initial)"
        );
    }

    // Always check if all required files are present. If not, trigger
    // re-downloads and don't start the science application.
    FILE_INFO_PSET missing_file_infos;
    retval = gstate.input_files_available(result, true, &missing_file_infos);
    if (retval) {
        for (FILE_INFO_PSET::iterator it = missing_file_infos.begin(); it != missing_file_infos.end(); ++it) {
            FILE_INFO* fip = *it;
            if (fip) {
                err_stream << "Input file " << fip->name
                           << " missing or invalid: " << retval;
            } else {
                err_stream << "Input file missing or invalid";
                // We can't trigger a new download if we don't have
                // any file information. Just fail here as before.
                goto error;
            }
            fip->status = FILE_NOT_PRESENT;
        }
    }
    if (!missing_file_infos.empty()) {
        // Some files are missing and are set for re-transfer.
        // Update status and return without error.
        result->set_state(RESULT_FILES_DOWNLOADING, "start");
        set_task_state(PROCESS_UNINITIALIZED, "start");
        next_scheduler_state = PROCESS_UNINITIALIZED;
        return 0;
    }

    if (!full_init_done) {
        checkpoint_cpu_time = 0;
        checkpoint_wall_time = gstate.now;
    }
    current_cpu_time = checkpoint_cpu_time;
    episode_start_cpu_time = checkpoint_cpu_time;
    debt_interval_start_cpu_time = checkpoint_cpu_time;

    graphics_request_queue.init(result->name);        // reset message queues
    process_control_queue.init(result->name);

    if (!app_client_shm.shm) {
        retval = get_shmem_seg_name();
        if (retval) {
            err_stream << "Can't get shared memory segment name: " << boincerror(retval);
            goto error;
        }
    }

    // this must go AFTER creating shmem name,
    // since the shmem name is part of the file
    //
    retval = write_app_init_file();
    if (retval) {
        err_stream << "Can't write init file: " << retval;
        goto error;
    }

    // set up applications files
    //
    strcpy(exec_name, "");
    for (i=0; i<app_version->app_files.size(); i++) {
        fref = app_version->app_files[i];
        FILE_INFO* fip = fref.file_info;
        std::string file_path = get_pathname(fip);
        if (fref.main_program) {
            if (is_image_file(fip->name)) {
                err_stream << "Main program " << fip->name << " is an image file";
                retval = ERR_NO_SIGNATURE;
                goto error;
            }
            if (!fip->executable && !wup->project->anonymous_platform) {
                err_stream << "Main program " << fip->name << " is not executable";
                retval = ERR_NO_SIGNATURE;
                goto error;
            }
            safe_strcpy(exec_name, fip->name.c_str());
            safe_strcpy(exec_path, file_path.c_str());
        }
        // anonymous platform may use different files than
        // when the result was started, so link files even if not first time
        if ((!full_init_done) || (wup->project->anonymous_platform)) {
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
            if (retval) {
                err_stream << "Can't link input file";
                goto error;
            }
        }
    }
    if (!strlen(exec_name)) {
        err_stream << "No main program specified";
        retval = ERR_NOT_FOUND;
        goto error;
    }

    // set up input, output files
    if (!full_init_done) {
        for (i=0; i<wup->input_files.size(); i++) {
            fref = wup->input_files[i];
            const FILE_INFO* fip = fref.file_info;
            std::string file_path = get_pathname(fref.file_info);
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
            if (retval) {
                err_stream << "Can't link input file";
                goto error;
            }
        }
        for (i=0; i<result->output_files.size(); i++) {
            fref = result->output_files[i];
            if (fref.copy_file) continue;
            const FILE_INFO* fip = fref.file_info;
            std::string file_path = get_pathname(fref.file_info);
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, false);
            if (retval) {
                err_stream << "Can't link output file";
                goto error;
            }
        }
        full_init_done = true;
    }

    link_user_files();

    if (gstate.exit_before_start) {
        exit(0);
    }

#ifdef _WIN32
    PROCESS_INFORMATION process_info;
    STARTUPINFO startup_info;
    LPVOID environment_block = NULL;
    char error_msg[1024];
    char error_msg2[1024];

    memset(&process_info, 0, sizeof(process_info));
    memset(&startup_info, 0, sizeof(startup_info));
    startup_info.cb = sizeof(startup_info);

    // suppress 2-sec rotating hourglass cursor on startup
    //
    startup_info.dwFlags = STARTF_FORCEOFFFEEDBACK;

    app_client_shm.reset_msgs();

    if (config.run_apps_manually) {
        // fill in core client's PID so we won't think app has exited
        pid = GetCurrentProcessId();
        pid_handle = GetCurrentProcess();
        set_task_state(PROCESS_EXECUTING, "start");
        return 0;
    }
    // NOTE: in Windows, stderr is redirected in boinc_init_diagnostics();

    cmd_line = exec_path + std::string(" ") + wup->command_line;
    if (strlen(app_version->cmdline)) {
        cmd_line += std::string(" ") + app_version->cmdline;
    }
    slotdirpath = relative_to_absolute(slot_dir);
    bool success = false;

    for (i=0; i<5; i++) {
        if (sandbox_account_service_token != NULL) {
            // Find CreateEnvironmentBlock/DestroyEnvironmentBlock pointers
            tCEB    pCEB = NULL;
            tDEB    pDEB = NULL;
            HMODULE hUserEnvLib = NULL;

            hUserEnvLib = LoadLibrary("userenv.dll");
            if (hUserEnvLib) {
                pCEB = (tCEB) GetProcAddress(hUserEnvLib, "CreateEnvironmentBlock");
                pDEB = (tDEB) GetProcAddress(hUserEnvLib, "DestroyEnvironmentBlock");
            }

            if (!pCEB(&environment_block, sandbox_account_service_token, FALSE)) {
                if (log_flags.task) {
                    windows_error_string(error_msg, sizeof(error_msg));
                    msg_printf(wup->project, MSG_INFO,
                        "Process environment block creation failed: %s", error_msg
                    );
                }
            }

            if (CreateProcessAsUser(
                sandbox_account_service_token,
                exec_path,
                (LPSTR)cmd_line.c_str(),
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS|CREATE_UNICODE_ENVIRONMENT,
                environment_block,
                slotdirpath.c_str(),
                &startup_info,
                &process_info
            )) {
                success = true;
                break;
            } else {
                windows_error_string(error_msg, sizeof(error_msg));
                msg_printf(wup->project, MSG_INTERNAL_ERROR,
                    "Process creation failed: %s", error_msg
                );
            }

            if (!pDEB(environment_block)) {
                if (log_flags.task) {
                    windows_error_string(error_msg, sizeof(error_msg2));
                    msg_printf(wup->project, MSG_INFO,
                        "Process environment block cleanup failed: %s",
                        error_msg2
                    );
                }
            }

            if (hUserEnvLib) {
                pCEB = NULL;
                pDEB = NULL;
                FreeLibrary(hUserEnvLib);
            }

        } else {
            if (CreateProcess(
                exec_path,
                (LPSTR)cmd_line.c_str(),
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS,
                NULL,
                slotdirpath.c_str(),
                &startup_info,
                &process_info
            )) {
                success = true;
                break;
            } else {
                windows_error_string(error_msg, sizeof(error_msg));
                msg_printf(wup->project, MSG_INTERNAL_ERROR,
                    "Process creation failed: %s", error_msg
                );
            }
        }
        boinc_sleep(drand());
    }

    if (!success) {
        err_stream << "CreateProcess() failed - " << error_msg;
        retval = ERR_EXEC;
        goto error;
    }
    pid = process_info.dwProcessId;
    pid_handle = process_info.hProcess;
    CloseHandle(process_info.hThread);  // thread handle is not used
#else
    // Unix/Linux/Mac case

    // Set up core/app shared memory seg if needed
    //
    if (!app_client_shm.shm) {
        if (app_version->api_major_version() >= 6) {
            // Use mmap() shared memory
            std::string buf = slot_dir + std::string("/") + std::string(MMAPPED_FILE_NAME);
            if (g_use_sandbox) {
                if (!boinc_file_exists(buf.c_str())) {
                    int fd = open(buf.c_str(), O_RDWR | O_CREAT, 0660);
                    if (fd >= 0) {
                        close (fd);
#ifdef SANDBOX
                        set_to_project_group(buf.c_str());
#endif
                    }
                }
            }
            retval = create_shmem_mmap(
                buf.c_str(), sizeof(SHARED_MEM), (void**)&app_client_shm.shm
            );
        } else {
            // Use shmget() shared memory
            retval = create_shmem(
                shmem_seg_name, sizeof(SHARED_MEM), gstate.boinc_project_gid,
                (void**)&app_client_shm.shm
            );

            if (retval) {
                needs_shmem = true;
                destroy_shmem(shmem_seg_name);
                return retval;
            }
        }
        needs_shmem = false;
    }
    app_client_shm.reset_msgs();

#if (defined (__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
    // PowerPC apps emulated on i386 Macs crash if running graphics
    powerpc_emulated_on_i386 = ! is_native_i386_app(exec_path);
#endif
    if (config.run_apps_manually) {
        pid = getpid();     // use the client's PID
        set_task_state(PROCESS_EXECUTING, "start");
        return 0;
    }

    // Prepare command line for the science app:
    cmdline << wup->command_line;
    if (strlen(app_version->cmdline)) {
        cmdline << ' ' << app_version->cmdline;
    }
    argv = parse_command_line(cmdline.str().c_str());
    if (log_flags.task_debug) {
        debug_print_argv(argv);
    }

    pid = fork();
    if (pid == -1) {
        err_stream << "fork() failed: " << strerror(errno);
        retval = ERR_FORK;
        goto error;
    }
    if (pid == 0) {
        // from here on we're running in a new process.
        // If an error happens,
        // exit nonzero so that the core client knows there was a problem.

        // don't pass stdout to the app
        //
        int fd = open("/dev/null", O_RDWR);
        dup2(fd, STDOUT_FILENO);
        close(fd);

        // add to library path:
        // - the project dir (../../projects/X)
        // - the slot dir (.)
        // - the Synecdoche dir (../..)
        // We use relative paths in case higher-level dirs
        // are not readable to the account under which app runs
        //
        std::string pdir = get_project_dir(wup->project);

        std::ostringstream libpath;
        const char* env_lib_path = getenv("LD_LIBRARY_PATH");
        if (env_lib_path) {
            libpath << env_lib_path << ':';
        }
        libpath << "../../" << pdir << ":.:../..";
        setenv("LD_LIBRARY_PATH", libpath.str().c_str(), 1);

        retval = chdir(slot_dir.c_str());
        if (retval) {
            perror("chdir");
            fflush(NULL);
            _exit(errno);
        }

#if 0
        // set stack size limit to the max.
        // Some BOINC apps have reported problems with exceeding
        // small stack limits (e.g. 8 MB)
        // and it seems like the best thing to raise it as high as possible
        //
        struct rlimit rlim;
#define MIN_STACK_LIMIT 64000000
        getrlimit(RLIMIT_STACK, &rlim);
        if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur <= MIN_STACK_LIMIT) {
            if (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_max > MIN_STACK_LIMIT) {
                rlim.rlim_cur = MIN_STACK_LIMIT;
            } else {
                rlim.rlim_cur = rlim.rlim_max;
            }
            setrlimit(RLIMIT_STACK, &rlim);
        }
#endif

        // hook up stderr to a specially-named file
        //
        freopen(STDERR_FILE, "a", stderr);

        // set idle process priority
#ifdef HAVE_SETPRIORITY
        if (setpriority(PRIO_PROCESS, 0, PROCESS_IDLE_PRIORITY)) {
            perror("setpriority");
        }
#endif
        std::string path = std::string("../../") + std::string(exec_path);
        if (g_use_sandbox) {
            std::ostringstream switcher_path;
            switcher_path << "../../" << SWITCHER_DIR << '/' << SWITCHER_FILE_NAME;
            argv.push_front(exec_name);
            argv.push_front(path);
            argv.push_front(SWITCHER_FILE_NAME);
            // Files written by projects have user boinc_project and group boinc_project,
            // so they must be world-readable so Synecdoche can read them.
            umask(2);
            retval = do_execv(switcher_path.str(), argv);
        } else {
            argv.push_front(exec_name);
            retval = do_execv(path, argv);
        }
        msg_printf(wup->project, MSG_INTERNAL_ERROR,
            "Process creation (%s) failed: %s, errno=%d\n", path.c_str(), boincerror(retval), errno
        );
        perror("execv");
        fflush(NULL);
        _exit(errno);
    }

    if (log_flags.task_debug) {
        msg_printf(wup->project, MSG_INFO,
            "[task_debug] ACTIVE_TASK::start(): forked process: pid %d\n", pid
        );
    }

#endif
    set_task_state(PROCESS_EXECUTING, "start");
    return 0;

    // go here on error; "error_msg" contains error message, "retval" is nonzero
    //
error:
    // if something failed, it's possible that the executable was munged.
    // Verify it to trigger another download.
    //
    gstate.input_files_available(result, true);
    gstate.report_result_error(*result, "%s", err_stream.str().c_str());
    set_task_state(PROCESS_COULDNT_START, "start");
    return retval;
}
Beispiel #24
0
/*
 * Lock a mutex (possibly interruptible), slowpath:
 */
static inline int
__mutex_lock_common(struct mutex *lock, long state)
{
	struct task_struct *task = current;
	struct mutex_waiter waiter;
	unsigned int old_val;
	unsigned long flags;

	spin_lock_mutex(&lock->wait_lock, flags);

	/* add waiting tasks to the end of the waitqueue (FIFO): */
	list_add_tail(&waiter.list, &lock->wait_list);
	waiter.task = task;

	old_val = atomic_xchg(&lock->count, -1);
	if (old_val == 1)
		goto done;

	for (;;) {
		/*
		 * Lets try to take the lock again - this is needed even if
		 * we get here for the first time (shortly after failing to
		 * acquire the lock), to make sure that we get a wakeup once
		 * it's unlocked. Later on, if we sleep, this is the
		 * operation that gives us the lock. We xchg it to -1, so
		 * that when we release the lock, we properly wake up the
		 * other waiters:
		 */
		old_val = atomic_xchg(&lock->count, -1);
		if (old_val == 1)
			break;

		/*
		 * got a signal? (This code gets eliminated in the
		 * TASK_UNINTERRUPTIBLE case.)
		 */
#if 0
		if (unlikely((state == TASK_INTERRUPTIBLE &&
					signal_pending(task)) ||
			      (state == TASK_KILLABLE &&
					fatal_signal_pending(task)))) {
			mutex_remove_waiter(lock, &waiter,
					    task_thread_info(task));
			spin_unlock_mutex(&lock->wait_lock, flags);

			return -EINTR;
		}
#endif
		set_task_state(task, state);

		/* didnt get the lock, go to sleep: */
		spin_unlock_mutex(&lock->wait_lock, flags);
		schedule();
		spin_lock_mutex(&lock->wait_lock, flags);
	}

done:
	/* got the lock - rejoice! */
	mutex_remove_waiter(lock, &waiter, task_thread_info(task));

	/* set it to 0 if there are no waiters left: */
	if (likely(list_empty(&lock->wait_list)))
		atomic_set(&lock->count, 0);

	spin_unlock_mutex(&lock->wait_lock, flags);


	return 0;
}
Beispiel #25
0
int remove_from_rq(pcontext *pcb)
{
	set_task_state(pcb, SLEEPING);
	return remove_task(pcb, 0);	
}
Beispiel #26
0
int wake_up_task(void *pcb)
{
    pcb = (pcontext *)pcb;
	set_task_state(pcb, READY);
	return insert_task(pcb);
}
/*
 * Setup MobiCore kernel log. It assumes it's running on CORE 0!
 * The fastcall will complain is that is not the case!
 */
long mobicore_log_setup(void)
{
	unsigned long phys_log_buf;
	union fc_generic fc_log;
	struct sched_param param = { .sched_priority = 1 };

	long ret;
	log_pos = 0;
	log_buf = NULL;
	log_thread = NULL;
	log_line = NULL;
	log_line_len = 0;
	prev_eol = false;
	prev_source = 0;
	thread_err = 0;

	/* Sanity check for the log size */
	if (log_size < PAGE_SIZE)
		return -EFAULT;
	else
		log_size = PAGE_ALIGN(log_size);

	log_line = kzalloc(LOG_LINE_SIZE, GFP_KERNEL);
	if (IS_ERR(log_line)) {
		MCDRV_DBG_ERROR(mcd, "failed to allocate log line!");
		return -ENOMEM;
	}

	log_thread = kthread_create(log_worker, NULL, "mc_log");
	if (IS_ERR(log_thread)) {
		MCDRV_DBG_ERROR(mcd, "MobiCore log thread creation failed!");
		ret = -EFAULT;
		goto err_free_line;
	}

	sched_setscheduler(log_thread, SCHED_IDLE, &param);
	/*
	 * We are going to map this buffer into virtual address space in SWd.
	 * To reduce complexity there, we use a contiguous buffer.
	 */
	log_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
					   get_order(log_size));
	if (!log_buf) {
		MCDRV_DBG_ERROR(mcd, "Failed to get page for logger!");
		ret = -ENOMEM;
		goto err_stop_kthread;
	}
	phys_log_buf = virt_to_phys(log_buf);

	memset(&fc_log, 0, sizeof(fc_log));
	fc_log.as_in.cmd = MC_FC_NWD_TRACE;
	fc_log.as_in.param[0] = phys_log_buf;
	fc_log.as_in.param[1] = log_size;

	MCDRV_DBG(mcd, "fc_log virt=%p phys=%p ",
		  log_buf, (void *)phys_log_buf);
	mc_fastcall(&fc_log);
	MCDRV_DBG(mcd, "fc_log out ret=0x%08x", fc_log.as_out.ret);

	/* If the setup failed we must free the memory allocated */
	if (fc_log.as_out.ret) {
		MCDRV_DBG_ERROR(mcd, "MobiCore shared traces setup failed!");
		free_pages((unsigned long)log_buf, get_order(log_size));
		log_buf = NULL;
		ret = -EIO;
		goto err_stop_kthread;
	}

	set_task_state(log_thread, TASK_INTERRUPTIBLE);

	MCDRV_DBG(mcd, "fc_log Logger version %u\n", log_buf->version);
	return 0;

err_stop_kthread:
	kthread_stop(log_thread);
	log_thread = NULL;
err_free_line:
	kfree(log_line);
	log_line = NULL;
	return ret;
}

/*
 * Free kernel log components.
 * ATTN: We can't free the log buffer because it's also in use by MobiCore and
 * even if the module is unloaded MobiCore is still running.
 */
void mobicore_log_free(void)
{
	if (log_thread && !IS_ERR(log_thread)) {
		/* We don't really care what the thread returns for exit */
		kthread_stop(log_thread);
	}

	kfree(log_line);
}
Beispiel #28
0
void serialchar_callback(struct serial_info *serial)
{
	set_task_state(serial->owner, TASK_RUNNING);
	schedule();
}
Beispiel #29
0
int ACTIVE_TASK::request_exit() {
    set_task_state(PROCESS_UNINITIALIZED, "request_exit");
    return 0;
}