コード例 #1
0
ファイル: AudioMixer.c プロジェクト: FREEWING-JP/blueberryMSX
void mixerStopLog(Mixer* mixer) 
{
    WavHeader header;
    int fileSize;

    if (mixer->logging == 0) {
        return;
    }

    mixer->logging = 0;
    
    fileSize = ftell(mixer->file);
    
    header.riff                     = str2ul("RIFF");
    header.fileSize                 = fileSize - 8;
    header.wave                     = str2ul("WAVE");
    header.wavHeader.fmt            = str2ul("fmt ");
    header.wavHeader.chunkSize      = 16;
    header.wavHeader.formatType     = 1;
    header.wavHeader.channels       = (mixer->stereo ? 2 : 1);
    header.wavHeader.samplesPerSec  = mixer->rate;
    header.wavHeader.avgBytesPerSec = (mixer->stereo ? 2 : 1) * mixer->rate * BITSPERSAMPLE / 8;
    header.wavHeader.blockAlign     = (mixer->stereo ? 2 : 1) * BITSPERSAMPLE / 8;
    header.wavHeader.bitsPerSample  = BITSPERSAMPLE;
    header.data                     = str2ul("data");
    header.dataSize                 = fileSize - sizeof(WavHeader);

    fseek(mixer->file, 0, SEEK_SET);
    fwrite(&header, 1, sizeof(WavHeader), mixer->file);
    fclose(mixer->file);
}
コード例 #2
0
/**
 * 作用:对nand标强制擦除
 *
 * 参数:
 * @blockid          ---block块的字符串
 *
 *
 * 描述:nand强制擦除功能,当如果有软件坏块时也可以用此函数来强制擦除
 */
void bsp_nand_erase_force(char *blockid)
{
    int ret = NANDC_ERROR;
    unsigned int id;

    char *blk_id = bsp_nand_argument_check(blockid);

    /* string to int  */
    ret= str2ul(blk_id, &id);
    if(ret)
    {
        NAND_TRACE(("[%s]ERROR: string to integer failed, ret = 0x%x.\n", __FUNCTION__, ret));
        goto ERRO;
    }

    /*直接擦除*/
    ret = nand_erase(id);
    if(ret)
    {
        NAND_TRACE(("[%s]ERROR: nand check bad failed, ret = 0x%x.\n", __FUNCTION__, ret));
        goto ERRO;
    }
    else
    {
        NAND_TRACE(("SUCCESS: erase block %x forcely.\n", id));
    }

    return;

ERRO:
    return;
}
コード例 #3
0
ファイル: tests.c プロジェクト: plasticlogic/eptest
int test_stripes(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	struct plep *plep;
	int stat;
	unsigned long width;

	assert(pldraw != NULL);

	if (opts_n > 0) {

		if (str2ul(&width, opts[0]) < 0) {
			LOG("Invalid stripes width: %s", opts[0]);
			return -1;
		}
	} else {
		width = 1;
	}

	plep = pldraw_get_plep(pldraw);

	draw_stripes(pldraw, g_black, width);
	stat = plep_update_screen(plep, g_quick_wf);
	if (stat)
		return stat;

	draw_stripes(pldraw, g_white, width);
	stat = plep_update_screen(plep, g_quick_wf);
	if (stat)
		return stat;

	return 0;
}
コード例 #4
0
ファイル: proc_stat.c プロジェクト: firehol/netdata
static int read_schedstat(char *schedstat_filename, struct per_core_cpuidle_chart **cpuidle_charts_address, size_t *schedstat_cores_found) {
    static size_t cpuidle_charts_len = 0;
    static procfile *ff = NULL;
    struct per_core_cpuidle_chart *cpuidle_charts = *cpuidle_charts_address;
    size_t cores_found = 0;

    if(unlikely(!ff)) {
        ff = procfile_open(schedstat_filename, " \t:", PROCFILE_FLAG_DEFAULT);
        if(unlikely(!ff)) return 1;
    }

    ff = procfile_readall(ff);
    if(unlikely(!ff)) return 1;

    size_t lines = procfile_lines(ff), l;
    size_t words;

    for(l = 0; l < lines ;l++) {
        char *row_key = procfile_lineword(ff, l, 0);

        // faster strncmp(row_key, "cpu", 3) == 0
        if(likely(row_key[0] == 'c' && row_key[1] == 'p' && row_key[2] == 'u')) {
            words = procfile_linewords(ff, l);
            if(unlikely(words < 10)) {
                error("Cannot read /proc/schedstat cpu line. Expected 9 params, read %zu.", words);
                return 1;
            }
            cores_found++;

            size_t core = str2ul(&row_key[3]);
            if(unlikely(core >= cores_found)) {
                error("Core %zu found but no more than %zu cores were expected.", core, cores_found);
                return 1;
            }

            if(unlikely(cpuidle_charts_len < cores_found)) {
                cpuidle_charts = reallocz(cpuidle_charts, sizeof(struct per_core_cpuidle_chart) * cores_found);
                *cpuidle_charts_address = cpuidle_charts;
                memset(cpuidle_charts + cpuidle_charts_len, 0, sizeof(struct per_core_cpuidle_chart) * (cores_found - cpuidle_charts_len));
                cpuidle_charts_len = cores_found;
            }

            cpuidle_charts[core].active_time = str2ull(procfile_lineword(ff, l, 7)) / 1000;
        }
    }

    *schedstat_cores_found = cores_found;
    return 0;
}
コード例 #5
0
/**
 * 作用:对nand标坏块
 *
 * 参数:
 * @blockid          ---block块的字符串
 *
 *
 * 描述:nand标坏块
 */
