Example #1
0
/**
 * take one step in the execution state machine given a run-tree context
 *
 * a run_tree is expected to have a code tree as the first child, parameters as the second,
 * and optionally an error handling routine as the third child.
 *
 * @param[in] processes context of defined processes
 * @param[in] pointer to context pointer
 * @returns the next state that will be called for the context
 */
Error _p_step(Defs *defs, R **contextP) {
    R *context = *contextP;

    switch(context->state) {
    case noReductionErr:
    case Block:
    case Send:
        raise_error0("whoa, virtual states can't be executed!"); // shouldn't be calling step if Done or noErr or Block or Send
        break;
    case Pop:
        // if this was the successful reduction by an error handler
        // move the value to the 1st child
        if (context->err) {
            T *t = _t_detach_by_idx(context->run_tree,3);
            if (t) {
                _t_replace(context->run_tree,1,t);
                context->err = noReductionErr;
            }
        }

        // if this is top caller on the stack then we are completely done
        if (!context->caller) {
            context->state = Done;
            break;
        }
        else {
            // otherwise pop the context
            R *ctx = context;
            context = context->caller;  // set the new context

            if (!ctx->err) {
                // get results of the run_tree
                T *np = _t_detach_by_idx(ctx->run_tree,1);
                _t_replace(context->parent,context->idx,np); // replace the process call node with the result
                rt_cur_child(np) = RUN_TREE_EVALUATED;
                context->node_pointer = np;
                context->state = Eval;  // or possible ascend??
            }
            else context->state = ctx->err;
            // cleanup
            _t_free(ctx->run_tree);
            free(ctx);
            context->callee = 0;
            *contextP = context;
        }

        break;
    case Eval:
        {
            T *np = context->node_pointer;
            if (!np) {
                raise_error0("Whoa! Null node pointer");
            }
            Process s = _t_symbol(np);

            if (semeq(s,PARAM_REF)) {
                T *param = _t_get(context->run_tree,(int *)_t_surface(np));
                if (!param) {
                    raise_error0("request for non-existent param");
                }
                context->node_pointer = np = _t_rclone(param);
                _t_replace(context->parent, context->idx,np);
                s = _t_symbol(np);
            }
            // @todo what if the replaced parameter is itself a PARAM_REF tree ??

            // if this node is not a process, i.e. it's data, then we are done descending
            // and it will be the result so ascend
            if (!is_process(s)) {
                context->state = Ascend;
            }
            else {
                int c = _t_children(np);
                if (c == rt_cur_child(np) || semeq(s,QUOTE)) {
                    // if the current child == the child count this means
                    // all the children have been processed, so we can evaluate this process
                    // if the process is QUOTE that's a special case and we evaluate it
                    // immediately without descending.
                    if (!is_sys_process(s)) {
                        // if it's user defined process then we check the signature and then make
                        // a new run-tree run that process
                        Error e = __p_check_signature(defs,s,np);
                        if (e) context->state = e;
                        else {
                            T *run_tree = __p_make_run_tree(defs->processes,s,np);
                            context->state = Pushed;
                            *contextP = __p_make_context(run_tree,context);
                        }
                    }
                    else {
                        // if it's a sys process we can just reduce it in and then ascend
                        // or move to the error handling state
                        Error e = __p_reduce_sys_proc(context,s,np);
                        context->state = e ? e : Ascend;
                    }
                }
                else if(c) {
                    //descend and increment the current child we're working on!
                    context->state = Descend;
                }
                else {
                    raise_error0("whoa! brain fart!");
                }
            }
        }
        break;
    case Ascend:
        rt_cur_child(context->node_pointer) = RUN_TREE_EVALUATED;
        context->node_pointer = context->parent;
        context->parent = _t_parent(context->node_pointer);
        if (!context->parent || context->parent == context->run_tree) {
            context->idx = 1;
        }
        else context->idx = rt_cur_child(context->parent);
        if (context->node_pointer == context->run_tree)
            context->state = Pop;
        else
            context->state = Eval;
        break;
    case Descend:
        context->parent = context->node_pointer;
        context->idx = ++rt_cur_child(context->node_pointer);
        context->node_pointer = _t_child(context->node_pointer,context->idx);
        context->state = Eval;
        break;
    default:
        context->err = context->state;
        if (_t_children(context->run_tree) <= 2) {
            // no error handler so just return the error
            context->state = Pop;
        }
        else {
            // the first parameter to the error code is always a reduction error
            // which gets added on as the 4th child of the run tree when the
            // error happens.
            T *ps = _t_newr(context->run_tree,PARAMS);

            //@todo: fix this so we don't actually use an error value that
            // then has to be translated into a symbol, but rather so that we
            // can programatically calculate the symbol.
            Symbol se;
            switch(context->state) {
            case tooFewParamsReductionErr: se=TOO_FEW_PARAMS_ERR;break;
            case tooManyParamsReductionErr: se=TOO_MANY_PARAMS_ERR;break;
            case signatureMismatchReductionErr: se=SIGNATURE_MISMATCH_ERR;break;
            case notProcessReductionError: se=NOT_A_PROCESS_ERR;break;
            case notInSignalContextReductionError: se=NOT_IN_SIGNAL_CONTEXT_ERR;
            case divideByZeroReductionErr: se=ZERO_DIVIDE_ERR;break;
            case incompatibleTypeReductionErr: se=INCOMPATIBLE_TYPE_ERR;break;
            case raiseReductionErr:
                se = *(Symbol *)_t_surface(_t_child(context->node_pointer,1));
                break;
            default: raise_error("unknown reduction error: %d",context->state);
            }
            T *err = __t_new(ps,se,0,0,sizeof(rT));
            int *path = _t_get_path(context->node_pointer);
            _t_new(err,ERROR_LOCATION,path,sizeof(int)*(_t_path_depth(path)+1));
            free(path);

            // switch the node_pointer to the top of the error handling routine
            context->node_pointer = _t_child(context->run_tree,3);
            context->idx = 3;
            context->parent = context->run_tree;

            context->state = Eval;
        }
    }
    return context->state;
}
Example #2
0
void getProcStats (struct procStats *procPtr, int iter)

{
        struct procStatNode *nodePtr;
        DIR *d;
        struct dirent *ent;
        FILE *f;
        int ppid, pgrp, session, tty_nr, tpgid;
        unsigned flags;
        unsigned long minflt, majflt, cmajflt, utime, stime, cutime, cstime;
        long int priority, nice, num_thr, itrealv;
        unsigned long startTime;
        char fname[100];
 
        procPtr->procTotal = 0;
        procPtr->procRun = 0;
        procPtr->procSleep = 0;
        procPtr->procDSleep = 0;
        procPtr->procZombie = 0;
        procPtr->procTrace = 0;
        procPtr->procPaging = 0;
        procPtr->head = NULL;
 
        if (d = opendir ("/proc"))
        {
                while (ent = readdir(d))
                {
                        if (is_process(ent->d_name))
                        {
                                if (procPtr->head == NULL)
                                {
                                        procPtr->head = (struct procStatNode *) malloc (sizeof(struct procStatNode));;
                                        nodePtr = procPtr->head;
                                } else {
                                        nodePtr->nxtProc = (struct procStatNode *) malloc (sizeof(struct procStatNode));
                                        nodePtr = nodePtr->nxtProc;
                                }
                                nodePtr->nxtProc = NULL;
 
                                sprintf (fname, "/proc/%s/stat", ent->d_name);
                                if (f = fopen(fname, "r"))
                                {
				  int nodePtrPid = 0;
				  fscanf (f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld", &nodePtrPid, (char*)&(nodePtr->cmd), &(nodePtr->state), &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &majflt, &cmajflt, &utime, &stime, &cutime, &cstime, &priority, &nice, &num_thr, &itrealv, &startTime);
					nodePtr->pid = (uint64_t)nodePtrPid;
                                        fclose(f);
 
                                        // Calculate CPU utilization here
                                        // nodePtr->cpuUtil = (utime + stime)/100.0;
                                        nodePtr->cpuTime = (utime + stime);
                                        // Assumption startTime/100 = wall time in secs
                                        // getWallTime(&(nodePtr->wt), startTime);
                                        nodePtr->wallTime = startTime/100;
                                } else
                                        printf ("Error! %s file not found\n", fname);
 
                                sprintf (fname, "/proc/%s/statm", ent->d_name);
                                if (f = fopen(fname, "r"))
                                {
				  int nodePtrSizeTotal = 0;
				  int nodePtrSizeRes = 0;
				  int nodePtrPages = 0;
				  fscanf (f, "%d %d %d", &nodePtrSizeTotal, &nodePtrSizeRes, &nodePtrPages);
				  nodePtr->sizeTotal = (uint64_t)nodePtrSizeTotal;
				  nodePtr->sizeRes = (uint64_t)nodePtrSizeRes;
				  nodePtr->pages = (uint64_t)nodePtrPages;
				  fclose(f);
				  // To avoid divide by 0
				  if (nodePtr->sizeTotal > 0)
				    nodePtr->memUtil = (nodePtr->sizeRes/(1.0*nodePtr->sizeTotal))*100;
				  else
				    nodePtr->memUtil = 0.0;
                                } else
				  printf ("Error! %s file not found\n", fname);
 
                                // Process counters
                                procPtr->procTotal ++;
                                if (nodePtr->state == 'R')
                                        procPtr->procRun ++;
                                else if (nodePtr->state == 'S')
                                        procPtr->procSleep ++;
                                else if (nodePtr->state == 'D')
                                        procPtr->procDSleep ++;
                                else if (nodePtr->state == 'Z')
                                        procPtr->procZombie ++;
                                else if (nodePtr->state == 'T')
                                        procPtr->procTrace ++;
                                else if (nodePtr->state == 'W')
                                        procPtr->procPaging ++;
                        }
                }
        } else {
                printf ("Error! Can not open /proc\n");
        }
}
Example #3
0
/*
 * update_input: does varying amount of updating on the input line depending
 * upon the position of the cursor and the update flag.  If the cursor has
 * move toward one of the edge boundaries on the screen, update_cursor()
 * flips the input line to the next (previous) line of text. The update flag
 * may be: 
 *
 * NO_UPDATE - only do the above bounds checking. 
 *
 * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should
 * be. 
 *
 * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from
 * the cursor to the right edge of the screen is current (by redrawing it). 
 *
 * UPDATE_ALL - redraws the entire line 
 */
void update_input(int update)
{
    int old_start;
    static int co = 0, li = 0;
    char *ptr;
    int len, free_it = 1, cnt, ansi_count, max;

    char *prompt;

    cursor_to_input();

    if (current_screen->promptlist)
	prompt = current_screen->promptlist->prompt;
    else
	prompt = input_prompt;
    if (prompt) {
	if (update != NO_UPDATE) {
	    char *inp_ptr = NULL;
	    int args_used;

	    if (is_process(get_target_by_refnum(0))) {
		ptr = (char *) get_prompt_by_refnum(0);
		free_it = 0;
	    } else if (!get_int_var(DISPLAY_ANSI_VAR))
		ptr = expand_alias(stripansicodes(prompt), empty_str, &args_used, NULL);
	    else
		ptr = expand_alias(prompt, empty_str, &args_used, NULL);
	    if (*ptr && ((my_strnicmp(ptr, "Password:"******"Operator Password:"******"Server Password:", 16) == 0)))
		term_echo(0);
	    else
		term_echo(1);
	    len = strlen(ptr);
	    if (strncmp(ptr, current_screen->input_buffer, len) || !len) {
		malloc_strcpy(&inp_ptr, INPUT_BUFFER + MIN_POS);
		strmcpy(INPUT_BUFFER, ptr, INPUT_BUFFER_SIZE);
		THIS_POS += (len - MIN_POS);
		MIN_POS = strlen(ptr);
		ADD_TO_INPUT(inp_ptr);
		new_free(&inp_ptr);
		update = UPDATE_ALL;
	    }

	    if (free_it)
		new_free(&ptr);
	}
    } else
	term_echo(1);

    if ((li != term_rows) || (co != term_cols)) {
	/* resized? Keep it simple and reset everything */
	input_line = term_rows - 1;
	zone = term_cols - (WIDTH * 2) + 4;
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	cursor = current_screen->buffer_min_pos;
	current_screen->buffer_pos = current_screen->buffer_min_pos;
	str_start = 0;
	li = term_rows;
	co = term_cols;
    }
    old_start = str_start;
    ansi_count = count_ansi(current_screen->input_buffer, zone);
    if (old_ansi != ansi_count || current_screen->buffer_pos - ansi_count > zone) {
	lower_mark = WIDTH;
	upper_mark = term_cols - WIDTH;
	str_start = 0;
    }
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);

    while ((current_screen->buffer_pos - ansi_count < lower_mark) && lower_mark > WIDTH) {
	upper_mark = lower_mark - ansi_count;
	lower_mark -= (zone + ansi_count);
	str_start -= (zone + ansi_count);
	if (str_start < zone) {
	    str_start = 0;
	    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
	    lower_mark -= ansi_count;
	    upper_mark -= ansi_count;
	}
    }
    while (current_screen->buffer_pos - ansi_count >= upper_mark) {
	lower_mark = upper_mark + ansi_count;
	upper_mark += zone + ansi_count;
	str_start += zone + ansi_count;
	if (ansi_count)
	    ansi_count = 0;
    }

    /* we need to count ansi characters again, this time in the part of the string we are gonna display in a few moments */
    ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone);
    old_ansi = count_ansi(current_screen->input_buffer, zone);
    /* we need to substract number of ansi characters from cursor position since those are not visible, otherwise we'd display cursor
     * in wrong place */
    cursor = current_screen->buffer_pos - str_start - ansi_count;
    if ((old_start != str_start) || (update == UPDATE_ALL)) {
	term_move_cursor(0, input_line);
	if ((str_start == 0) && (MIN_POS > 0)) {
	    int echo;

	    echo = term_echo(1);
	    if (MIN_POS > (term_cols - WIDTH))
		len = term_cols - WIDTH - 1 /* + ansi_count */ ;
	    else
		len = MIN_POS;
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), len);
	    term_echo(echo);
	    cnt += /* term_puts */ safe_puts(&(current_screen->input_buffer[
									       str_start + len]), term_cols - len + ansi_count);
	} else
	    cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), term_cols);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_FROM_CURSOR) {
	term_move_cursor(cursor, input_line);
	cnt = cursor;
	max = term_cols - (current_screen->buffer_pos - str_start) + ansi_count;
	if ((len = strlen(&(THIS_CHAR))) > max)
	    len = max;
	cnt += /* term_puts */ safe_puts(&(THIS_CHAR), len);
	term_clear_to_eol();
	term_move_cursor(cursor, input_line);
    } else if (update == UPDATE_JUST_CURSOR)
	term_move_cursor(cursor, input_line);
    term_flush();
}