void bsp_nand_markbad(char *blockid)
{
    int ret = NANDC_ERROR;
    unsigned int id, bad_flag;
    char *blk_id = bsp_nand_argument_check(blockid);

    /* string to int  */
    ret= str2ul(blk_id, &id);
    if(ret)
    {
        NAND_TRACE(("ERROR: string to integer failed, ret = 0x%x.\n", ret));
        goto EXIT;
    }

    /* check block bad. if good, mark bad; else return */
    ret = nand_isbad(id, &bad_flag);
    if(ret)
    {
        NAND_TRACE(("[%s]ERROR: nand check bad failed, ret = 0x%x.\n", __FUNCTION__, ret));
        goto EXIT;
    }

    if(NANDC_GOOD_BLOCK == bad_flag)
    {
        ret = nand_bad(id);
        if(ret)
        {
            NAND_TRACE(("[%s]ERROR: nand mark bad failed, ret = 0x%x.\n", __FUNCTION__, ret));
            goto EXIT;
        }
    }
    else
    {
        NAND_TRACE(("[%s]WARNING: block 0x%x is already bad.\n", __FUNCTION__));
        goto EXIT;
    }

    return;

EXIT:
    return;
}
コード例 #6
0
ファイル: web_api_old.c プロジェクト: cppmx/netdata
int web_client_api_old_data_request(RRDHOST *host, struct web_client *w, char *url, int datasource_type) {
    if(!url || !*url) {
        buffer_flush(w->response.data);
        buffer_sprintf(w->response.data, "Incomplete request.");
        return 400;
    }

    RRDSET *st = NULL;

    char *args = strchr(url, '?');
    if(args) {
        *args='\0';
        args = &args[1];
    }

    // get the name of the data to show
    char *tok = mystrsep(&url, "/");
    if(!tok) tok = "";

    // do we have such a data set?
    if(*tok) {
        debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
        st = rrdset_find_byname(host, tok);
        if(!st) st = rrdset_find(host, tok);
    }

    if(!st) {
        // we don't have it
        // try to send a file with that name
        buffer_flush(w->response.data);
        return(mysendfile(w, tok));
    }

    // we have it
    debug(D_WEB_CLIENT, "%llu: Found RRD data with name '%s'.", w->id, tok);

    // how many entries does the client want?
    int lines = (int)st->entries;
    int group_count = 1;
    time_t after = 0, before = 0;
    int group_method = GROUP_AVERAGE;
    int nonzero = 0;

    if(url) {
        // parse the lines required
        tok = mystrsep(&url, "/");
        if(tok) lines = str2i(tok);
        if(lines < 1) lines = 1;
    }
    if(url) {
        // parse the group count required
        tok = mystrsep(&url, "/");
        if(tok && *tok) group_count = str2i(tok);
        if(group_count < 1) group_count = 1;
        //if(group_count > save_history / 20) group_count = save_history / 20;
    }
    if(url) {
        // parse the grouping method required
        tok = mystrsep(&url, "/");
        if(tok && *tok) {
            if(strcmp(tok, "max") == 0) group_method = GROUP_MAX;
            else if(strcmp(tok, "average") == 0) group_method = GROUP_AVERAGE;
            else if(strcmp(tok, "sum") == 0) group_method = GROUP_SUM;
            else debug(D_WEB_CLIENT, "%llu: Unknown group method '%s'", w->id, tok);
        }
    }
    if(url) {
        // parse after time
        tok = mystrsep(&url, "/");
        if(tok && *tok) after = str2ul(tok);
        if(after < 0) after = 0;
    }
    if(url) {
        // parse before time
        tok = mystrsep(&url, "/");
        if(tok && *tok) before = str2ul(tok);
        if(before < 0) before = 0;
    }
    if(url) {
        // parse nonzero
        tok = mystrsep(&url, "/");
        if(tok && *tok && strcmp(tok, "nonzero") == 0) nonzero = 1;
    }

    w->response.data->contenttype = CT_APPLICATION_JSON;
    buffer_flush(w->response.data);

    char *google_version = "0.6";
    char *google_reqId = "0";
    char *google_sig = "0";
    char *google_out = "json";
    char *google_responseHandler = "google.visualization.Query.setResponse";
    char *google_outFileName = NULL;
    time_t last_timestamp_in_data = 0;
    if(datasource_type == DATASOURCE_DATATABLE_JSON || datasource_type == DATASOURCE_DATATABLE_JSONP) {

        w->response.data->contenttype = CT_APPLICATION_X_JAVASCRIPT;

        while(args) {
            tok = mystrsep(&args, "&");
            if(tok && *tok) {
                char *name = mystrsep(&tok, "=");
                if(name && *name && strcmp(name, "tqx") == 0) {
                    char *key = mystrsep(&tok, ":");
                    char *value = mystrsep(&tok, ";");
                    if(key && value && *key && *value) {
                        if(strcmp(key, "version") == 0)
                            google_version = value;

                        else if(strcmp(key, "reqId") == 0)
                            google_reqId = value;

                        else if(strcmp(key, "sig") == 0)
                            google_sig = value;

                        else if(strcmp(key, "out") == 0)
                            google_out = value;

                        else if(strcmp(key, "responseHandler") == 0)
                            google_responseHandler = value;

                        else if(strcmp(key, "outFileName") == 0)
                            google_outFileName = value;
                    }
                }
            }
        }

        debug(D_WEB_CLIENT_ACCESS, "%llu: GOOGLE JSONP: version = '%s', reqId = '%s', sig = '%s', out = '%s', responseHandler = '%s', outFileName = '%s'",
                w->id, google_version, google_reqId, google_sig, google_out, google_responseHandler, google_outFileName
        );

        if(datasource_type == DATASOURCE_DATATABLE_JSONP) {
            last_timestamp_in_data = strtoul(google_sig, NULL, 0);

            // check the client wants json
            if(strcmp(google_out, "json") != 0) {
                buffer_sprintf(w->response.data,
                        "%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'invalid_query',message:'output format is not supported',detailed_message:'the format %s requested is not supported by netdata.'}]});",
                        google_responseHandler, google_version, google_reqId, google_out);
                return 200;
            }
        }
    }

    if(datasource_type == DATASOURCE_DATATABLE_JSONP) {
        buffer_sprintf(w->response.data,
                "%s({version:'%s',reqId:'%s',status:'ok',sig:'%ld',table:",
                google_responseHandler, google_version, google_reqId, st->last_updated.tv_sec);
    }

    debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %ld after, %ld before).",
            w->id, st->name, st->id, lines, group_count, group_method, after, before);

    time_t timestamp_in_data = rrdset2json_api_old(datasource_type, st, w->response.data, lines, group_count
                                                   , group_method, (unsigned long) after, (unsigned long) before
                                                   , nonzero);

    if(datasource_type == DATASOURCE_DATATABLE_JSONP) {
        if(timestamp_in_data > last_timestamp_in_data)
            buffer_strcat(w->response.data, "});");

        else {
            // the client already has the latest data
            buffer_flush(w->response.data);
            buffer_sprintf(w->response.data,
                    "%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});",
                    google_responseHandler, google_version, google_reqId);
        }
    }

    return 200;
}
コード例 #7
0
ファイル: epview.c プロジェクト: plasticlogic/epview
int main(int argc, char **argv)
{
	//static const char OPTIONS[] = "hvlpsjPr:g:f::A:Ww:m:d:e:b:T:t:o:a:c:O:i:";
	static const char OPTIONS[] = "A:a:b:c:D:d:E:e:F:f:g:hi:jlm:no:O:Ppr:sT:t:vWw:x:y:";
	__sighandler_t sigint_original;
	char * const *file_names = NULL;
	size_t n_files = 0;
	int dither_mode = 0;
	int keep_power_on = 0;
	const char *waveform_id_str = "2";
	int waveform_id = 2;
	int do_enumerate_waveforms = 0;
	int do_log_info = 0;
	int do_wait_power_off = 0;
	int do_synchro = 0;
	int do_infinite_loop = 0;
	int cfa = -1;
	int display_enable = 0;
	int do_fill = 0;
	int fill_color = 0xFF;
	int do_auto_rotate = 0;
	int rotation_angle = -1;
	int do_partial_update = 0;
	int use_manual_temperature = 0;
	int manual_temperature = 25;
	unsigned long pause_ms = 2000;
	const char *mode = NULL;
	const char *fbdev = NULL;
	const char *epdev = NULL;
	const char *background = NULL;
	struct plep_point offset = { 0, 0 };
	enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE;
	enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE;
	struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } };
	const char *doc_type = NULL;
	const char *conf_file = NULL;
	struct plep *plep;
	struct pldraw *pldraw;
	int onoff = -1;
	int c;
	int ret;
	int use_alternative_vsource = 0;
	while ((c = getopt(argc, argv, OPTIONS)) != -1) {
		switch (c) {
		case 'A':
			if (!strcmp(optarg, "l")) {
			use_alternative_vsource = 1;
			}else if (!strcmp(optarg, "h")) {
			use_alternative_vsource = 2;
			}else if (!strcmp(optarg, "lh")) {
			use_alternative_vsource = 3;
			}else if (!strcmp(optarg, "hl")) {
			use_alternative_vsource = 3;
			}else{
				LOG("invalid alternative VSOURCE selection");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;
		case 'h':
			print_usage();
			exit(EXIT_SUCCESS);
			break;

		case 'v':
			printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION,
			       DESCRIPTION, COPYRIGHT, LICENSE);
			exit(EXIT_SUCCESS);
			break;

		case 'l':
			do_log_info = 1;
			break;
		case 'P':
			do_partial_update = 1;
			break;

		case 'p':
			do_wait_power_off = 1;
			break;

		case 's':
			do_synchro = 1;
			break;

		case 'j':
			do_infinite_loop = 1;
			break;

		case 'r':
			if (!strcmp(optarg, "auto")) {
				do_auto_rotate = 1;
			} else {
				unsigned long raw_angle;

				if (str2ul(optarg, &raw_angle) < 0) {
					LOG("failed to parse rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				if ((raw_angle > 270) || (raw_angle % 90)) {
					LOG("invalid rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				rotation_angle = raw_angle;
			}
			break;

		case 'g':
			if (str2ul(optarg, &pause_ms) < 0) {
				LOG("failed to parse pause duration");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'f':
			if (optarg == NULL) {
				cfa = PLDRAW_CFA_GR_BW;
			} else {
				cfa = pldraw_get_cfa_id(optarg);

				if (cfa < 0) {
					LOG("Invalid CFA identifier: %s",
					    optarg);
					print_usage();
					exit(EXIT_FAILURE);
				}
			}
			break;
		
		case 'F':{
			char* str = optarg;
			if (optarg == NULL) {
				// set color to white (0xFF)
				do_fill = 1;
			} else {
				do_fill = 1;
				if(!strncmp(optarg, "0x", 2) || !strncmp(optarg, "0X", 2)){
					fill_color = strtoul(optarg, NULL, 16);
				}else{
					fill_color = atoi(optarg);
				}
			}
			break;
		}
		case 'T':
			manual_temperature = atoi(optarg);
			use_manual_temperature = 1;
			break;
		case 'W':
			do_enumerate_waveforms = 1;
			break;
		case 'i':
			waveform_id_str = NULL;
			waveform_id = atoi(optarg);
			break;
		case 'w':
			waveform_id_str = optarg;
			break;

		case 'm':
			mode = optarg;
			break;

		case 'd':
			fbdev = optarg;
			break;

		case 'e':
			epdev = optarg;
			break;

		case 'b':
			background = optarg;
			break;

		case 't':
			doc_type = optarg;
			break;

		case 'o':
			if (parse_offset(&offset, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'a':
			if (parse_alignment(&align_h, &align_v, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'c':
			if (parse_crop(&crop, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;
		case 'O':
			conf_file = optarg;
			if (access(conf_file, F_OK)) {
				LOG_ERRNO("Configuration file");
				exit(EXIT_FAILURE);
			}
			break;
		case 'x':{
			onoff = atoi(optarg);
			break;
		}	
		case 'E':{
			//Enable Display N
			display_enable = atoi(optarg);
			if(display_enable > 3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		}
		case 'D':{
			//disable Display N
			display_enable -= atoi(optarg);
			if(display_enable < -3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		}
		case 'y':
			dither_mode = atoi(optarg);
			LOG("dither_mode %i", dither_mode);
			if(display_enable < 0 || display_enable > 3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		case 'n':{
			keep_power_on = 1;
			break;
		}	
		case '?':
		default:
			LOG("Invalid arguments");
			print_usage();
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (optind < argc) {
		file_names = &argv[optind];
		n_files = argc - optind;
	}

	LOG("%s v%s", APP_NAME, VERSION);

	plep = plep_init(epdev, mode, conf_file);

	if (plep == NULL) {
		LOG("failed to initialise ePDC");
		goto error_plep;
	}

	pldraw = pldraw_init(fbdev, conf_file);

	if (pldraw == NULL) {
		LOG("failed to initialise pldraw");
		goto error_pldraw;
	}

	pldraw_set_plep(pldraw, plep);
	
	if(waveform_id_str){
		waveform_id = plep_get_wfid(plep, waveform_id_str);

		if (waveform_id < 0) {
			LOG("Invalid waveform path: %s", waveform_id_str);
			goto error_pldraw;
		}
	}
	
	if (cfa >= 0)
		pldraw_set_cfa(pldraw, cfa);
	else
		cfa = pldraw_get_cfa(pldraw);

	if (cfa != PLDRAW_CFA_NONE)
		LOG("CFA: %s", pldraw_cfa_name[cfa]);

	if (rotation_angle < 0)
		rotation_angle = pldraw_get_rotation(pldraw);

	if (rotation_angle)
		LOG("rotation: %d", rotation_angle);

	if (do_log_info)
		pldraw_log_info(pldraw);

	sigint_original = signal(SIGINT, sigint_abort);

	if(onoff != -1){
		LOG("POWER ONOFF:%i\n", onoff);
		if(onoff)
			plep_powerup(plep);
		else
			plep_powerdown(plep);
		exit(EXIT_SUCCESS);
	}
	if(display_enable != 0){
		//LOG("DISPLAY ENABLE:%i\n", display_enable);
		if(display_enable>0){
			plep_enable_display(plep, display_enable);
		}else{
			plep_disable_display(plep, display_enable);
		}
		exit(EXIT_SUCCESS);
	}
	if (do_enumerate_waveforms) {
		ret = enumerate_waveforms(plep);
	} else {
		struct epdoc_opt opt;

		plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro);

		if (do_wait_power_off)
			plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1);

		if(do_partial_update){
			plep_set_opt(plep, PLEP_PARTIAL, 1);
		}
		
		if(use_manual_temperature){
			plep_set_opt(plep, PLEP_TEMPERATURE, 1);
			plep_set_hw_opt(plep, PLEP_TEMPERATURE, manual_temperature);
		}else{
			plep_set_opt(plep, PLEP_TEMPERATURE_AUTO, 1);
		}
		opt.dither_mode = dither_mode;
		opt.keep_power_on = keep_power_on;
		opt.do_auto_rotate = do_auto_rotate;
		opt.rotation_angle = rotation_angle;
		opt.wfid = waveform_id;
		opt.offset.x = offset.x;
		opt.offset.y = offset.y;
		opt.align_h = align_h;
		opt.align_v = align_v;
		memcpy(&opt.crop, &crop, sizeof opt.crop);
		opt.doc_type = doc_type;
		opt.use_alternative_vsource = use_alternative_vsource;
		
		if(do_fill){
			pldraw_fill_rect(pldraw, pldraw_get_grey(pldraw, fill_color), &crop);
			plep_update_screen(plep, opt.wfid);
		}else{
		
			ret = show_contents(pldraw, file_names, n_files, &opt,
				    pause_ms, do_infinite_loop, background);
		}
	}

	signal(SIGINT, sigint_original);
	pldraw_free(pldraw);
	plep_free(plep);

	exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS);

error_pldraw:
	plep_free(plep);
error_plep:
	exit(EXIT_FAILURE);
}
コード例 #8
0
ファイル: tests.c プロジェクト: plasticlogic/eptest
int test_check(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	const struct plep_point origin = { .x = 0, .y = 0 };
	struct plep *plep = pldraw_get_plep(pldraw);
	pldraw_color_t draw_col;
	unsigned long dim;
	int wfid;
	int n;
	int m;

	assert(pldraw != NULL);
	assert(g_initialised);

	if (opts_n > 0) {
		if (str2ul(&dim, opts[0]) < 0) {
			LOG("Invalid square dimension: %s", opts[0]);
			return -1;
		}
	} else {
		dim = pldraw_get_xres(pldraw) / 40;
	}

	if (opts_n > 1) {
		if (pldraw_str2col(pldraw, &draw_col, opts[1]))
			return -1;
	} else {
		draw_col = g_black;
	}

	if (opts_n > 2) {
		const char *wfid_str = opts[2];

		wfid = plep_get_wfid(plep, wfid_str);

		if (wfid < 0) {
			LOG("Invalid waveform: %s", wfid_str);
			return -1;
		}

		LOG("waveform name: %s", wfid_str);
	} else {
		wfid = g_clear_wf;
	}

	if (dim == 0)
		return -1;

	n = 1 + ((pldraw_get_xres(pldraw) - 1) / dim);
	m = 1 + ((pldraw_get_yres(pldraw) - 1) / dim);

	draw_checkerboard(pldraw, &origin, dim, 0, n, m, draw_col);

	return plep_update_screen(plep, wfid);
}

int test_fill(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	struct plep *plep;
	pldraw_color_t col;
	int wfid;

	assert(pldraw != NULL);
	assert(g_initialised);

	plep = pldraw_get_plep(pldraw);

	if (opts_n < 1)
		col = g_white;
	else if (pldraw_str2col(pldraw, &col, opts[0]))
		return -1;

	if (opts_n > 1) {
		const char *wfid_str = opts[1];

		wfid = plep_get_wfid(plep, wfid_str);

		if (wfid < 0) {
			LOG("Invalid waveform: %s", wfid_str);
			return -1;
		}

		LOG("waveform name: %s", wfid_str);
	} else {
		wfid = g_clear_wf;
	}

	pldraw_fill_screen(pldraw, col);

	return plep_update_screen(plep, wfid);
}

int test_sweep(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	struct plep *plep;
	unsigned long sleep_us = 10000;
	int i;

	assert(pldraw != NULL);

	plep = pldraw_get_plep(pldraw);

	if (opts_n >= 1) {
		unsigned long sleep_ms;

		if (str2ul(&sleep_ms, opts[0]) < 0) {
			LOG("Invalid sleep value: %s", opts[0]);
			return -1;
		}

		sleep_us = sleep_ms * 1000;
	}

	for (i = 0; i < 0xFF; ++i) {
		const pldraw_color_t col = pldraw_get_color(pldraw, i, i, i);

		pldraw_fill_screen(pldraw, col);
		plep_update_screen(plep, g_clear_wf);
		usleep(sleep_us);
	}

	return 0;
}

int test_none(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	pldraw = NULL;

	LOG("That's all folks!");

	return 0;
}
コード例 #9
0
ファイル: tests.c プロジェクト: plasticlogic/eptest
int test_radar(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	enum quadrant_id {
		EDGE_TOP,
		EDGE_RIGHT,
		EDGE_BOTTOM,
		EDGE_LEFT,
	};
	static const int PITCH = 10;
	const pldraw_color_t col_rgbw[] = {
		g_red, g_green, g_blue, g_white };
	const int col_rgbw_n = ARRAY_SIZE(col_rgbw);
	struct plep *plep;
	__sighandler_t prev_sigint;
	struct plep_rect rect;
	struct plep_rect ep_area;
	struct plep_rect line;
	enum quadrant_id quad;
	pldraw_color_t draw_col = g_black;
	pldraw_color_t col;
	int col_rgbw_index = -1;
	unsigned long sleep_us;
	int wfid;
	int xres;
	int yres;
	int width;
	int height;
	int ret = 0;

	assert(pldraw != NULL);
	assert(g_initialised);

	if (opts_n > 0) {
		unsigned long sleep_ms;

		if (str2ul(&sleep_ms, opts[0]) < 0) {
			LOG("Invalid sleep value: %s", opts[0]);
			return -1;
		}

		sleep_us = sleep_ms * 1000;
	} else {
		sleep_us = 10000;
	}

	if (opts_n > 1) {
		const char *col_str = opts[1];

		if (!strcmp(col_str, "rgbw")) {
			col_rgbw_index = 0;
		} else if (pldraw_str2col(pldraw, &draw_col, col_str) < 0) {
			return -1;
		}
	}

	if (!pldraw_colcmp(pldraw, col, g_black)
	    && (pldraw_get_cfa(pldraw) == PLDRAW_CFA_NONE)) {
		wfid = g_clear_wf;
	} else {
		wfid = g_quick_wf;
	}

	plep = pldraw_get_plep(pldraw);

	xres = pldraw_get_xres(pldraw);
	yres = pldraw_get_yres(pldraw);
	width = ((xres / PITCH) - 2) * PITCH;
	height = ((yres / PITCH) - 2) * PITCH;

	rect.a.x = (xres - width) / 2;
	rect.a.y = (yres - height) / 2;
	rect.b.x = rect.a.x + width;
	rect.b.y = rect.a.y + height;

	LOG("rectangle: (%i, %i, %i, %i)",
	    rect.a.x, rect.a.y, rect.b.x, rect.b.y);

	draw_border(pldraw, draw_col, &rect);

	if (plep_update(plep, &rect, g_clear_wf) < 0)
		ret = -1;

	plep_set_opt(plep, PLEP_SYNC_UPDATE, 0);
	plep_set_opt(plep, PLEP_PARTIAL, 1);

	++rect.a.x;
	++rect.a.y;
	--rect.b.x;
	--rect.b.y;
	memcpy(&ep_area, &rect, sizeof ep_area);
	--rect.b.x;
	--rect.b.y;

	line.a.x = (rect.a.x + rect.b.x) / 2;
	line.a.y = (rect.a.y + rect.b.y) / 2;
	line.b.x = rect.a.x;
	line.b.y = rect.a.y;

	if (col_rgbw_index < 0)
		col = draw_col;
	else
		col = col_rgbw[0];

	prev_sigint = signal(SIGINT, sigint_stop);
	quad = EDGE_TOP;
	g_run = 1;
	LOG("Press Ctrl-C to stop");

	while (!ret && g_run) {
		pldraw_draw_line(pldraw, col, &line);

		if (plep_update(plep, &ep_area, wfid) < 0) {
			ret = -1;
			break;
		}

		switch (quad)
		{
		case EDGE_TOP:
			line.b.x += PITCH;
			if (line.b.x >= rect.b.x) {
				line.b.x = rect.b.x;
				quad = EDGE_RIGHT;
			}
			break;
		case EDGE_RIGHT:
			line.b.y += PITCH;
			if (line.b.y >= rect.b.y) {
				line.b.y = rect.b.y;
				quad = EDGE_BOTTOM;
			}
			break;
		case EDGE_BOTTOM:
			line.b.x -= PITCH;
			if (line.b.x <= rect.a.x) {
				line.b.x = rect.a.x;
				quad = EDGE_LEFT;
			}
			break;
		case EDGE_LEFT:
			line.b.y -= PITCH;
			if (line.b.y <= rect.a.y) {
				line.b.y = rect.a.y;
				quad = EDGE_TOP;

				if (col_rgbw_index < 0) {
					col = pldraw_colcmp(
						pldraw, col, draw_col)
						? draw_col : g_white;
				} else {
					if (++col_rgbw_index == col_rgbw_n)
						col_rgbw_index = 0;
					col = col_rgbw[col_rgbw_index];
				}
			}
			break;
		}

		usleep(sleep_us);
	}

	signal(SIGINT, prev_sigint);

	plep_set_opt(plep, PLEP_PARTIAL, 0);

	return ret;
}
コード例 #10
0
ファイル: tests.c プロジェクト: plasticlogic/eptest
int test_frame(struct pldraw *pldraw, char * const *opts, int opts_n)
{
	struct plep *plep;
	struct plep_rect rect;
	struct plep_rect outer;
	struct plep_rect inner;
	unsigned long grid = 12;
	pldraw_color_t draw_col = g_black;
	unsigned long gap = 1;
	unsigned long max_gap;
	float x_grid, y_grid;
	int xres, yres;
	int wfid = g_clear_wf;

	assert(pldraw != NULL);
	assert(g_initialised);

	plep = pldraw_get_plep(pldraw);
	xres = pldraw_get_xres(pldraw);
	yres = pldraw_get_yres(pldraw);

	if (opts_n > 0) {
		if (str2ul(&grid, opts[0]) < 0) {
			LOG("Invalid grid value: %s", opts[0]);
			return -1;
		}

		if (grid < 4) {
			LOG("Grid value is too small, minimum is 4");
			return -1;
		}
	}

	if (opts_n > 1) {
		if (pldraw_str2col(pldraw, &draw_col, opts[1]))
			return -1;
	}

	if (opts_n > 2) {
		if (str2ul(&gap, opts[2]) < 0) {
			LOG("Invalid gap value: %s", opts[2]);
			return -1;
		}
	}

	if (opts_n > 3) {
		wfid = plep_get_wfid(plep, opts[3]);

		if (wfid < 0) {
			LOG("Invalid waveform: %s", opts[3]);
			return -1;
		}
	}

	x_grid = xres / (float)grid;
	y_grid = yres / (float)grid;

	LOG("grid: %lu, x: %.3f, y: %.3f", grid, x_grid, y_grid);

	max_gap = (y_grid * ((grid / 2) - 2)) - 1;

	if (gap > max_gap) {
		LOG("Gap is too big, maximum is %lu", max_gap);
		return -1;
	}

	outer.a.x = x_grid;
	outer.a.y = y_grid;
	outer.b.x = x_grid * (grid - 1);
	outer.b.y = y_grid * (grid - 1);

	inner.a.x = x_grid * 2;
	inner.a.y = y_grid * 2;
	inner.b.x = x_grid * (grid - 2);
	inner.b.y = y_grid * (grid - 2);

	rect.a.x = outer.a.x;
	rect.a.y = outer.a.y;
	rect.b.x = outer.b.x;
	rect.b.y = inner.a.y;
	pldraw_fill_rect(pldraw, draw_col, &rect);

	if (plep_update(plep, &rect, wfid) < 0)
		return -1;

	rect.a.y = inner.b.y;
	rect.b.y = outer.b.y;
	pldraw_fill_rect(pldraw, draw_col, &rect);

	if (plep_update(plep, &rect, wfid) < 0)
		return -1;

	rect.a.x = outer.a.x;
	rect.a.y = inner.a.y + gap;
	rect.b.x = inner.a.x;
	rect.b.y = inner.b.y - gap;
	pldraw_fill_rect(pldraw, draw_col, &rect);

	if (plep_update(plep, &rect, wfid) < 0)
		return -1;

	rect.a.x = inner.b.x;
	rect.b.x = outer.b.x;
	pldraw_fill_rect(pldraw, draw_col, &rect);

	if (plep_update(plep, &rect, wfid) < 0)
		return -1;

	return 0;
}
コード例 #11
0
// read the whole mountinfo into a linked list
struct mountinfo *mountinfo_read(int do_statvfs) {
    char filename[FILENAME_MAX + 1];
    snprintfz(filename, FILENAME_MAX, "%s/proc/self/mountinfo", netdata_configured_host_prefix);
    procfile *ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
    if(unlikely(!ff)) {
        snprintfz(filename, FILENAME_MAX, "%s/proc/1/mountinfo", netdata_configured_host_prefix);
        ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
        if(unlikely(!ff)) return NULL;
    }

    ff = procfile_readall(ff);
    if(unlikely(!ff))
        return NULL;

    struct mountinfo *root = NULL, *last = NULL, *mi = NULL;

    unsigned long l, lines = procfile_lines(ff);
    for(l = 0; l < lines ;l++) {
        if(unlikely(procfile_linewords(ff, l) < 5))
            continue;

        mi = mallocz(sizeof(struct mountinfo));

        unsigned long w = 0;
        mi->id = str2ul(procfile_lineword(ff, l, w)); w++;
        mi->parentid = str2ul(procfile_lineword(ff, l, w)); w++;

        char *major = procfile_lineword(ff, l, w), *minor; w++;
        for(minor = major; *minor && *minor != ':' ;minor++) ;

        if(unlikely(!*minor)) {
            error("Cannot parse major:minor on '%s' at line %lu of '%s'", major, l + 1, filename);
            freez(mi);
            continue;
        }

        *minor = '\0';
        minor++;

        mi->flags = 0;

        mi->major = str2ul(major);
        mi->minor = str2ul(minor);

        mi->root = strdupz(procfile_lineword(ff, l, w)); w++;
        mi->root_hash = simple_hash(mi->root);

        mi->mount_point = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
        mi->mount_point_hash = simple_hash(mi->mount_point);

        mi->persistent_id = strdupz(mi->mount_point);
        netdata_fix_chart_id(mi->persistent_id);
        mi->persistent_id_hash = simple_hash(mi->persistent_id);

        mi->mount_options = strdupz(procfile_lineword(ff, l, w)); w++;

        if(unlikely(is_read_only(mi->mount_options)))
            mi->flags |= MOUNTINFO_READONLY;

        // count the optional fields
/*
        unsigned long wo = w;
*/
        mi->optional_fields_count = 0;
        char *s = procfile_lineword(ff, l, w);
        while(*s && *s != '-') {
            w++;
            s = procfile_lineword(ff, l, w);
            mi->optional_fields_count++;
        }

/*
        if(unlikely(mi->optional_fields_count)) {
            // we have some optional fields
            // read them into a new array of pointers;

            mi->optional_fields = mallocz(mi->optional_fields_count * sizeof(char *));

            int i;
            for(i = 0; i < mi->optional_fields_count ; i++) {
                *mi->optional_fields[wo] = strdupz(procfile_lineword(ff, l, w));
                wo++;
            }
        }
        else
            mi->optional_fields = NULL;
*/

        if(likely(*s == '-')) {
            w++;

            mi->filesystem = strdupz(procfile_lineword(ff, l, w)); w++;
            mi->filesystem_hash = simple_hash(mi->filesystem);

            mi->mount_source = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
            mi->mount_source_hash = simple_hash(mi->mount_source);

            mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;

            if(unlikely(is_read_only(mi->super_options)))
                mi->flags |= MOUNTINFO_READONLY;

            if(unlikely(ME_DUMMY(mi->mount_source, mi->filesystem)))
                mi->flags |= MOUNTINFO_IS_DUMMY;

            if(unlikely(ME_REMOTE(mi->mount_source, mi->filesystem)))
                mi->flags |= MOUNTINFO_IS_REMOTE;

            // mark as BIND the duplicates (i.e. same filesystem + same source)
            if(do_statvfs) {
                struct stat buf;
                if(unlikely(stat(mi->mount_point, &buf) == -1)) {
                    mi->st_dev = 0;
                    mi->flags |= MOUNTINFO_NO_STAT;
                }
                else {
                    mi->st_dev = buf.st_dev;

                    struct mountinfo *mt;
                    for(mt = root; mt; mt = mt->next) {
                        if(unlikely(mt->st_dev == mi->st_dev && !(mt->flags & MOUNTINFO_IS_SAME_DEV))) {
                            if(strlen(mi->mount_point) < strlen(mt->mount_point))
                                mt->flags |= MOUNTINFO_IS_SAME_DEV;
                            else
                                mi->flags |= MOUNTINFO_IS_SAME_DEV;
                        }
                    }
                }
            }
            else {
                mi->st_dev = 0;
            }
        }
        else {
            mi->filesystem = NULL;
            mi->filesystem_hash = 0;

            mi->mount_source = NULL;
            mi->mount_source_hash = 0;

            mi->super_options = NULL;

            mi->st_dev = 0;
        }

        // check if it has size
        if(do_statvfs && !(mi->flags & MOUNTINFO_IS_DUMMY)) {
            struct statvfs buff_statvfs;
            if(unlikely(statvfs(mi->mount_point, &buff_statvfs) < 0)) {
                mi->flags |= MOUNTINFO_NO_STAT;
            }
            else if(unlikely(!buff_statvfs.f_blocks /* || !buff_statvfs.f_files */)) {
                mi->flags |= MOUNTINFO_NO_SIZE;
            }
        }

        // link it
        if(unlikely(!root))
            root = mi;
        else
            last->next = mi;

        last = mi;
        mi->next = NULL;

/*
#ifdef NETDATA_INTERNAL_CHECKS
        fprintf(stderr, "MOUNTINFO: %ld %ld %lu:%lu root '%s', persistent id '%s', mount point '%s', mount options '%s', filesystem '%s', mount source '%s', super options '%s'%s%s%s%s%s%s\n",
             mi->id,
             mi->parentid,
             mi->major,
             mi->minor,
             mi->root,
             mi->persistent_id,
                (mi->mount_point)?mi->mount_point:"",
                (mi->mount_options)?mi->mount_options:"",
                (mi->filesystem)?mi->filesystem:"",
                (mi->mount_source)?mi->mount_source:"",
                (mi->super_options)?mi->super_options:"",
                (mi->flags & MOUNTINFO_IS_DUMMY)?" DUMMY":"",
                (mi->flags & MOUNTINFO_IS_BIND)?" BIND":"",
                (mi->flags & MOUNTINFO_IS_REMOTE)?" REMOTE":"",
                (mi->flags & MOUNTINFO_NO_STAT)?" NOSTAT":"",
                (mi->flags & MOUNTINFO_NO_SIZE)?" NOSIZE":"",
                (mi->flags & MOUNTINFO_IS_SAME_DEV)?" SAMEDEV":""
        );
#endif
*/
    }

/* find if the mount options have "bind" in them
    {
        FILE *fp = setmntent(MOUNTED, "r");
        if (fp != NULL) {
            struct mntent mntbuf;
            struct mntent *mnt;
            char buf[4096 + 1];

            while ((mnt = getmntent_r(fp, &mntbuf, buf, 4096))) {
                char *bind = hasmntopt(mnt, "bind");
                if(unlikely(bind)) {
                    struct mountinfo *mi;
                    for(mi = root; mi ; mi = mi->next) {
                        if(unlikely(strcmp(mnt->mnt_dir, mi->mount_point) == 0)) {
                            fprintf(stderr, "Mount point '%s' is BIND\n", mi->mount_point);
                            mi->flags |= MOUNTINFO_IS_BIND;
                            break;
                        }
                    }

#ifdef NETDATA_INTERNAL_CHECKS
                    if(unlikely(!mi)) {
                        error("Mount point '%s' not found in /proc/self/mountinfo", mnt->mnt_dir);
                    }
#endif
                }
            }
            endmntent(fp);
        }
    }
*/

    procfile_close(ff);
    return root;
}
コード例 #12
0
ファイル: proc_stat.c プロジェクト: tvieira/netdata
int do_proc_stat(int update_every, usec_t dt) {
    (void)dt;

    static struct cpu_chart *all_cpu_charts = NULL;
    static size_t all_cpu_charts_size = 0;
    static procfile *ff = NULL;
    static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1, do_core_throttle_count = -1, do_package_throttle_count = -1, do_scaling_cur_freq = -1;
    static uint32_t hash_intr, hash_ctxt, hash_processes, hash_procs_running, hash_procs_blocked;
    static char *core_throttle_count_filename = NULL, *package_throttle_count_filename = NULL, *scaling_cur_freq_filename = NULL;

    if(unlikely(do_cpu == -1)) {
        do_cpu                    = config_get_boolean("plugin:proc:/proc/stat", "cpu utilization", CONFIG_BOOLEAN_YES);
        do_cpu_cores              = config_get_boolean("plugin:proc:/proc/stat", "per cpu core utilization", CONFIG_BOOLEAN_YES);
        do_interrupts             = config_get_boolean("plugin:proc:/proc/stat", "cpu interrupts", CONFIG_BOOLEAN_YES);
        do_context                = config_get_boolean("plugin:proc:/proc/stat", "context switches", CONFIG_BOOLEAN_YES);
        do_forks                  = config_get_boolean("plugin:proc:/proc/stat", "processes started", CONFIG_BOOLEAN_YES);
        do_processes              = config_get_boolean("plugin:proc:/proc/stat", "processes running", CONFIG_BOOLEAN_YES);

        // give sane defaults based on the number of processors
        if(processors > 50) {
            // the system has too many processors
            keep_per_core_fds_open = CONFIG_BOOLEAN_NO;
            do_core_throttle_count = CONFIG_BOOLEAN_NO;
            do_package_throttle_count = CONFIG_BOOLEAN_NO;
            do_scaling_cur_freq = CONFIG_BOOLEAN_NO;
        }
        else {
            // the system has a reasonable number of processors
            keep_per_core_fds_open = CONFIG_BOOLEAN_YES;
            do_core_throttle_count = CONFIG_BOOLEAN_AUTO;
            do_package_throttle_count = CONFIG_BOOLEAN_NO;
            do_scaling_cur_freq = CONFIG_BOOLEAN_NO;
        }

        keep_per_core_fds_open    = config_get_boolean("plugin:proc:/proc/stat", "keep per core files open", keep_per_core_fds_open);
        do_core_throttle_count    = config_get_boolean_ondemand("plugin:proc:/proc/stat", "core_throttle_count", do_core_throttle_count);
        do_package_throttle_count = config_get_boolean_ondemand("plugin:proc:/proc/stat", "package_throttle_count", do_package_throttle_count);
        do_scaling_cur_freq       = config_get_boolean_ondemand("plugin:proc:/proc/stat", "scaling_cur_freq", do_scaling_cur_freq);

        hash_intr = simple_hash("intr");
        hash_ctxt = simple_hash("ctxt");
        hash_processes = simple_hash("processes");
        hash_procs_running = simple_hash("procs_running");
        hash_procs_blocked = simple_hash("procs_blocked");

        char filename[FILENAME_MAX + 1];
        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/thermal_throttle/core_throttle_count");
        core_throttle_count_filename = config_get("plugin:proc:/proc/stat", "core_throttle_count filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/thermal_throttle/package_throttle_count");
        package_throttle_count_filename = config_get("plugin:proc:/proc/stat", "package_throttle_count filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/cpufreq/scaling_cur_freq");
        scaling_cur_freq_filename = config_get("plugin:proc:/proc/stat", "scaling_cur_freq filename to monitor", filename);
    }

    if(unlikely(!ff)) {
        char filename[FILENAME_MAX + 1];
        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/stat");
        ff = procfile_open(config_get("plugin:proc:/proc/stat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
        if(unlikely(!ff)) return 1;
    }

    ff = procfile_readall(ff);
    if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time

    size_t lines = procfile_lines(ff), l;
    size_t words;

    unsigned long long processes = 0, running = 0 , blocked = 0;

    for(l = 0; l < lines ;l++) {
        char *row_key = procfile_lineword(ff, l, 0);
        uint32_t hash = simple_hash(row_key);

        // faster strncmp(row_key, "cpu", 3) == 0
        if(likely(row_key[0] == 'c' && row_key[1] == 'p' && row_key[2] == 'u')) {
            words = procfile_linewords(ff, l);
            if(unlikely(words < 9)) {
                error("Cannot read /proc/stat cpu line. Expected 9 params, read %zu.", words);
                continue;
            }

            size_t core    = (row_key[3] == '\0') ? 0 : str2ul(&row_key[3]) + 1;

            if(likely((core == 0 && do_cpu) || (core > 0 && do_cpu_cores))) {
                char *id;
                unsigned long long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;

                id          = row_key;
                user        = str2ull(procfile_lineword(ff, l, 1));
                nice        = str2ull(procfile_lineword(ff, l, 2));
                system      = str2ull(procfile_lineword(ff, l, 3));
                idle        = str2ull(procfile_lineword(ff, l, 4));
                iowait      = str2ull(procfile_lineword(ff, l, 5));
                irq         = str2ull(procfile_lineword(ff, l, 6));
                softirq     = str2ull(procfile_lineword(ff, l, 7));
                steal       = str2ull(procfile_lineword(ff, l, 8));

                guest       = str2ull(procfile_lineword(ff, l, 9));
                user -= guest;

                guest_nice  = str2ull(procfile_lineword(ff, l, 10));
                nice -= guest_nice;

                char *title, *type, *context, *family;
                long priority;

                if(core >= all_cpu_charts_size) {
                    size_t old_cpu_charts_size = all_cpu_charts_size;
                    all_cpu_charts_size = core + 1;
                    all_cpu_charts = reallocz(all_cpu_charts, sizeof(struct cpu_chart) * all_cpu_charts_size);
                    memset(&all_cpu_charts[old_cpu_charts_size], 0, sizeof(struct cpu_chart) * (all_cpu_charts_size - old_cpu_charts_size));
                }
                struct cpu_chart *cpu_chart = &all_cpu_charts[core];

                if(unlikely(!cpu_chart->st)) {
                    cpu_chart->id = strdupz(id);

                    if(core == 0) {
                        title = "Total CPU utilization";
                        type = "system";
                        context = "system.cpu";
                        family = id;
                        priority = 100;
                    }
                    else {
                        title = "Core utilization";
                        type = "cpu";
                        context = "cpu.cpu";
                        family = "utilization";
                        priority = 1000;

                        // FIXME: check for /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
                        // FIXME: check for /sys/devices/system/cpu/cpu*/cpufreq/stats/time_in_state

                        char filename[FILENAME_MAX + 1];
                        struct stat stbuf;

                        if(do_core_throttle_count != CONFIG_BOOLEAN_NO) {
                            snprintfz(filename, FILENAME_MAX, core_throttle_count_filename, id);
                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[CORE_THROTTLE_COUNT_INDEX].filename = strdupz(filename);
                                cpu_chart->files[CORE_THROTTLE_COUNT_INDEX].fd = -1;
                                do_core_throttle_count = CONFIG_BOOLEAN_YES;
                            }
                        }

                        if(do_package_throttle_count != CONFIG_BOOLEAN_NO) {
                            snprintfz(filename, FILENAME_MAX, package_throttle_count_filename, id);
                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[PACKAGE_THROTTLE_COUNT_INDEX].filename = strdupz(filename);
                                cpu_chart->files[PACKAGE_THROTTLE_COUNT_INDEX].fd = -1;
                                do_package_throttle_count = CONFIG_BOOLEAN_YES;
                            }
                        }

                        if(do_scaling_cur_freq != CONFIG_BOOLEAN_NO) {
                            snprintfz(filename, FILENAME_MAX, scaling_cur_freq_filename, id);
                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[SCALING_CUR_FREQ_INDEX].filename = strdupz(filename);
                                cpu_chart->files[SCALING_CUR_FREQ_INDEX].fd = -1;
                                do_scaling_cur_freq = CONFIG_BOOLEAN_YES;
                            }
                        }
                    }

                    cpu_chart->st = rrdset_create_localhost(
                            type
                            , id
                            , NULL
                            , family
                            , context
                            , title
                            , "percentage"
                            , "proc"
                            , "stat"
                            , priority
                            , update_every
                            , RRDSET_TYPE_STACKED
                    );

                    long multiplier = 1;
                    long divisor = 1; // sysconf(_SC_CLK_TCK);

                    cpu_chart->rd_guest_nice = rrddim_add(cpu_chart->st, "guest_nice", NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_guest      = rrddim_add(cpu_chart->st, "guest",      NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_steal      = rrddim_add(cpu_chart->st, "steal",      NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_softirq    = rrddim_add(cpu_chart->st, "softirq",    NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_irq        = rrddim_add(cpu_chart->st, "irq",        NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_user       = rrddim_add(cpu_chart->st, "user",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_system     = rrddim_add(cpu_chart->st, "system",     NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_nice       = rrddim_add(cpu_chart->st, "nice",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_iowait     = rrddim_add(cpu_chart->st, "iowait",     NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_idle       = rrddim_add(cpu_chart->st, "idle",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    rrddim_hide(cpu_chart->st, "idle");
                }
                else rrdset_next(cpu_chart->st);

                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_user, user);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_nice, nice);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_system, system);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_idle, idle);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_iowait, iowait);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_irq, irq);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_softirq, softirq);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_steal, steal);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_guest, guest);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_guest_nice, guest_nice);
                rrdset_done(cpu_chart->st);
            }
        }
        else if(unlikely(hash == hash_intr && strcmp(row_key, "intr") == 0)) {
            if(likely(do_interrupts)) {
                static RRDSET *st_intr = NULL;
                static RRDDIM *rd_interrupts = NULL;
                unsigned long long value = str2ull(procfile_lineword(ff, l, 1));

                if(unlikely(!st_intr)) {
                    st_intr = rrdset_create_localhost(
                            "system"
                            , "intr"
                            , NULL
                            , "interrupts"
                            , NULL
                            , "CPU Interrupts"
                            , "interrupts/s"
                            , "proc"
                            , "stat"
                            , 900
                            , update_every
                            , RRDSET_TYPE_LINE
                    );

                    rrdset_flag_set(st_intr, RRDSET_FLAG_DETAIL);

                    rd_interrupts = rrddim_add(st_intr, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                }
                else rrdset_next(st_intr);

                rrddim_set_by_pointer(st_intr, rd_interrupts, value);
                rrdset_done(st_intr);
            }
        }
        else if(unlikely(hash == hash_ctxt && strcmp(row_key, "ctxt") == 0)) {
            if(likely(do_context)) {
                static RRDSET *st_ctxt = NULL;
                static RRDDIM *rd_switches = NULL;
                unsigned long long value = str2ull(procfile_lineword(ff, l, 1));

                if(unlikely(!st_ctxt)) {
                    st_ctxt = rrdset_create_localhost(
                            "system"
                            , "ctxt"
                            , NULL
                            , "processes"
                            , NULL
                            , "CPU Context Switches"
                            , "context switches/s"
                            , "proc"
                            , "stat"
                            , 800
                            , update_every
                            , RRDSET_TYPE_LINE
                    );

                    rd_switches = rrddim_add(st_ctxt, "switches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                }
                else rrdset_next(st_ctxt);

                rrddim_set_by_pointer(st_ctxt, rd_switches, value);
                rrdset_done(st_ctxt);
            }
        }
        else if(unlikely(hash == hash_processes && !processes && strcmp(row_key, "processes") == 0)) {
            processes = str2ull(procfile_lineword(ff, l, 1));
        }
        else if(unlikely(hash == hash_procs_running && !running && strcmp(row_key, "procs_running") == 0)) {
            running = str2ull(procfile_lineword(ff, l, 1));
        }
        else if(unlikely(hash == hash_procs_blocked && !blocked && strcmp(row_key, "procs_blocked") == 0)) {
            blocked = str2ull(procfile_lineword(ff, l, 1));
        }
    }

    // --------------------------------------------------------------------

    if(likely(do_forks)) {
        static RRDSET *st_forks = NULL;
        static RRDDIM *rd_started = NULL;

        if(unlikely(!st_forks)) {
            st_forks = rrdset_create_localhost(
                    "system"
                    , "forks"
                    , NULL
                    , "processes"
                    , NULL
                    , "Started Processes"
                    , "processes/s"
                    , "proc"
                    , "stat"
                    , 700
                    , update_every
                    , RRDSET_TYPE_LINE
            );
            rrdset_flag_set(st_forks, RRDSET_FLAG_DETAIL);

            rd_started = rrddim_add(st_forks, "started", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
        }
        else rrdset_next(st_forks);

        rrddim_set_by_pointer(st_forks, rd_started, processes);
        rrdset_done(st_forks);
    }

    // --------------------------------------------------------------------

    if(likely(do_processes)) {
        static RRDSET *st_processes = NULL;
        static RRDDIM *rd_running = NULL;
        static RRDDIM *rd_blocked = NULL;

        if(unlikely(!st_processes)) {
            st_processes = rrdset_create_localhost(
                    "system"
                    , "processes"
                    , NULL
                    , "processes"
                    , NULL
                    , "System Processes"
                    , "processes"
                    , "proc"
                    , "stat"
                    , 600
                    , update_every
                    , RRDSET_TYPE_LINE
            );

            rd_running = rrddim_add(st_processes, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
            rd_blocked = rrddim_add(st_processes, "blocked", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
        }
        else rrdset_next(st_processes);

        rrddim_set_by_pointer(st_processes, rd_running, running);
        rrddim_set_by_pointer(st_processes, rd_blocked, blocked);
        rrdset_done(st_processes);
    }

    if(likely(all_cpu_charts_size > 1)) {
        if(likely(do_core_throttle_count != CONFIG_BOOLEAN_NO)) {
            int r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CORE_THROTTLE_COUNT_INDEX);
            if(likely(r != -1 && (do_core_throttle_count == CONFIG_BOOLEAN_YES || r > 0))) {
                do_core_throttle_count = CONFIG_BOOLEAN_YES;

                static RRDSET *st_core_throttle_count = NULL;

                if (unlikely(!st_core_throttle_count))
                    st_core_throttle_count = rrdset_create_localhost(
                            "cpu"
                            , "core_throttling"
                            , NULL
                            , "throttling"
                            , "cpu.core_throttling"
                            , "Core Thermal Throttling Events"
                            , "events/s"
                            , "proc"
                            , "stat"
                            , 5001
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_core_throttle_count);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CORE_THROTTLE_COUNT_INDEX, st_core_throttle_count, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                rrdset_done(st_core_throttle_count);
            }
        }

        if(likely(do_package_throttle_count != CONFIG_BOOLEAN_NO)) {
            int r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, PACKAGE_THROTTLE_COUNT_INDEX);
            if(likely(r != -1 && (do_package_throttle_count == CONFIG_BOOLEAN_YES || r > 0))) {
                do_package_throttle_count = CONFIG_BOOLEAN_YES;

                static RRDSET *st_package_throttle_count = NULL;

                if(unlikely(!st_package_throttle_count))
                    st_package_throttle_count = rrdset_create_localhost(
                            "cpu"
                            , "package_throttling"
                            , NULL
                            , "throttling"
                            , "cpu.package_throttling"
                            , "Package Thermal Throttling Events"
                            , "events/s"
                            , "proc"
                            , "stat"
                            , 5002
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_package_throttle_count);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, PACKAGE_THROTTLE_COUNT_INDEX, st_package_throttle_count, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                rrdset_done(st_package_throttle_count);
            }
        }

        if(likely(do_scaling_cur_freq != CONFIG_BOOLEAN_NO)) {
            int r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, SCALING_CUR_FREQ_INDEX);
            if(likely(r != -1 && (do_scaling_cur_freq == CONFIG_BOOLEAN_YES || r > 0))) {
                do_scaling_cur_freq = CONFIG_BOOLEAN_YES;

                static RRDSET *st_scaling_cur_freq = NULL;

                if(unlikely(!st_scaling_cur_freq))
                    st_scaling_cur_freq = rrdset_create_localhost(
                            "cpu"
                            , "scaling_cur_freq"
                            , NULL
                            , "cpufreq"
                            , "cpu.scaling_cur_freq"
                            , "Per CPU Core, Current CPU Scaling Frequency"
                            , "MHz"
                            , "proc"
                            , "stat"
                            , 5003
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_scaling_cur_freq);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, SCALING_CUR_FREQ_INDEX, st_scaling_cur_freq, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
                rrdset_done(st_scaling_cur_freq);
            }
        }
    }

    return 0;
}
コード例 #13
0
ファイル: proc_stat.c プロジェクト: firehol/netdata
int do_proc_stat(int update_every, usec_t dt) {
    (void)dt;

    static struct cpu_chart *all_cpu_charts = NULL;
    static size_t all_cpu_charts_size = 0;
    static procfile *ff = NULL;
    static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
           do_core_throttle_count = -1, do_package_throttle_count = -1, do_cpu_freq = -1, do_cpuidle = -1;
    static uint32_t hash_intr, hash_ctxt, hash_processes, hash_procs_running, hash_procs_blocked;
    static char *core_throttle_count_filename = NULL, *package_throttle_count_filename = NULL, *scaling_cur_freq_filename = NULL,
           *time_in_state_filename = NULL, *schedstat_filename = NULL, *cpuidle_name_filename = NULL, *cpuidle_time_filename = NULL;
    static RRDVAR *cpus_var = NULL;
    static int accurate_freq_avail = 0, accurate_freq_is_used = 0;
    size_t cores_found = (size_t)processors;

    if(unlikely(do_cpu == -1)) {
        do_cpu                    = config_get_boolean("plugin:proc:/proc/stat", "cpu utilization", CONFIG_BOOLEAN_YES);
        do_cpu_cores              = config_get_boolean("plugin:proc:/proc/stat", "per cpu core utilization", CONFIG_BOOLEAN_YES);
        do_interrupts             = config_get_boolean("plugin:proc:/proc/stat", "cpu interrupts", CONFIG_BOOLEAN_YES);
        do_context                = config_get_boolean("plugin:proc:/proc/stat", "context switches", CONFIG_BOOLEAN_YES);
        do_forks                  = config_get_boolean("plugin:proc:/proc/stat", "processes started", CONFIG_BOOLEAN_YES);
        do_processes              = config_get_boolean("plugin:proc:/proc/stat", "processes running", CONFIG_BOOLEAN_YES);

        // give sane defaults based on the number of processors
        if(unlikely(processors > 50)) {
            // the system has too many processors
            keep_per_core_fds_open = CONFIG_BOOLEAN_NO;
            do_core_throttle_count = CONFIG_BOOLEAN_NO;
            do_package_throttle_count = CONFIG_BOOLEAN_NO;
            do_cpu_freq = CONFIG_BOOLEAN_NO;
            do_cpuidle = CONFIG_BOOLEAN_NO;
        }
        else {
            // the system has a reasonable number of processors
            keep_per_core_fds_open = CONFIG_BOOLEAN_YES;
            do_core_throttle_count = CONFIG_BOOLEAN_AUTO;
            do_package_throttle_count = CONFIG_BOOLEAN_NO;
            do_cpu_freq = CONFIG_BOOLEAN_YES;
            do_cpuidle = CONFIG_BOOLEAN_YES;
        }
        if(unlikely(processors > 24)) {
            // the system has too many processors
            keep_cpuidle_fds_open = CONFIG_BOOLEAN_NO;
        }
        else {
            // the system has a reasonable number of processors
            keep_cpuidle_fds_open = CONFIG_BOOLEAN_YES;
        }

        keep_per_core_fds_open    = config_get_boolean("plugin:proc:/proc/stat", "keep per core files open", keep_per_core_fds_open);
        keep_cpuidle_fds_open     = config_get_boolean("plugin:proc:/proc/stat", "keep cpuidle files open", keep_cpuidle_fds_open);
        do_core_throttle_count    = config_get_boolean_ondemand("plugin:proc:/proc/stat", "core_throttle_count", do_core_throttle_count);
        do_package_throttle_count = config_get_boolean_ondemand("plugin:proc:/proc/stat", "package_throttle_count", do_package_throttle_count);
        do_cpu_freq               = config_get_boolean_ondemand("plugin:proc:/proc/stat", "cpu frequency", do_cpu_freq);
        do_cpuidle                = config_get_boolean_ondemand("plugin:proc:/proc/stat", "cpu idle states", do_cpuidle);

        hash_intr = simple_hash("intr");
        hash_ctxt = simple_hash("ctxt");
        hash_processes = simple_hash("processes");
        hash_procs_running = simple_hash("procs_running");
        hash_procs_blocked = simple_hash("procs_blocked");

        char filename[FILENAME_MAX + 1];
        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/thermal_throttle/core_throttle_count");
        core_throttle_count_filename = config_get("plugin:proc:/proc/stat", "core_throttle_count filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/thermal_throttle/package_throttle_count");
        package_throttle_count_filename = config_get("plugin:proc:/proc/stat", "package_throttle_count filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/cpufreq/scaling_cur_freq");
        scaling_cur_freq_filename = config_get("plugin:proc:/proc/stat", "scaling_cur_freq filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/%s/cpufreq/stats/time_in_state");
        time_in_state_filename = config_get("plugin:proc:/proc/stat", "time_in_state filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/schedstat");
        schedstat_filename = config_get("plugin:proc:/proc/stat", "schedstat filename to monitor", filename);

        if(do_cpuidle != CONFIG_BOOLEAN_NO) {
            struct stat stbuf;

            if (stat(schedstat_filename, &stbuf))
                do_cpuidle = CONFIG_BOOLEAN_NO;
        }

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/cpu%zu/cpuidle/state%zu/name");
        cpuidle_name_filename = config_get("plugin:proc:/proc/stat", "cpuidle name filename to monitor", filename);

        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/cpu/cpu%zu/cpuidle/state%zu/time");
        cpuidle_time_filename = config_get("plugin:proc:/proc/stat", "cpuidle time filename to monitor", filename);
    }

    if(unlikely(!ff)) {
        char filename[FILENAME_MAX + 1];
        snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/stat");
        ff = procfile_open(config_get("plugin:proc:/proc/stat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
        if(unlikely(!ff)) return 1;
    }

    ff = procfile_readall(ff);
    if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time

    size_t lines = procfile_lines(ff), l;
    size_t words;

    unsigned long long processes = 0, running = 0 , blocked = 0;

    for(l = 0; l < lines ;l++) {
        char *row_key = procfile_lineword(ff, l, 0);
        uint32_t hash = simple_hash(row_key);

        // faster strncmp(row_key, "cpu", 3) == 0
        if(likely(row_key[0] == 'c' && row_key[1] == 'p' && row_key[2] == 'u')) {
            words = procfile_linewords(ff, l);
            if(unlikely(words < 9)) {
                error("Cannot read /proc/stat cpu line. Expected 9 params, read %zu.", words);
                continue;
            }

            size_t core    = (row_key[3] == '\0') ? 0 : str2ul(&row_key[3]) + 1;
            if(likely(core > 0)) cores_found = core;

            if(likely((core == 0 && do_cpu) || (core > 0 && do_cpu_cores))) {
                char *id;
                unsigned long long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;

                id          = row_key;
                user        = str2ull(procfile_lineword(ff, l, 1));
                nice        = str2ull(procfile_lineword(ff, l, 2));
                system      = str2ull(procfile_lineword(ff, l, 3));
                idle        = str2ull(procfile_lineword(ff, l, 4));
                iowait      = str2ull(procfile_lineword(ff, l, 5));
                irq         = str2ull(procfile_lineword(ff, l, 6));
                softirq     = str2ull(procfile_lineword(ff, l, 7));
                steal       = str2ull(procfile_lineword(ff, l, 8));

                guest       = str2ull(procfile_lineword(ff, l, 9));
                user -= guest;

                guest_nice  = str2ull(procfile_lineword(ff, l, 10));
                nice -= guest_nice;

                char *title, *type, *context, *family;
                long priority;

                if(unlikely(core >= all_cpu_charts_size)) {
                    size_t old_cpu_charts_size = all_cpu_charts_size;
                    all_cpu_charts_size = core + 1;
                    all_cpu_charts = reallocz(all_cpu_charts, sizeof(struct cpu_chart) * all_cpu_charts_size);
                    memset(&all_cpu_charts[old_cpu_charts_size], 0, sizeof(struct cpu_chart) * (all_cpu_charts_size - old_cpu_charts_size));
                }
                struct cpu_chart *cpu_chart = &all_cpu_charts[core];

                if(unlikely(!cpu_chart->st)) {
                    cpu_chart->id = strdupz(id);

                    if(unlikely(core == 0)) {
                        title = "Total CPU utilization";
                        type = "system";
                        context = "system.cpu";
                        family = id;
                        priority = NETDATA_CHART_PRIO_SYSTEM_CPU;
                    }
                    else {
                        title = "Core utilization";
                        type = "cpu";
                        context = "cpu.cpu";
                        family = "utilization";
                        priority = NETDATA_CHART_PRIO_CPU_PER_CORE;

                        char filename[FILENAME_MAX + 1];
                        struct stat stbuf;

                        if(do_core_throttle_count != CONFIG_BOOLEAN_NO) {
                            snprintfz(filename, FILENAME_MAX, core_throttle_count_filename, id);
                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[CORE_THROTTLE_COUNT_INDEX].filename = strdupz(filename);
                                cpu_chart->files[CORE_THROTTLE_COUNT_INDEX].fd = -1;
                                do_core_throttle_count = CONFIG_BOOLEAN_YES;
                            }
                        }

                        if(do_package_throttle_count != CONFIG_BOOLEAN_NO) {
                            snprintfz(filename, FILENAME_MAX, package_throttle_count_filename, id);
                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[PACKAGE_THROTTLE_COUNT_INDEX].filename = strdupz(filename);
                                cpu_chart->files[PACKAGE_THROTTLE_COUNT_INDEX].fd = -1;
                                do_package_throttle_count = CONFIG_BOOLEAN_YES;
                            }
                        }

                        if(do_cpu_freq != CONFIG_BOOLEAN_NO) {

                            snprintfz(filename, FILENAME_MAX, scaling_cur_freq_filename, id);

                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->files[CPU_FREQ_INDEX].filename = strdupz(filename);
                                cpu_chart->files[CPU_FREQ_INDEX].fd = -1;
                                do_cpu_freq = CONFIG_BOOLEAN_YES;
                            }

                            snprintfz(filename, FILENAME_MAX, time_in_state_filename, id);

                            if (stat(filename, &stbuf) == 0) {
                                cpu_chart->time_in_state_files.filename = strdupz(filename);
                                cpu_chart->time_in_state_files.ff = NULL;
                                do_cpu_freq = CONFIG_BOOLEAN_YES;
                                accurate_freq_avail = 1;
                            }
                        }
                    }

                    cpu_chart->st = rrdset_create_localhost(
                            type
                            , id
                            , NULL
                            , family
                            , context
                            , title
                            , "percentage"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , priority + core
                            , update_every
                            , RRDSET_TYPE_STACKED
                    );

                    long multiplier = 1;
                    long divisor = 1; // sysconf(_SC_CLK_TCK);

                    cpu_chart->rd_guest_nice = rrddim_add(cpu_chart->st, "guest_nice", NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_guest      = rrddim_add(cpu_chart->st, "guest",      NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_steal      = rrddim_add(cpu_chart->st, "steal",      NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_softirq    = rrddim_add(cpu_chart->st, "softirq",    NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_irq        = rrddim_add(cpu_chart->st, "irq",        NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_user       = rrddim_add(cpu_chart->st, "user",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_system     = rrddim_add(cpu_chart->st, "system",     NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_nice       = rrddim_add(cpu_chart->st, "nice",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_iowait     = rrddim_add(cpu_chart->st, "iowait",     NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    cpu_chart->rd_idle       = rrddim_add(cpu_chart->st, "idle",       NULL, multiplier, divisor, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                    rrddim_hide(cpu_chart->st, "idle");

                    if(unlikely(core == 0 && cpus_var == NULL))
                        cpus_var = rrdvar_custom_host_variable_create(localhost, "active_processors");
                }
                else rrdset_next(cpu_chart->st);

                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_user, user);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_nice, nice);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_system, system);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_idle, idle);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_iowait, iowait);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_irq, irq);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_softirq, softirq);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_steal, steal);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_guest, guest);
                rrddim_set_by_pointer(cpu_chart->st, cpu_chart->rd_guest_nice, guest_nice);
                rrdset_done(cpu_chart->st);
            }
        }
        else if(unlikely(hash == hash_intr && strcmp(row_key, "intr") == 0)) {
            if(likely(do_interrupts)) {
                static RRDSET *st_intr = NULL;
                static RRDDIM *rd_interrupts = NULL;
                unsigned long long value = str2ull(procfile_lineword(ff, l, 1));

                if(unlikely(!st_intr)) {
                    st_intr = rrdset_create_localhost(
                            "system"
                            , "intr"
                            , NULL
                            , "interrupts"
                            , NULL
                            , "CPU Interrupts"
                            , "interrupts/s"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , NETDATA_CHART_PRIO_SYSTEM_INTR
                            , update_every
                            , RRDSET_TYPE_LINE
                    );

                    rrdset_flag_set(st_intr, RRDSET_FLAG_DETAIL);

                    rd_interrupts = rrddim_add(st_intr, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                }
                else rrdset_next(st_intr);

                rrddim_set_by_pointer(st_intr, rd_interrupts, value);
                rrdset_done(st_intr);
            }
        }
        else if(unlikely(hash == hash_ctxt && strcmp(row_key, "ctxt") == 0)) {
            if(likely(do_context)) {
                static RRDSET *st_ctxt = NULL;
                static RRDDIM *rd_switches = NULL;
                unsigned long long value = str2ull(procfile_lineword(ff, l, 1));

                if(unlikely(!st_ctxt)) {
                    st_ctxt = rrdset_create_localhost(
                            "system"
                            , "ctxt"
                            , NULL
                            , "processes"
                            , NULL
                            , "CPU Context Switches"
                            , "context switches/s"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , NETDATA_CHART_PRIO_SYSTEM_CTXT
                            , update_every
                            , RRDSET_TYPE_LINE
                    );

                    rd_switches = rrddim_add(st_ctxt, "switches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                }
                else rrdset_next(st_ctxt);

                rrddim_set_by_pointer(st_ctxt, rd_switches, value);
                rrdset_done(st_ctxt);
            }
        }
        else if(unlikely(hash == hash_processes && !processes && strcmp(row_key, "processes") == 0)) {
            processes = str2ull(procfile_lineword(ff, l, 1));
        }
        else if(unlikely(hash == hash_procs_running && !running && strcmp(row_key, "procs_running") == 0)) {
            running = str2ull(procfile_lineword(ff, l, 1));
        }
        else if(unlikely(hash == hash_procs_blocked && !blocked && strcmp(row_key, "procs_blocked") == 0)) {
            blocked = str2ull(procfile_lineword(ff, l, 1));
        }
    }

    // --------------------------------------------------------------------

    if(likely(do_forks)) {
        static RRDSET *st_forks = NULL;
        static RRDDIM *rd_started = NULL;

        if(unlikely(!st_forks)) {
            st_forks = rrdset_create_localhost(
                    "system"
                    , "forks"
                    , NULL
                    , "processes"
                    , NULL
                    , "Started Processes"
                    , "processes/s"
                    , PLUGIN_PROC_NAME
                    , PLUGIN_PROC_MODULE_STAT_NAME
                    , NETDATA_CHART_PRIO_SYSTEM_FORKS
                    , update_every
                    , RRDSET_TYPE_LINE
            );
            rrdset_flag_set(st_forks, RRDSET_FLAG_DETAIL);

            rd_started = rrddim_add(st_forks, "started", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
        }
        else rrdset_next(st_forks);

        rrddim_set_by_pointer(st_forks, rd_started, processes);
        rrdset_done(st_forks);
    }

    // --------------------------------------------------------------------

    if(likely(do_processes)) {
        static RRDSET *st_processes = NULL;
        static RRDDIM *rd_running = NULL;
        static RRDDIM *rd_blocked = NULL;

        if(unlikely(!st_processes)) {
            st_processes = rrdset_create_localhost(
                    "system"
                    , "processes"
                    , NULL
                    , "processes"
                    , NULL
                    , "System Processes"
                    , "processes"
                    , PLUGIN_PROC_NAME
                    , PLUGIN_PROC_MODULE_STAT_NAME
                    , NETDATA_CHART_PRIO_SYSTEM_PROCESSES
                    , update_every
                    , RRDSET_TYPE_LINE
            );

            rd_running = rrddim_add(st_processes, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
            rd_blocked = rrddim_add(st_processes, "blocked", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
        }
        else rrdset_next(st_processes);

        rrddim_set_by_pointer(st_processes, rd_running, running);
        rrddim_set_by_pointer(st_processes, rd_blocked, blocked);
        rrdset_done(st_processes);
    }

    if(likely(all_cpu_charts_size > 1)) {
        if(likely(do_core_throttle_count != CONFIG_BOOLEAN_NO)) {
            int r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CORE_THROTTLE_COUNT_INDEX);
            if(likely(r != -1 && (do_core_throttle_count == CONFIG_BOOLEAN_YES || r > 0))) {
                do_core_throttle_count = CONFIG_BOOLEAN_YES;

                static RRDSET *st_core_throttle_count = NULL;

                if (unlikely(!st_core_throttle_count))
                    st_core_throttle_count = rrdset_create_localhost(
                            "cpu"
                            , "core_throttling"
                            , NULL
                            , "throttling"
                            , "cpu.core_throttling"
                            , "Core Thermal Throttling Events"
                            , "events/s"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , NETDATA_CHART_PRIO_CORE_THROTTLING
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_core_throttle_count);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CORE_THROTTLE_COUNT_INDEX, st_core_throttle_count, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                rrdset_done(st_core_throttle_count);
            }
        }

        if(likely(do_package_throttle_count != CONFIG_BOOLEAN_NO)) {
            int r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, PACKAGE_THROTTLE_COUNT_INDEX);
            if(likely(r != -1 && (do_package_throttle_count == CONFIG_BOOLEAN_YES || r > 0))) {
                do_package_throttle_count = CONFIG_BOOLEAN_YES;

                static RRDSET *st_package_throttle_count = NULL;

                if(unlikely(!st_package_throttle_count))
                    st_package_throttle_count = rrdset_create_localhost(
                            "cpu"
                            , "package_throttling"
                            , NULL
                            , "throttling"
                            , "cpu.package_throttling"
                            , "Package Thermal Throttling Events"
                            , "events/s"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , NETDATA_CHART_PRIO_PACKAGE_THROTTLING
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_package_throttle_count);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, PACKAGE_THROTTLE_COUNT_INDEX, st_package_throttle_count, 1, 1, RRD_ALGORITHM_INCREMENTAL);
                rrdset_done(st_package_throttle_count);
            }
        }

        if(likely(do_cpu_freq != CONFIG_BOOLEAN_NO)) {
            char filename[FILENAME_MAX + 1];
            int r = 0;

            if (accurate_freq_avail) {
                r = read_per_core_time_in_state_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CPU_FREQ_INDEX);
                if(r > 0 && !accurate_freq_is_used) {
                    accurate_freq_is_used = 1;
                    snprintfz(filename, FILENAME_MAX, time_in_state_filename, "cpu*");
                    info("cpufreq is using %s", filename);
                }
            }
            if (r < 1) {
                r = read_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CPU_FREQ_INDEX);
                if(accurate_freq_is_used) {
                    accurate_freq_is_used = 0;
                    snprintfz(filename, FILENAME_MAX, scaling_cur_freq_filename, "cpu*");
                    info("cpufreq fell back to %s", filename);
                }
            }

            if(likely(r != -1 && (do_cpu_freq == CONFIG_BOOLEAN_YES || r > 0))) {
                do_cpu_freq = CONFIG_BOOLEAN_YES;

                static RRDSET *st_scaling_cur_freq = NULL;

                if(unlikely(!st_scaling_cur_freq))
                    st_scaling_cur_freq = rrdset_create_localhost(
                            "cpu"
                            , "cpufreq"
                            , NULL
                            , "cpufreq"
                            , "cpufreq.cpufreq"
                            , "Current CPU Frequency"
                            , "MHz"
                            , PLUGIN_PROC_NAME
                            , PLUGIN_PROC_MODULE_STAT_NAME
                            , NETDATA_CHART_PRIO_CPUFREQ_SCALING_CUR_FREQ
                            , update_every
                            , RRDSET_TYPE_LINE
                    );
                else
                    rrdset_next(st_scaling_cur_freq);

                chart_per_core_files(&all_cpu_charts[1], all_cpu_charts_size - 1, CPU_FREQ_INDEX, st_scaling_cur_freq, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
                rrdset_done(st_scaling_cur_freq);
            }
        }
    }

    // --------------------------------------------------------------------

    static struct per_core_cpuidle_chart *cpuidle_charts = NULL;
    size_t schedstat_cores_found = 0;

    if(likely(do_cpuidle != CONFIG_BOOLEAN_NO && !read_schedstat(schedstat_filename, &cpuidle_charts, &schedstat_cores_found))) {
        int cpu_states_updated = 0;
        size_t core, state;


        // proc.plugin runs on Linux systems only. Multi-platform compatibility is not needed here,
        // so bare pthread functions are used to avoid unneeded overheads.
        for(core = 0; core < schedstat_cores_found; core++) {
            if(unlikely(!(cpuidle_charts[core].active_time - cpuidle_charts[core].last_active_time))) {
                pthread_t thread;

                if(unlikely(pthread_create(&thread, NULL, wake_cpu_thread, (void *)&core)))
                    error("Cannot create wake_cpu_thread");
                else if(unlikely(pthread_join(thread, NULL)))
                    error("Cannot join wake_cpu_thread");
                cpu_states_updated = 1;
            }
        }

        if(unlikely(!cpu_states_updated || !read_schedstat(schedstat_filename, &cpuidle_charts, &schedstat_cores_found))) {
            for(core = 0; core < schedstat_cores_found; core++) {
                cpuidle_charts[core].last_active_time = cpuidle_charts[core].active_time;

                int r = read_cpuidle_states(cpuidle_name_filename, cpuidle_time_filename, cpuidle_charts, core);
                if(likely(r != -1 && (do_cpuidle == CONFIG_BOOLEAN_YES || r > 0))) {
                    do_cpuidle = CONFIG_BOOLEAN_YES;

                    char cpuidle_chart_id[RRD_ID_LENGTH_MAX + 1];
                    snprintfz(cpuidle_chart_id, RRD_ID_LENGTH_MAX, "cpu%zu_cpuidle", core);

                    if(unlikely(!cpuidle_charts[core].st)) {
                        cpuidle_charts[core].st = rrdset_create_localhost(
                                "cpu"
                                , cpuidle_chart_id
                                , NULL
                                , "cpuidle"
                                , "cpuidle.cpuidle"
                                , "C-state residency time"
                                , "percentage"
                                , PLUGIN_PROC_NAME
                                , PLUGIN_PROC_MODULE_STAT_NAME
                                , NETDATA_CHART_PRIO_CPUIDLE + core
                                , update_every
                                , RRDSET_TYPE_STACKED
                        );

                        char cpuidle_dim_id[RRD_ID_LENGTH_MAX + 1];
                        snprintfz(cpuidle_dim_id, RRD_ID_LENGTH_MAX, "cpu%zu_active_time", core);
                        cpuidle_charts[core].active_time_rd = rrddim_add(cpuidle_charts[core].st, cpuidle_dim_id, "C0 (active)", 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                        for(state = 0; state < cpuidle_charts[core].cpuidle_state_len; state++) {
                            snprintfz(cpuidle_dim_id, RRD_ID_LENGTH_MAX, "cpu%zu_cpuidle_state%zu_time", core, state);
                            cpuidle_charts[core].cpuidle_state[state].rd = rrddim_add(cpuidle_charts[core].st, cpuidle_dim_id,
                                                                                      cpuidle_charts[core].cpuidle_state[state].name,
                                                                                      1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
                        }
                    }
                    else
                        rrdset_next(cpuidle_charts[core].st);

                    rrddim_set_by_pointer(cpuidle_charts[core].st, cpuidle_charts[core].active_time_rd, cpuidle_charts[core].active_time);
                    for(state = 0; state < cpuidle_charts[core].cpuidle_state_len; state++) {
                        rrddim_set_by_pointer(cpuidle_charts[core].st, cpuidle_charts[core].cpuidle_state[state].rd, cpuidle_charts[core].cpuidle_state[state].value);
                    }
                    rrdset_done(cpuidle_charts[core].st);
                }
            }
        }
    }

    if(cpus_var)
        rrdvar_custom_host_variable_set(localhost, cpus_var, cores_found);

    return 0;
}
コード例 #14
0
//*****************************************************************************
//
// Handles CDC driver notifications related to the receive channel (data from
// the USB host).
//
// \param ulCBData is the client-supplied callback data value for this channel.
// \param ulEvent identifies the event we are being notified about.
// \param ulMsgValue is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the CDC driver to notify us of any events
// related to operation of the receive data channel (the OUT channel carrying
// data from the USB host).
//
// \return The return value is event-specific.
//
//*****************************************************************************
unsigned long
USB_RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,
          void *pvMsgData)
{
    unsigned long ulCount;
    unsigned char ucCharArr[USB_RX_LENGTH];
    unsigned char ucBytesRead;
    unsigned char nextByte;
    //
    // Which event are we being sent?
    //
    switch(ulEvent)
    {
        //
        // A new packet has been received.
        //
        case USB_EVENT_RX_AVAILABLE:
        {
        	//Increment Packet Counter
        	g_ulUSBRxCount++;

        	if(g_ulReceiveMode == REC_MODE_STREAM){
				//Buffer reading handled in stream interrupt
				#ifdef __DEBUG__
					UARTprintf("\nUSB Stream Mode Rx Event");
				#ifdef __DEBUG_TRACEBACK__
							UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
				#endif
				#endif
        	}

        	else{
        		//allocate packet array
        		ucBytesRead = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, ucCharArr, USB_RX_LENGTH-1);
        		ucCharArr[ucBytesRead] = NULL; //Null terminate string
				#ifdef __DEBUG__
					UARTprintf("\nUSB Buffer Dump (length = %d):\n%s\n",ucBytesRead, ucCharArr);
				#endif
				for(ulCount=0;ulCount<ucBytesRead;ulCount++){
					nextByte = ucCharArr[ulCount];
					#ifdef __DEBUG__
					#ifdef __DEBUG_USB_EVERYCHAR__
						UARTprintf("\nUSB nextByte = %c, ",nextByte);
					#ifdef __DEBUG_TRACEBACK__
						UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
					#endif
					#endif
					#endif

					//Ignore non-printing and whitespace characters
					if(nextByte <= ' '){
						#ifdef __DEBUG__
							UARTprintf("\nUSB Ignored Character = %c, ",nextByte);
						#ifdef __DEBUG_TRACEBACK__
							UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
						#endif
						#endif
						continue;
					}


					if(nextByte == '#'){
						if(g_ucReadMode == COMMENT){
							g_ucReadMode = WAITING;
							g_ulCharIndex = 0;
							g_ulParamIndex = 0;
							#ifdef __DEBUG__
								UARTprintf("\ng_ucReadMode = FUNCTION");
								#ifdef __DEBUG_TRACEBACK__
									UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
								#endif
							#endif
							continue;
						}
						else{
							g_ucReadMode = COMMENT;
							#ifdef __DEBUG__
								UARTprintf("\ng_ucReadMode = COMMENT");
								#ifdef __DEBUG_TRACEBACK__
									UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
								#endif
							#endif
							continue;
						}
					}

					switch(g_ucReadMode){
					case WAITING:
							if(nextByte < 'A' || nextByte > 'Z'){
								continue;
							}
							else{
								g_ucReadMode = FUNCTION;
							}
							//DON'T PUT A BREAK HERE!
					case FUNCTION:
						if(nextByte == '('){ //end of Function section
							g_strAssembler[g_ulCharIndex] = NULL; //Terminate string
							g_strFuncName = malloc(strlen((char *)g_strAssembler) + 1); //allocate memory for function name
							strcpy((char *)g_strFuncName,(char *)g_strAssembler); //Copy function name
							g_ulCharIndex = 0;
							g_ucReadMode = PARAMETER;
							#ifdef __DEBUG__
							#ifdef __DEBUG_USB_EVERYCHAR__
								UARTprintf("\ng_ucReadMode = PARAMETER");
								#ifdef __DEBUG_TRACEBACK__
									UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
								#endif
							#endif
							#endif
							continue;
						}
						else{
							g_strAssembler[g_ulCharIndex] = nextByte;
							g_ulCharIndex ++;
							if(g_ulCharIndex > MAX_FUNC_LENGTH){ //Error Checking
								g_ucReadMode = WAITING;
								g_ulCharIndex = 0;
								g_ulParamIndex = 0;
								#ifdef __DEBUG__
									UARTprintf("\nFUNCTION LENGTH EXCEEDED, g_ucReadMode = WAITING");
									#ifdef __DEBUG_TRACEBACK__
										UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
									#endif
								#endif
								continue;
							}
						}
						break;
					case PARAMETER:
						if(nextByte == ')'){ //end of input
							g_strAssembler[g_ulCharIndex] = NULL;
							g_ulParams[g_ulParamIndex] = str2ul(g_strAssembler);

							if(g_ulParamIndex > 0){
								g_ulParamIndex ++;
							}

							parseUSB(g_strFuncName,g_ulParams,g_ulParamIndex);
							g_ucReadMode = WAITING;
							g_ulCharIndex = 0;
							g_ulParamIndex = 0;
							free(g_strFuncName);
							#ifdef __DEBUG__
							#ifdef __DEBUG_USB_EVERYCHAR__
								UARTprintf("\ng_ucReadMode = WAITING");
								#ifdef __DEBUG_TRACEBACK__
									UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
								#endif
							#endif
							#endif
							continue;
						}
						else{
							if(nextByte == ' ' || nextByte == ','){ //next parameter
							g_strAssembler[g_ulCharIndex] = NULL;
							g_ulParams[g_ulParamIndex] = str2ul(g_strAssembler);
							g_ulParamIndex ++;
							g_ulCharIndex = 0;
							continue;
							}
							else{
								g_strAssembler[g_ulCharIndex] = nextByte;
								g_ulCharIndex ++;
								if(g_ulCharIndex > MAX_PARAM_LENGTH){ //Error Checking
									g_ucReadMode = WAITING;
									g_ulCharIndex = 0;
									g_ulParamIndex = 0;
									#ifdef __DEBUG__
									#ifdef __DEBUG_USB_EVERYCHAR__
										UARTprintf("\nPARAMEtER LENGTH EXCEEDED, g_ucReadMode = WAITING");
										#ifdef __DEBUG_TRACEBACK__
											UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
										#endif
									#endif
									#endif
									continue;
								}
							}
						}

						break;
					default:
						break;
					}
				}
			}
        }
        // We are being asked how much unprocessed data we have still to
        // process. We return 0 if the UART is currently idle or 1 if it is
        // in the process of transmitting something. The actual number of
        // bytes in the UART FIFO is not important here, merely whether or
        // not everything previously sent to us has been transmitted.
        //
        case USB_EVENT_DATA_REMAINING:
        {
            //
            // For now just return 0
            //
			#ifdef __DEBUG__
				UARTprintf("\nUSB_EVENT_DATA_REMAINING");
				#ifdef __DEBUG_TRACEBACK__
					UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
				#endif
			#endif
        	ulCount = 0;
            return(ulCount);
        }

        //
        // We are being asked to provide a buffer into which the next packet
        // can be read. We do not support this mode of receiving data so let
        // the driver know by returning 0. The CDC driver should not be sending
        // this message but this is included just for illustration and
        // completeness.
        //
        case USB_EVENT_REQUEST_BUFFER:
        {
			#ifdef __DEBUG__
				UARTprintf("\nUSB_EVENT_REQUEST_BUFFER");
				#ifdef __DEBUG_TRACEBACK__
					UARTprintf(" File: %s Line: %d", __FILE__,__LINE__);
				#endif
			#endif
            return(0);
        }

        //
        // We don't expect to receive any other events.  Ignore any that show
        // up in a release build or hang in a debug build.
        //
        default:
        	return(0);
    }
}
コード例 #15
0
int main(int argc, char **argv)
{
	static const char OPTIONS[] = "hvlpsjr:g:f::Ww:m:d:e:b:t:o:a:c:O:";
	__sighandler_t sigint_original;
	char * const *file_names = NULL;
	size_t n_files = 0;
	const char *waveform_id_str = NULL;
	int waveform_id;
	int do_enumerate_waveforms = 0;
	int do_log_info = 0;
	int do_wait_power_off = 0;
	int do_synchro = 0;
	int do_infinite_loop = 0;
	int cfa = -1;
	int do_auto_rotate = 0;
	int rotation_angle = -1;
	unsigned long pause_ms = 2000;
	const char *mode = NULL;
	const char *fbdev = NULL;
	const char *epdev = NULL;
	const char *background = NULL;
	struct plep_point offset = { 0, 0 };
	enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE;
	enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE;
	struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } };
	const char *doc_type = NULL;
	const char *conf_file = NULL;
	struct plep *plep;
	struct pldraw *pldraw;
	int c;
	int ret;

	while ((c = getopt(argc, argv, OPTIONS)) != -1) {
		switch (c) {
		case 'h':
			print_usage();
			exit(EXIT_SUCCESS);
			break;

		case 'v':
			printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION,
			       DESCRIPTION, COPYRIGHT, LICENSE);
			exit(EXIT_SUCCESS);
			break;

		case 'l':
			do_log_info = 1;
			break;

		case 'p':
			do_wait_power_off = 1;
			break;

		case 's':
			do_synchro = 1;
			break;

		case 'j':
			do_infinite_loop = 1;
			break;

		case 'r':
			if (!strcmp(optarg, "auto")) {
				do_auto_rotate = 1;
			} else {
				unsigned long raw_angle;

				if (str2ul(optarg, &raw_angle) < 0) {
					LOG("failed to parse rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				if ((raw_angle > 270) || (raw_angle % 90)) {
					LOG("invalid rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				rotation_angle = raw_angle;
			}
			break;

		case 'g':
			if (str2ul(optarg, &pause_ms) < 0) {
				LOG("failed to parse pause duration");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'f':
			if (optarg == NULL) {
				cfa = PLDRAW_CFA_GR_BW;
			} else {
				cfa = pldraw_get_cfa_id(optarg);

				if (cfa < 0) {
					LOG("Invalid CFA identifier: %s",
					    optarg);
					print_usage();
					exit(EXIT_FAILURE);
				}
			}
			break;

		case 'W':
			do_enumerate_waveforms = 1;
			break;

		case 'w':
			waveform_id_str = optarg;
			break;

		case 'm':
			mode = optarg;
			break;

		case 'd':
			fbdev = optarg;
			break;

		case 'e':
			epdev = optarg;
			break;

		case 'b':
			background = optarg;
			break;

		case 't':
			doc_type = optarg;
			break;

		case 'o':
			if (parse_offset(&offset, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'a':
			if (parse_alignment(&align_h, &align_v, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'c':
			if (parse_crop(&crop, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'O':
			conf_file = optarg;
			if (access(conf_file, F_OK)) {
				LOG_ERRNO("Configuration file");
				exit(EXIT_FAILURE);
			}
			break;

		case '?':
		default:
			LOG("Invalid arguments");
			print_usage();
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (optind < argc) {
		file_names = &argv[optind];
		n_files = argc - optind;
	}

	LOG("%s v%s", APP_NAME, VERSION);

	plep = plep_init(epdev, mode, conf_file);

	if (plep == NULL) {
		LOG("failed to initialise ePDC");
		goto error_plep;
	}

	pldraw = pldraw_init(fbdev, conf_file);

	if (pldraw == NULL) {
		LOG("failed to initialise pldraw");
		goto error_pldraw;
	}

	pldraw_set_plep(pldraw, plep);

	waveform_id = plep_get_wfid(plep, waveform_id_str);

	if (waveform_id < 0) {
		LOG("Invalid waveform path: %s", waveform_id_str);
		goto error_pldraw;
	}

	if (cfa >= 0)
		pldraw_set_cfa(pldraw, cfa);
	else
		cfa = pldraw_get_cfa(pldraw);

	if (cfa != PLDRAW_CFA_NONE)
		LOG("CFA: %s", pldraw_cfa_name[cfa]);

	if (rotation_angle < 0)
		rotation_angle = pldraw_get_rotation(pldraw);

	if (rotation_angle)
		LOG("rotation: %d", rotation_angle);

	if (do_log_info)
		pldraw_log_info(pldraw);

	sigint_original = signal(SIGINT, sigint_abort);

	if (do_enumerate_waveforms) {
		ret = enumerate_waveforms(plep);
	} else {
		struct epdoc_opt opt;

		plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro);

		if (do_wait_power_off)
			plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1);

		opt.do_auto_rotate = do_auto_rotate;
		opt.rotation_angle = rotation_angle;
		opt.wfid = waveform_id;
		opt.offset.x = offset.x;
		opt.offset.y = offset.y;
		opt.align_h = align_h;
		opt.align_v = align_v;
		memcpy(&opt.crop, &crop, sizeof opt.crop);
		opt.doc_type = doc_type;

		ret = show_contents(pldraw, file_names, n_files, &opt,
				    pause_ms, do_infinite_loop, background);
	}

	signal(SIGINT, sigint_original);
	pldraw_free(pldraw);
	plep_free(plep);

	exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS);

error_pldraw:
	plep_free(plep);
error_plep:
	exit(EXIT_FAILURE);
}