Beispiel #1
0
int main(int argc, char *argv[])
{
	int ret, i, action = -1;
	char config_file[PATH_MAX] = {};
	int type = 0;
	struct utsname u;
	int version, major, minor;

	/* Check kernel version: it must be >= 2.6.18 */
	if (uname(&u) == -1) {
		dlog(LOG_ERR, "Can't retrieve kernel version via uname()");
		exit(EXIT_FAILURE);
	}
	sscanf(u.release, "%d.%d.%d", &version, &major, &minor);
	if (version < 2 && major < 6 && minor < 18) {
		dlog(LOG_ERR, "Linux kernel version must be >= 2.6.18");
		exit(EXIT_FAILURE);
	}

	for (i=1; i<argc; i++) {
		switch(argv[i][1]) {
		case 'd':
			set_operation_mode(&type, DAEMON, argv);
			CONFIG(running_mode) = DAEMON;
			break;
		case 'c':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_COMMIT, EXP_COMMIT,
						ALL_COMMIT, &action);
			break;
		case 'i':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_INTERNAL,
						EXP_DUMP_INTERNAL,
						CT_DUMP_INTERNAL, &action);
			break;
		case 'e':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_EXTERNAL,
						EXP_DUMP_EXTERNAL,
						CT_DUMP_EXTERNAL, &action);
			break;
		case 'C':
			if (++i < argc) {
				strncpy(config_file, argv[i], PATH_MAX);
				if (strlen(argv[i]) >= PATH_MAX){
					config_file[PATH_MAX-1]='\0';
					dlog(LOG_WARNING, "Path to config file"
					     " to long. Cutting it down to %d"
					     " characters", PATH_MAX);
				}
				break;
			}
			show_usage(argv[0]);
			dlog(LOG_ERR, "Missing config filename");
			break;
		case 'F':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_FLUSH_MASTER,
						EXP_FLUSH_MASTER,
						ALL_FLUSH_MASTER, &action);
			break;
		case 'f':
			set_operation_mode(&type, REQUEST, argv);
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "internal",
					    strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_INT_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "external",
						 strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_EXT_CACHE;
					i++;
				} else {
					dlog(LOG_ERR, "unknown parameter `%s' "
					     "for option `-f'", argv[i + 1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general flushing */
				action = ALL_FLUSH_CACHE;
			}
			break;
		case 'R':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_RESYNC_MASTER,
						EXP_RESYNC_MASTER,
						ALL_RESYNC_MASTER, &action);
			break;
		case 'B':
			set_operation_mode(&type, REQUEST, argv);
			action = SEND_BULK;
			break;
		case 't':
			set_operation_mode(&type, REQUEST, argv);
			action = RESET_TIMERS;
			break;
		case 'k':
			set_operation_mode(&type, REQUEST, argv);
			action = KILL;
			break;
		case 's':
			set_operation_mode(&type, REQUEST, argv);
			/* we've got a parameter */
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "network",
					    strlen(argv[i+1])) == 0) {
					action = STATS_NETWORK;
					i++;
				} else if (strncmp(argv[i+1], "cache",
						 strlen(argv[i+1])) == 0) {
					action = STATS_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "runtime",
						 strlen(argv[i+1])) == 0) {
					action = STATS_RUNTIME;
					i++;
				} else if (strncmp(argv[i+1], "multicast",
						 strlen(argv[i+1])) == 0) {
					dlog(LOG_WARNING, "use `link' "
					     "instead of `multicast' as "
					     "parameter.");
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "link",
						 strlen(argv[i+1])) == 0) {
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "rsqueue",
						strlen(argv[i+1])) == 0) {
					action = STATS_RSQUEUE;
					i++;
				} else if (strncmp(argv[i+1], "process",
						 strlen(argv[i+1])) == 0) {
					action = STATS_PROCESS;
					i++;
				} else if (strncmp(argv[i+1], "queue",
						strlen(argv[i+1])) == 0) {
					action = STATS_QUEUE;
					i++;
				} else if (strncmp(argv[i+1], "ct",
						strlen(argv[i+1])) == 0) {
					action = STATS;
					i++;
				} else if (strncmp(argv[i+1], "expect",
						strlen(argv[i+1])) == 0) {
					action = EXP_STATS;
					i++;
				} else {
					dlog(LOG_ERR, "unknown parameter `%s' "
					     "for option `-s'", argv[i + 1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general statistics */
				action = STATS;
			}
			break;
		case 'S':
			dlog(LOG_WARNING,"-S option is obsolete. Ignoring.");
			break;
		case 'n':
			set_operation_mode(&type, REQUEST, argv);
			action = REQUEST_DUMP;
			break;
		case 'x':
			if (action == CT_DUMP_INTERNAL)
				action = CT_DUMP_INT_XML;
			else if (action == CT_DUMP_EXTERNAL)
				action = CT_DUMP_EXT_XML;
			else if (action == EXP_DUMP_INTERNAL)
				action = EXP_DUMP_INT_XML;
			else if (action == EXP_DUMP_EXTERNAL)
				action = EXP_DUMP_EXT_XML;
			else {
				show_usage(argv[0]);
				dlog(LOG_ERR,  "Invalid parameters");
				exit(EXIT_FAILURE);

			}
			break;
		case 'v':
			show_version();
			exit(EXIT_SUCCESS);
		case 'h':
			show_usage(argv[0]);
			exit(EXIT_SUCCESS);
		default:
			show_usage(argv[0]);
			dlog(LOG_ERR, "Unknown option: %s", argv[i]);
			return 0;
			break;
		}
	}

	if (!config_file[0])
		strcpy(config_file, DEFAULT_CONFIGFILE);

	umask(0177);

	if ((ret = init_config(config_file)) == -1) {
		dlog(LOG_ERR, "can't open config file `%s'", config_file);
		exit(EXIT_FAILURE);
	}

	if (type == REQUEST) {
		if (do_local_request(action, &conf.local, local_step) == -1) {
			dlog(LOG_ERR, "can't connect: is conntrackd "
			     "running? appropriate permissions?");
			exit(EXIT_FAILURE);
		}
		exit(EXIT_SUCCESS);
	}

	/*
	 * Setting up logging
	 */
	if (init_log() == -1)
		exit(EXIT_FAILURE);

	/*
	 * lock file
	 */
	ret = open(CONFIG(lockfile), O_CREAT | O_EXCL | O_TRUNC, 0600);
	if (ret == -1) {
		dlog(LOG_ERR, "lockfile `%s' exists, perhaps conntrackd"
		     " already running?", CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}
	close(ret);

	/*
	 * Setting process priority and scheduler
	 */
	set_nice_value(CONFIG(nice));

	if (CONFIG(sched).type != SCHED_OTHER) {
		struct sched_param schedparam = {
			.sched_priority = CONFIG(sched).prio,
		};

		ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam);
		if (ret == -1) {
			dlog(LOG_ERR, "scheduler configuration failed: %s",
			     strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/*
	 * initialization process
	 */

	if (init() == -1) {
		dlog(LOG_ERR, "conntrackd cannot start, please review your "
		     "configuration");
		close_log();
		unlink(CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}

	do_chdir("/");
	close(STDIN_FILENO);

	sd_ct_watchdog_init();

	/* Daemonize conntrackd */
	if (type == DAEMON) {
		pid_t pid;

		if ((pid = fork()) == -1) {
			dlog(LOG_ERR, "fork has failed: %s", strerror(errno));
			exit(EXIT_FAILURE);
		} else if (pid) {
			sd_ct_mainpid(pid);
			exit(EXIT_SUCCESS);
		}

		setsid();

		close(STDOUT_FILENO);
		close(STDERR_FILENO);

		dlog(LOG_NOTICE, "-- starting in daemon mode --");
	} else
		dlog(LOG_NOTICE, "-- starting in console mode --");

	sd_ct_init();

	/*
	 * run main process
	 */
	select_main_loop();
	return 0;
}
Beispiel #2
0
int
main(int argc, char **argv)
{
    int i, len;
    double eval, clk;
    long long ncycles_ref, counter;
    double eptime;
    double add_delay;
    struct cfg cf;
    char buf[256];
    struct recfilter loop_error;
    struct PFD phase_detector;
    useconds_t usleep_time;
    struct sched_param sparam;
#if RTPP_DEBUG
    double sleep_time, filter_lastval;
#endif
    memset(&cf, 0, sizeof(cf));

    cf.stable = malloc(sizeof(struct rtpp_cfg_stable));
    if (cf.stable == NULL) {
         err(1, "can't allocate memory for the struct rtpp_cfg_stable");
         /* NOTREACHED */
    }
    memset(cf.stable, '\0', sizeof(struct rtpp_cfg_stable));
    cf.stable->ctrl_socks = malloc(sizeof(struct rtpp_list));
    if (cf.stable->ctrl_socks == NULL) {
         err(1, "can't allocate memory for the struct rtpp_cfg_stable");
         /* NOTREACHED */
    }
    memset(cf.stable->ctrl_socks, '\0', sizeof(struct rtpp_list));
    RTPP_LIST_RESET(cf.stable->ctrl_socks);    

    init_config(&cf, argc, argv);

    seedrandom();

    cf.stable->sessions_ht = rtpp_hash_table_ctor();
    if (cf.stable->sessions_ht == NULL) {
        err(1, "can't allocate memory for the hash table");
         /* NOTREACHED */
    }
    cf.stable->rtpp_stats = rtpp_stats_ctor();
    if (cf.stable->rtpp_stats == NULL) {
        err(1, "can't allocate memory for the stats data");
         /* NOTREACHED */
    }
    init_port_table(&cf);

    if (rtpp_controlfd_init(&cf) != 0) {
        err(1, "can't inilialize control socket%s",
          cf.stable->ctrl_socks->len > 1 ? "s" : "");
    }

    if (cf.stable->nodaemon == 0) {
	if (rtpp_daemon(0, 0) == -1)
	    err(1, "can't switch into daemon mode");
	    /* NOTREACHED */
    }

    if (rtpp_notify_init() != 0)
        errx(1, "can't start notification thread");

    cf.stable->glog = rtpp_log_open(cf.stable, "rtpproxy", NULL, LF_REOPEN);
    rtpp_log_setlevel(cf.stable->glog, cf.stable->log_level);
    _sig_cf = &cf;
    atexit(ehandler);
    rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog, "rtpproxy started, pid %d", getpid());

    i = open(cf.stable->pid_file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
    if (i >= 0) {
	len = sprintf(buf, "%u\n", (unsigned int)getpid());
	write(i, buf, len);
	close(i);
    } else {
	rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "can't open pidfile for writing");
    }

    signal(SIGHUP, sighup);
    signal(SIGINT, fatsignal);
    signal(SIGKILL, fatsignal);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGTERM, fatsignal);
    signal(SIGXCPU, fatsignal);
    signal(SIGXFSZ, fatsignal);
    signal(SIGVTALRM, fatsignal);
    signal(SIGPROF, fatsignal);
    signal(SIGUSR1, fatsignal);
    signal(SIGUSR2, fatsignal);

    if (cf.stable->sched_policy != SCHED_OTHER) {
        sparam.sched_priority = sched_get_priority_max(cf.stable->sched_policy);
        if (sched_setscheduler(0, cf.stable->sched_policy, &sparam) == -1) {
            rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "sched_setscheduler(SCHED_%s, %d)",
              (cf.stable->sched_policy == SCHED_FIFO) ? "FIFO" : "RR", sparam.sched_priority);
        }
    }

    if (cf.stable->run_uname != NULL || cf.stable->run_gname != NULL) {
	if (drop_privileges(&cf) != 0) {
	    rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog,
	      "can't switch to requested user/group");
	    exit(1);
	}
    }
    set_rlimits(&cf);

    cf.sessinfo.sessions[0] = NULL;
    cf.sessinfo.nsessions = 0;
    cf.rtp_nsessions = 0;

    rtpp_command_async_init(&cf);
    rtpp_proc_async_init(&cf);

    counter = 0;
    recfilter_init(&loop_error, 0.96, 0.0, 0);
    PFD_init(&phase_detector, 2.0);
#ifdef HAVE_SYSTEMD_SD_DAEMON_H
    sd_notify(0, "READY=1");
#endif
#ifdef RTPP_CHECK_LEAKS
    rtpp_memdeb_setbaseln();
#endif
    for (;;) {
	eptime = getdtime();

        clk = (eptime + cf.stable->sched_offset) * cf.stable->target_pfreq;

        ncycles_ref = llrint(clk);

        eval = PFD_get_error(&phase_detector, clk);

#if RTPP_DEBUG
        filter_lastval = loop_error.lastval;
#endif

        if (eval != 0.0) {
            recfilter_apply(&loop_error, sigmoid(eval));
        }

#if RTPP_DEBUG
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) {
          rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld ncycles %f raw error1 %f, filter lastval %f, filter nextval %f",
            counter, clk, eval, filter_lastval, loop_error.lastval);
        }
#endif
        add_delay = freqoff_to_period(cf.stable->target_pfreq, 1.0, loop_error.lastval);
        usleep_time = add_delay * 1000000.0;
#if RTPP_DEBUG
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) {
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld filter lastval %f, filter nextval %f, error %f",
              counter, filter_lastval, loop_error.lastval, sigmoid(eval));
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld extra sleeping time %llu", counter, usleep_time);
        }
        sleep_time = getdtime();
#endif
        rtpp_proc_async_wakeup(cf.stable->rtpp_proc_cf, counter, ncycles_ref);
        usleep(usleep_time);
#if RTPP_DEBUG
        sleep_time = getdtime() - sleep_time;
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000 || sleep_time > add_delay * 2.0) {
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld sleeping time required %llu sleeping time actual %f, CSV: %f,%f,%f", \
              counter, usleep_time, sleep_time, (double)counter / cf.stable->target_pfreq, ((double)usleep_time) / 1000.0, sleep_time * 1000.0);
        }
#endif
        counter += 1;
        if (cf.stable->slowshutdown != 0) {
            pthread_mutex_lock(&cf.sessinfo.lock);
            if (cf.sessinfo.nsessions == 0) {
                /* The below unlock is not necessary, but does not hurt either */
                pthread_mutex_unlock(&cf.sessinfo.lock);
                rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog,
                  "deorbiting-burn sequence completed, exiting");
                break;
            }
            pthread_mutex_unlock(&cf.sessinfo.lock);
        }
    }

#ifdef HAVE_SYSTEMD_SD_DAEMON_H
    sd_notify(0, "STATUS=Exited");
#endif

#ifdef RTPP_CHECK_LEAKS
    exit(rtpp_memdeb_dumpstats(&cf) == 0 ? 0 : 1);
#else
    exit(0);
#endif
}
Beispiel #3
0
int main(int argc, char* argv[]){

    long i;
    long iterations = DEFAULT_ITERATIONS;
    struct sched_param param;
    int policy, num_processes, status;
    double x, y;
    double inCircle = 0.0;
    double inSquare = 0.0;
    double pCircle = 0.0;
    double piCalc = 0.0;
    pid_t pid, wpid;
    int j = 0;

    int rv;
    int inputFD;
    int outputFD;
    char inputFilename[MAXFILENAMELENGTH];
    char outputFilename[MAXFILENAMELENGTH];
    char outputFilenameBase[MAXFILENAMELENGTH];

    ssize_t transfersize = DEFAULT_TRANSFERSIZE;
    ssize_t blocksize = DEFAULT_BLOCKSIZE; 
    char* transferBuffer = NULL;
    ssize_t buffersize;

    ssize_t bytesRead = 0;
    ssize_t totalBytesRead = 0;
    int totalReads = 0;
    ssize_t bytesWritten = 0;
    ssize_t totalBytesWritten = 0;
    int totalWrites = 0;
    int inputFileResets = 0;

    /* Set input and output filename and size */
    strncpy(inputFilename, DEFAULT_INPUTFILENAME, MAXFILENAMELENGTH);
    strncpy(outputFilenameBase, DEFAULT_OUTPUTFILENAMEBASE, MAXFILENAMELENGTH);

    /* Set default policy if not supplied */
    if(argc < 2){
        policy = SCHED_OTHER;
    }

    /* Set default number of processes */
    if(argc < 3){
        num_processes = LOW;
    }
    /* Set policy if supplied */
    if(argc > 1){
        if(!strcmp(argv[1], "SCHED_OTHER")){
            policy = SCHED_OTHER;
        }
        else if(!strcmp(argv[1], "SCHED_FIFO")){
            policy = SCHED_FIFO;
        }
        else if(!strcmp(argv[1], "SCHED_RR")){
            policy = SCHED_RR;
        }
        else{
            fprintf(stderr, "Unhandeled scheduling policy\n");
            exit(EXIT_FAILURE);
        }
    }

    /* Set # Of Processes */
    if(argc > 2){
        if(!strcmp(argv[2], "LOW")){
            num_processes = LOW;
        }
        else if(!strcmp(argv[2], "MEDIUM")){
            num_processes = MEDIUM;
        }
        else if(!strcmp(argv[2], "HIGH")){
            num_processes = HIGH;
        }
        else{
            fprintf(stderr, "Unhandeled number of processes\n");
            exit(EXIT_FAILURE);
        }
    }
    
    /* Set process to max prioty for given scheduler */
    param.sched_priority = sched_get_priority_max(policy);
    
    /* Set new scheduler policy */
    fprintf(stdout, "Current Scheduling Policy: %d\n", sched_getscheduler(0));
    fprintf(stdout, "Setting Scheduling Policy to: %d\n", policy);
    if(sched_setscheduler(0, policy, &param)){
    perror("Error setting scheduler policy");
    exit(EXIT_FAILURE);
    }
    fprintf(stdout, "New Scheduling Policy: %d\n", sched_getscheduler(0));

    /* Fork number of processes specified */
    printf("Number of processes to be forked %d \n", num_processes);
    for(i = 0; i < num_processes; i++){
        if((pid = fork())==-1){
            fprintf(stderr, "Error Forking Child Process");
            exit(EXIT_FAILURE); 
        } 
        if(pid == 0){ 
            /* Calculate pi using statistical methode across all iterations*/
            for(i=0; i<iterations; i++){
            x = (random() % (RADIUS * 2)) - RADIUS;
            y = (random() % (RADIUS * 2)) - RADIUS;
            if(zeroDist(x,y) < RADIUS){
                inCircle++;
            }
            inSquare++;
            }

            /* Finish calculation */
            pCircle = inCircle/inSquare;
            piCalc = pCircle * 4.0;

            /* Print result */
            fprintf(stdout, "pi = %f\n", piCalc);
        
            /* Confirm blocksize is multiple of and less than transfersize*/
            if(blocksize > transfersize){
            fprintf(stderr, "blocksize can not exceed transfersize\n");
            exit(EXIT_FAILURE);
            }
            if(transfersize % blocksize){
            fprintf(stderr, "blocksize must be multiple of transfersize\n");
            exit(EXIT_FAILURE);
            }

            /* Allocate buffer space */
            buffersize = blocksize;
            if(!(transferBuffer = malloc(buffersize*sizeof(*transferBuffer)))){
            perror("Failed to allocate transfer buffer");
            exit(EXIT_FAILURE);
            }
            
            /* Open Input File Descriptor in Read Only mode */
            if((inputFD = open(inputFilename, O_RDONLY | O_SYNC)) < 0){
            perror("Failed to open input file");
            exit(EXIT_FAILURE);
            }

            /* Open Output File Descriptor in Write Only mode with standard permissions*/
            rv = snprintf(outputFilename, MAXFILENAMELENGTH, "%s-%d",
                  outputFilenameBase, getpid());    
            if(rv > MAXFILENAMELENGTH){
            fprintf(stderr, "Output filenmae length exceeds limit of %d characters.\n",
                MAXFILENAMELENGTH);
            exit(EXIT_FAILURE);
            }
            else if(rv < 0){
            perror("Failed to generate output filename");
            exit(EXIT_FAILURE);
            }
            if((outputFD =
            open(outputFilename,
                 O_WRONLY | O_CREAT | O_TRUNC | O_SYNC,
                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)) < 0){
            perror("Failed to open output file");
            exit(EXIT_FAILURE);
            }

            /* Print Status */
            fprintf(stdout, "Reading from %s and writing to %s\n",
                inputFilename, outputFilename);

            /* Read from input file and write to output file*/
            do{
            /* Read transfersize bytes from input file*/
            bytesRead = read(inputFD, transferBuffer, buffersize);
            if(bytesRead < 0){
                perror("Error reading input file");
                exit(EXIT_FAILURE);
            }
            else{
                totalBytesRead += bytesRead;
                totalReads++;
            }
            
            /* If all bytes were read, write to output file*/
            if(bytesRead == blocksize){
                bytesWritten = write(outputFD, transferBuffer, bytesRead);
                if(bytesWritten < 0){
                perror("Error writing output file");
                exit(EXIT_FAILURE);
                }
                else{
                totalBytesWritten += bytesWritten;
                totalWrites++;
                }
            }
            /* Otherwise assume we have reached the end of the input file and reset */
            else{
                if(lseek(inputFD, 0, SEEK_SET)){
                perror("Error resetting to beginning of file");
                exit(EXIT_FAILURE);
                }
                inputFileResets++;
            }
            
            }while(totalBytesWritten < transfersize);

            /* Output some possibly helpfull info to make it seem like we were doing stuff */
            fprintf(stdout, "Read:    %zd bytes in %d reads\n",
                totalBytesRead, totalReads);
            fprintf(stdout, "Written: %zd bytes in %d writes\n",
                totalBytesWritten, totalWrites);
            fprintf(stdout, "Read input file in %d pass%s\n",
                (inputFileResets + 1), (inputFileResets ? "es" : ""));
            fprintf(stdout, "Processed %zd bytes in blocks of %zd bytes\n",
                transfersize, blocksize);
            
            /* Free Buffer */
            free(transferBuffer);

            /* Close Output File Descriptor */
            if(close(outputFD)){
            perror("Failed to close output file");
            exit(EXIT_FAILURE);
            }

            /* Close Input File Descriptor */
            if(close(inputFD)){
            perror("Failed to close input file");
            exit(EXIT_FAILURE);
            }
            

            exit(0);
        }
    }
    /* Parent Process Waits For All Of the children to terminate */
    while((wpid = wait(&status)) > 0){
        if(WIFEXITED(status)){ 
        printf("Exit status of child process %d was normal \n", wpid);
        j++;
        }
    }
    printf("Total # of Processes terminated was %d\n", j);
    return EXIT_SUCCESS;  
}
/*****************************************************************************
 Function   : VOS_CreateTask
 Description: create task with default task mode:
              VOS_T_PREEMPT | VOS_T_NO_TSLICE | VOS_T_SUPV
 Input      : puchName              -- name identify task
              pfnFunc               -- task entry function
              ulPriority            -- task priority
              ulStackSize           -- task stack size
              aulArgs[VOS_TARG_NUM] -- arguments for task
 Output     : pulTaskID             -- task id allocated by dopra
 Return     : result of VOS_CreateTaskEx
 *****************************************************************************/
VOS_UINT32 VOS_CreateTask( VOS_CHAR * puchName,
                           VOS_UINT32 * pulTaskID,
                           VOS_TASK_ENTRY_TYPE pfnFunc,
                           VOS_UINT32 ulPriority,
                           VOS_UINT32 ulStackSize,
                           VOS_UINT32 aulArgs[VOS_TARG_NUM] )
{
    int             i;
    VOS_UINT32      iTid;
//    pid_t           ThreadID;
    VOS_CHAR        default_name[8] = {0};
    VOS_UCHAR       value;
//    VOS_UINT32      ulOsTaskPriority;
//    VOS_UINT32      ulMode;
    VOS_INT_PTR          lFuncAddr;
    struct task_struct  *tsk;

    struct sched_param  param;

    iTid = VOS_TaskCtrlBlkGet();
    if( iTid == (VOS_UINT32)VOS_TASK_CTRL_BLK_NULL )
    {
		VOS_TaskPrintCtrlBlkInfo();

        lFuncAddr = (VOS_INT_PTR)pfnFunc;

        DRV_SYSTEM_ERROR(OSA_ALLOC_TASK_CONTROL_ERROR, (VOS_INT)vos_TaskCtrlBlkNumber, (VOS_INT)lFuncAddr, VOS_NULL_PTR, 0);

        VOS_SetErrorNo(VOS_ERRNO_TASK_CREATE_NOFREETCB);
        return( VOS_ERRNO_TASK_CREATE_NOFREETCB );
    }

    /* caller not use name asign a default name */
    if ( VOS_NULL_PTR == puchName )
    {
        default_name[0]= 't';
        default_name[1]= 'i';
        default_name[2]= 'd';
        default_name[3] = (VOS_CHAR)(48 + iTid/100);
        value = (VOS_UCHAR)(iTid%100);
        default_name[4] = (VOS_CHAR)(48 + value/10);
        default_name[5] = (VOS_CHAR)(48 + value%10);
        default_name[6]= '\0';
    }

    *pulTaskID = iTid;

    if ( VOS_NULL_PTR != puchName )
    {
        for(i=0; i<VOS_MAX_LENGTH_TASK_NAME; i++)
        {
            vos_TaskCtrlBlk[iTid].Name[i]= puchName[i];
        }
        vos_TaskCtrlBlk[iTid].Name[i-1]  = '\0';
    }
    else
    {
        vos_TaskCtrlBlk[iTid].Name[0] = default_name[0];
        vos_TaskCtrlBlk[iTid].Name[1] = default_name[1];
        vos_TaskCtrlBlk[iTid].Name[2] = default_name[2];
        vos_TaskCtrlBlk[iTid].Name[3] = default_name[3];
        vos_TaskCtrlBlk[iTid].Name[4] = default_name[4];
        vos_TaskCtrlBlk[iTid].Name[5] = default_name[5];
        vos_TaskCtrlBlk[iTid].Name[6] = default_name[6];
    }

    vos_TaskCtrlBlk[iTid].Function   = pfnFunc;
    vos_TaskCtrlBlk[iTid].Priority   = ulPriority;
    vos_TaskCtrlBlk[iTid].StackSize  = ulStackSize;

    for ( i=0; i<VOS_TARG_NUM; i++ )
    {
        vos_TaskCtrlBlk[iTid].Args[i]    = aulArgs[i];
    }

    tsk = kthread_run( (LINUX_START_ROUTINE)VOS_LinuxTaskEntry,
        ( VOS_VOID * )&(vos_TaskCtrlBlk[iTid]), vos_TaskCtrlBlk[iTid].Name);

    if (tsk == VOS_NULL)
    {
        VOS_TaskPrintCtrlBlkInfo();

        DRV_SYSTEM_ERROR(OSA_CREATE_TASK_ERROR, (VOS_INT)(__LINE__), (VOS_INT)iTid, VOS_NULL_PTR, 0);

        VOS_TaskCtrlBlkFree(iTid);
        VOS_SetErrorNo(VOS_ERRNO_TASK_CREATE_OSALCREATEFAIL);
        return( VOS_ERRNO_TASK_CREATE_OSALCREATEFAIL );
    }

    vos_TaskCtrlBlk[iTid].ulLinuxThreadId = tsk->pid;

    param.sched_priority = ulPriority;

    if (VOS_NULL != sched_setscheduler(tsk, SCHED_FIFO, &param))
    {
        vos_printf("\r\nVOS_CreateTask: Creat Task %s ID %d sched_setscheduler Error", puchName, iTid);

        VOS_TaskPrintCtrlBlkInfo();

        DRV_SYSTEM_ERROR(OSA_SET_TASK_PRI_ERROR, (VOS_INT)ulPriority, (VOS_INT)iTid, (VOS_CHAR *)tsk, sizeof(struct task_struct));

        return VOS_ERR;
    }

    return VOS_OK;
}
Beispiel #5
0
int
lx_sched_setscheduler(uintptr_t pid, uintptr_t policy, uintptr_t param)
{
	int	rt_pol;
	int	rv;
	pid_t	s_pid;
	lwpid_t	s_tid;
	struct lx_sched_param lp;

	struct sched_param sp;

	if (((pid_t)pid < 0) || (param == NULL))
		return (-EINVAL);

	if ((rt_pol = validate_policy((int)policy)) < 0)
		return (rt_pol);

	if ((rv = ltos_sparam(policy, (struct lx_sched_param *)param,
	    &sp)) != 0)
		return (rv);

	if (uucopy((void *)param, &lp, sizeof (lp)) != 0)
		return (-errno);

	/*
	 * In Linux, the only valid SCHED_OTHER scheduler priority is 0
	 */
	if ((rt_pol == LX_SCHED_OTHER) && (lp.lx_sched_prio != 0))
		return (-EINVAL);

	if (lx_lpid_to_spair((pid_t)pid, &s_pid, &s_tid) < 0)
		return (-ESRCH);

	/*
	 * Check if we're allowed to change the scheduler for the process.
	 *
	 * If we're operating on a thread, we can't just call
	 * pthread_setschedparam() because as all threads reside within a
	 * single Solaris process, Solaris will allow the modification.
	 *
	 * If we're operating on a process, we can't just call
	 * sched_setscheduler() because Solaris will allow the call to succeed
	 * if the scheduler and scheduler parameters do not differ from those
	 * being installed, but Linux wants the call to fail.
	 */
	if ((rv = check_schedperms(s_pid)) != 0)
		return (rv);

	if (s_pid == getpid()) {
		struct sched_param param;
		int pol;

		if ((pol = sched_getscheduler(s_pid)) != 0)
			return (-errno);

		/*
		 * sched_setscheduler() returns the previous scheduling policy
		 * on success, so call pthread_getschedparam() to get the
		 * current thread's scheduling policy and return that if the
		 * call to pthread_setschedparam() succeeds.
		 */
		if ((rv = pthread_getschedparam(s_tid, &pol, &param)) != 0)
			return (-rv);

		return (((rv = pthread_setschedparam(s_tid, rt_pol, &sp)) != 0)
		    ? -rv : pol);
	}

	return (((rv = sched_setscheduler(s_pid, rt_pol, &sp)) == -1)
	    ? -errno : rv);
}
Beispiel #6
0
int main(int argc, char **argv)
{
    int ok;
    if(argc < 2) {
        printf("Enter latency tolerancy in millisec\n");
        return 0;
    }
    int thres_time = PERIOD_NS + (MILLISEC * atoi(*(argv+1)));
    printf("Latency threshold set to +%d\n", thres_time);
    bool fifo = argc == 2;
    printf("main: getpid()=%d, gettid()=%d\n", getpid(), gettid());
    if (fifo) {
        struct sched_param param;
        param.sched_priority = PRIORITY;
        ok = sched_setscheduler(gettid(), SCHED_FIFO, &param);
        printf("sched_setscheduler = %d\n", ok);
    } else {
        ok = setpriority(PRIO_PROCESS, 0 /* self */, -19);
        printf("setpriority = %d\n", ok);
    }
#ifdef USE_TIMER
    timer_t timerid;
    struct sigevent ev;
#endif
    clockid_t clockid;
    clockid = CLOCK_MONOTONIC;
#ifdef USE_TIMER
    ev.sigev_notify = SIGEV_THREAD;
    ev.sigev_signo = 0;
    ev.sigev_value.sival_int = 0;
    ev.sigev_notify_function = notify_function;
    ev.sigev_notify_attributes = NULL;
    //ev.sigev_notify_thread_id = 0;
    ok = timer_create(clockid, &ev, &timerid);
    //printf("timer_create ok=%d, timerid=%p\n", ok, timerid);
#endif
    ok = clock_gettime(CLOCK_MONOTONIC, &previous);
    //printf("clock_gettime ok=%d\n", ok);
#ifdef USE_TIMER
    int flags = 0;
    struct itimerspec new_;
    struct itimerspec old;
    new_.it_interval.tv_sec = 0;
    new_.it_interval.tv_nsec = PERIOD_NS;
    new_.it_value.tv_sec = 0;
    new_.it_value.tv_nsec = PERIOD_NS;
#endif
    int seconds = (int) (((long long) PERIOD_NS * (long long) MAX_COUNT) / 1000000000LL);
    printf("please wait %d seconds\n", seconds);
#ifdef USE_TIMER
    ok = timer_settime(timerid, flags, &new_, &old);
    //printf("timer_settime ok=%d\n", ok);
    sleep(seconds + 1);
    ok = timer_delete(timerid);
    //printf("\ntimer_delete ok=%d\n", ok);
#else
    struct timespec delay;
    delay.tv_sec = 0;
    delay.tv_nsec = PERIOD_NS;
    for (count = 0; count < MAX_COUNT; ++count) {
        {
            android::ScopedTrace(ATRACE_TAG, "nanosleep");
            nanosleep(&delay, NULL);
        }
        struct timespec ts;
        {
            android::ScopedTrace(ATRACE_TAG, "clock_gettime");
            ok = clock_gettime(CLOCK_MONOTONIC, &ts);
        }
        if (0 == ok) {
            unsigned delta_sec = ts.tv_sec - previous.tv_sec;
            int delta_ns = ts.tv_nsec - previous.tv_nsec;
            if (delta_ns < 0) {
                delta_ns += 1000000000;
                --delta_sec;
            }
            
            if(delta_ns > thres_time) {
                printf("[%d] Iterations passed\n", count);
                printf("delta exceeding at %lu.%09lu\n", delta_sec, delta_ns);
                return -1;
            }

            struct timespec delta_x;
            delta_x.tv_sec = delta_sec;
            delta_x.tv_nsec = delta_ns;
            delta_ts[count] = delta_x;
            previous = ts;
            ATRACE_INT("cycle_us", delta_ns / 1000);
        }
    }
#endif
    printf("expected samples: %d, actual samples: %d\n", MAX_COUNT, count);
    qsort(delta_ts, count, sizeof(struct timespec), compar);
    printf("99.8%% CDF, ideal is all ~%d ns:\n", PERIOD_NS);
    int i;
    for (i = (count * 998) / 1000; i < count; ++i) {
        printf("%lu.%09lu\n", delta_ts[i].tv_sec, delta_ts[i].tv_nsec);
    }
    return EXIT_SUCCESS;
}
static int sdio_irq_thread(void *_host)
{
	struct mmc_host *host = _host;
	struct sched_param param = { .sched_priority = 1 };
	unsigned long period, idle_period;
	int ret;

	sched_setscheduler(current, SCHED_FIFO, &param);

	/*
	 * We want to allow for SDIO cards to work even on non SDIO
	 * aware hosts.  One thing that non SDIO host cannot do is
	 * asynchronous notification of pending SDIO card interrupts
	 * hence we poll for them in that case.
	 */
	idle_period = msecs_to_jiffies(10);
	period = (host->caps & MMC_CAP_SDIO_IRQ) ?
		MAX_SCHEDULE_TIMEOUT : idle_period;

	pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
		 mmc_hostname(host), period);

	do {
		/*
		 * We claim the host here on drivers behalf for a couple
		 * reasons:
		 *
		 * 1) it is already needed to retrieve the CCCR_INTx;
		 * 2) we want the driver(s) to clear the IRQ condition ASAP;
		 * 3) we need to control the abort condition locally.
		 *
		 * Just like traditional hard IRQ handlers, we expect SDIO
		 * IRQ handlers to be quick and to the point, so that the
		 * holding of the host lock does not cover too much work
		 * that doesn't require that lock to be held.
		 */
		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
		if (ret)
			break;
		ret = process_sdio_pending_irqs(host->card);
		mmc_release_host(host);

		/*
		 * Give other threads a chance to run in the presence of
		 * errors.
		 */
		if (ret < 0) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (!kthread_should_stop())
				schedule_timeout(HZ);
			set_current_state(TASK_RUNNING);
		}

		/*
		 * Adaptive polling frequency based on the assumption
		 * that an interrupt will be closely followed by more.
		 * This has a substantial benefit for network devices.
		 */
		if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
			if (ret > 0)
				period /= 2;
			else {
				period++;
				if (period > idle_period)
					period = idle_period;
			}
		}

		set_current_state(TASK_INTERRUPTIBLE);
		if (host->caps & MMC_CAP_SDIO_IRQ) {
			mmc_host_clk_hold(host);
			host->ops->enable_sdio_irq(host, 1);
			mmc_host_clk_release(host);
		}
		if (!kthread_should_stop())
			schedule_timeout(period);
		set_current_state(TASK_RUNNING);
	} while (!kthread_should_stop());

	if (host->caps & MMC_CAP_SDIO_IRQ) {
		mmc_host_clk_hold(host);
		host->ops->enable_sdio_irq(host, 0);
		mmc_host_clk_release(host);
	}

	pr_debug("%s: IRQ thread exiting with code %d\n",
		 mmc_hostname(host), ret);

	return ret;
}

static int sdio_card_irq_get(struct mmc_card *card)
{
	struct mmc_host *host = card->host;

	WARN_ON(!host->claimed);

	if (!host->sdio_irqs++) {
		atomic_set(&host->sdio_irq_thread_abort, 0);
		host->sdio_irq_thread =
			kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
				mmc_hostname(host));
		if (IS_ERR(host->sdio_irq_thread)) {
			int err = PTR_ERR(host->sdio_irq_thread);
			host->sdio_irqs--;
			return err;
		}
	}

	return 0;
}

static int sdio_card_irq_put(struct mmc_card *card)
{
	struct mmc_host *host = card->host;

	WARN_ON(!host->claimed);
	BUG_ON(host->sdio_irqs < 1);

	if (!--host->sdio_irqs) {
		atomic_set(&host->sdio_irq_thread_abort, 1);
		kthread_stop(host->sdio_irq_thread);
	}

	return 0;
}

/**
 *	sdio_claim_irq - claim the IRQ for a SDIO function
 *	@func: SDIO function
 *	@handler: IRQ handler callback
 *
 *	Claim and activate the IRQ for the given SDIO function. The provided
 *	handler will be called when that IRQ is asserted.  The host is always
 *	claimed already when the handler is called so the handler must not
 *	call sdio_claim_host() nor sdio_release_host().
 */
int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
{
	int ret;
	unsigned char reg;

	BUG_ON(!func);
	BUG_ON(!func->card);

	pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));

	if (func->irq_handler) {
		pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
		return -EBUSY;
	}

	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
	if (ret)
		return ret;

	reg |= 1 << func->num;

	reg |= 1; /* Master interrupt enable */

	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
	if (ret)
		return ret;

	func->irq_handler = handler;
	ret = sdio_card_irq_get(func->card);
	if (ret)
		func->irq_handler = NULL;

	return ret;
}
Beispiel #8
0
int main(int argc, char **argv)
{
	struct sched_param proc_sched_param;
	pid_t finished;
	int i = 0, status = 0, excode;
	char *freezerdir;

	if (argc < 2)
		exit(1);
	freezerdir = argv[1];

	/* FIXME eventually stdio streams should be harmless */
	close(0);
	logfp = fopen(LOG_FILE, "w");
	if (!logfp) {
		perror("FAIL: couldn't open logfile");
		exit(6);
	}
	 /* redirect stdout and stderr to the log file */
	dup2(fileno(logfp), 1);
	dup2(fileno(logfp), 2);

	set_rtprio_range();

	proc_sched_param.sched_priority = prio_min;
	if (sched_setscheduler(getpid(), sched_policy,
			       &proc_sched_param) != 0) {
		log_error("sched_setscheduler");
		fclose(logfp);
		exit(3);
	}

	log("INFO", "running test with %d children\n", N);

	if (!move_to_cgroup("freezer", freezerdir, getpid())) {
		log_error("move_to_cgroup");
		fclose(logfp);
		exit(5);
	}

	kids = malloc(sizeof(pid_t)*N);
	if (kids == NULL) {
		log_error("malloc");
		fclose(logfp);
		exit(7);
	}

	/* Initialize the waitq to hold N - 1 processes */
	waitq = alloc_futex_mem(sizeof(*waitq));
	if (!waitq) {
		log_error("alloc_futex_mem");
		fclose(logfp);
		exit(8);
	}
	atomic_set(waitq, -1);

	pi_futex = alloc_futex_mem(sizeof(*pi_futex));
	if (!pi_futex) {
		log_error("alloc_futex_mem");
		fclose(logfp);
		exit(9);
	}
	atomic_set(pi_futex, 0);

	fflush(logfp);
	fflush(stderr);
	fflush(stdout);
	for (i = 0; i < (int)N; i++) {

		char *new_stack = malloc(SIGSTKSZ*8);
		kids[i] = clone(kid, new_stack + SIGSTKSZ*8, clone_flags, (void*)(long)i);
		if (kids[i] <= 0)
			break;
		log("INFO", "thread %d started.\n", kids[i]);
	}

	if (i < (int)N) {
		log_error("couldn't start N children");
		log("INFO", "killing %d child tasks.\n", i);
		for (; --i > -1;)
			kill(kids[i], SIGTERM);
		excode = 3;
		goto out;
	}

	log("INFO", "Waiting for children to finish.\n");
	excode = 0;
	do {
		/*
		 * __WALL allows us to wait for all threads to exit
		 */
		finished = waitpid(-1, &status, __WALL);
		if (!finished)
			continue;
		if ((finished == -1) && (errno == ECHILD))
			break;

		if (clone_flags & CLONE_THREAD)
			i = 0;
		else
			i--;

		log("INFO", "%d exited\n", finished);
		/* Save any [ir]regular termination info in excode. */
		if (WIFEXITED(status)) {
			log("INFO", "child %d exited with %d\n", finished,
			    WEXITSTATUS(status));
			if (!excode)
				excode = WEXITSTATUS(status);
		} else if (WIFSIGNALED(status)) {
			log("FAIL", "child %d terminated irregularly with signal %d.\n", finished, WTERMSIG(status));
			if (!excode)
				excode = WTERMSIG(status);
		}
	} while(1);
out:
	log("INFO", "Parent exiting (%d children left).\n", i);
	fflush(logfp);
	fclose(logfp);
	free(kids);
	exit(excode);
}
Beispiel #9
0
static int tzdd_proxy_thread(void *data)
{
	tzdd_dev_t *dev;
	tee_msg_head_t *tee_msg_send_head = NULL;

	//uint32_t nice;

	uint32_t res_size = 0;
	uint32_t msg_flag;

	uint32_t ret;
	bool list_ret;
	bool is_lpm_blocked = false;

	struct sched_param param;

	set_cpus_allowed_ptr(current, cpumask_of(0));
	TZDD_DBG("tzdd_proxy_thread on cpu %d\n", smp_processor_id());

	param.sched_priority = MAX_RT_PRIO - 1;

	sched_setscheduler(current, SCHED_FIFO, &param);
#if 0
	nice = task_nice(current);
	TZDD_DBG("tzdd_proxy_thread: nice = %d\n", nice);
#endif

	dev = (tzdd_dev_t *) data;

	while (1) {
		while (tzdd_get_first_req(&tee_msg_send_head)) {
			TZDD_DBG
			    ("%s: tee_msg_send_head (0x%08x) =\
			    {magic (%c%c%c%c),\
			    size (0x%08x)},\
			    cmd (0x%x)\n",\
			     __func__, (uint32_t) tee_msg_send_head,
			     tee_msg_send_head->magic[0],
			     tee_msg_send_head->magic[1],
			     tee_msg_send_head->magic[2],
			     tee_msg_send_head->magic[3],
			     tee_msg_send_head->msg_sz,
			     *((uint32_t *) (tee_msg_send_head) + 8));

			list_ret =
			    tzdd_del_node_from_req_list(&
							(tee_msg_send_head->
							 node));
			OSA_ASSERT(list_ret);

			tzdd_pt_send(tee_msg_send_head);

			if (false == is_lpm_blocked) {
				/* block LPM D1P and deeper than D1P */
#ifdef __ENABLE_PM_
				osa_wait_for_sem(_g_pm_lock, INFINITE);
				pm_qos_update_request(&_g_tzdd_lpm_cons,
					PM_QOS_CPUIDLE_BLOCK_AXI_VALUE);
#endif
				is_lpm_blocked = true;
			}
			tee_add_time_record_point("npct");
			/* Call IPI to TW */
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
			g_pre_ipi_num++;
#endif
			tee_cm_smi(CALL_IPI);
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
			g_pst_ipi_num++;
#endif
			tee_add_time_record_point("npbt");
			_g_tzdd_send_num++;
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
			g_msg_sent++;
#endif
		}

		res_size = tee_cm_get_data_size();

		while (res_size) {

			msg_flag = tzdd_pt_recv();
			if (msg_flag == TEE_MSG_IGNORE_COUNTER) {
				/* do nothing */
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
				g_msg_ignd++;
#endif
			} else {	/* TEE_MSG_FAKE && TEE_MSG_NORMAL */
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
				if (TEE_MSG_NORMAL == msg_flag)
					g_msg_recv++;
				else if (TEE_MSG_FAKE == msg_flag)
					g_msg_fake++;
				else
					OSA_ASSERT(0);
#endif
				_g_tzdd_send_num--;
			}

			res_size = tee_cm_get_data_size();
		}
		tee_add_time_record_point("nprm");
		if (_g_tzdd_send_num) {
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
			g_pre_dmy_num++;
#endif
			if (tee_cm_tw_is_idle()) {
				g_wait_for = 1;
				g_wait_for_idle++;
				ret = osa_wait_for_sem(dev->pt_sem, 5);
				g_wait_for = 0;
				if (ret != OSA_OK) {
					tee_cm_smi(0);
				}
			} else {
				tee_cm_smi(0);
			}
#ifdef TEE_DEBUG_ENALBE_PROC_FS_LOG
			g_pst_dmy_num++;
#endif
		} else {
			/* release D1P LPM constraint */
			if (true == is_lpm_blocked) {
#ifdef __ENABLE_PM_
				pm_qos_update_request(&_g_tzdd_lpm_cons,
					PM_QOS_CPUIDLE_BLOCK_DEFAULT_VALUE);
				osa_release_sem(_g_pm_lock);
#endif
				is_lpm_blocked = false;
			}

			tee_add_time_record_point("npwa");
			g_wait_for = 2;
			g_wait_for_command++;
			ret = osa_wait_for_sem(dev->pt_sem, INFINITE);
			g_wait_for = 0;
			OSA_ASSERT(!ret);

			if (true == _g_pt_thread_stop_flag) {
				TZDD_DBG("tzdd_proxy_thread(),P-break\n");
				break;
			}
			tee_add_time_record_point("npet");
		}
	}
Beispiel #10
0
static void
action_launch_child(svc_action_t *op)
{
    int lpc;

    /* SIGPIPE is ignored (which is different from signal blocking) by the gnutls library.
     * Depending on the libqb version in use, libqb may set SIGPIPE to be ignored as well. 
     * We do not want this to be inherited by the child process. By resetting this the signal
     * to the default behavior, we avoid some potential odd problems that occur during OCF
     * scripts when SIGPIPE is ignored by the environment. */
    signal(SIGPIPE, SIG_DFL);

#if defined(HAVE_SCHED_SETSCHEDULER)
    if (sched_getscheduler(0) != SCHED_OTHER) {
        struct sched_param sp;

        memset(&sp, 0, sizeof(sp));
        sp.sched_priority = 0;

        if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
            crm_perror(LOG_ERR, "Could not reset scheduling policy to SCHED_OTHER for %s", op->id);
        }
    }
#endif
    if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
        crm_perror(LOG_ERR, "Could not reset process priority to 0 for %s", op->id);
    }

    /* Man: The call setpgrp() is equivalent to setpgid(0,0)
     * _and_ compiles on BSD variants too
     * need to investigate if it works the same too.
     */
    setpgid(0, 0);

    /* close all descriptors except stdin/out/err and channels to logd */
    for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) {
        close(lpc);
    }

#if SUPPORT_CIBSECRETS
    if (replace_secret_params(op->rsc, op->params) < 0) {
        /* replacing secrets failed! */
        if (safe_str_eq(op->action,"stop")) {
            /* don't fail on stop! */
            crm_info("proceeding with the stop operation for %s", op->rsc);

        } else {
            crm_err("failed to get secrets for %s, "
                    "considering resource not configured", op->rsc);
            _exit(PCMK_OCF_NOT_CONFIGURED);
        }
    }
#endif
    /* Setup environment correctly */
    add_OCF_env_vars(op);

    /* execute the RA */
    execvp(op->opaque->exec, op->opaque->args);

    /* Most cases should have been already handled by stat() */
    services_handle_exec_error(op, errno);

    _exit(op->rc);
}
Beispiel #11
0
static void watchdog_set_prio(unsigned int policy, unsigned int prio)
{
	struct sched_param param = { .sched_priority = prio };

	sched_setscheduler(current, policy, &param);
}
Beispiel #12
0
int main(int argc, char **argv)
{
    pthread_t *threads;
    long i;
    int ret;
    struct timespec intv;
    struct sched_param param;

    rt_init("a:r:t:e:l:h:", parse_args, argc, argv);
    signal(SIGINT, stop_log);

    if (argc >= (optind + 1))
        nr_tasks = atoi(argv[optind]);
    else {
        numcpus = sysconf(_SC_NPROCESSORS_ONLN);
        nr_tasks = numcpus + 1;
    }

    intervals = malloc(sizeof(stats_container_t) * nr_tasks);
    if (!intervals)
        debug(DBG_ERR, "malloc failed\n");
    memset(intervals, 0, sizeof(stats_container_t) * nr_tasks);

    intervals_length = malloc(sizeof(stats_container_t) * nr_tasks);
    if (!intervals_length)
        debug(DBG_ERR, "malloc failed\n");
    memset(intervals_length, 0, sizeof(stats_container_t) * nr_tasks);

    if (!intervals_loops)
        debug(DBG_ERR, "malloc failed\n");
    intervals_loops = malloc(sizeof(stats_container_t) * nr_tasks);
    memset(intervals_loops, 0, sizeof(stats_container_t) * nr_tasks);

    threads = malloc(sizeof(*threads) * nr_tasks);
    if (!threads)
        debug(DBG_ERR, "malloc failed\n");
    memset(threads, 0, sizeof(*threads) * nr_tasks);

    ret = pthread_barrier_init(&start_barrier, NULL, nr_tasks + 1);
    ret = pthread_barrier_init(&end_barrier, NULL, nr_tasks + 1);
    if (ret < 0)
        debug(DBG_ERR, "pthread_barrier_init failed: %s\n",
              strerror(ret));


    for (i = 0; i < nr_tasks; i++) {
        stats_container_init(&intervals[i], nr_runs);
        stats_container_init(&intervals_length[i], nr_runs);
        stats_container_init(&intervals_loops[i], nr_runs);
    }

    thread_pids = malloc(sizeof(long) * nr_tasks);
    if (!thread_pids)
        debug(DBG_ERR, "malloc thread_pids failed\n");

    for (i = 0; i < nr_tasks; i++) {
        threads[i] = create_fifo_thread(start_task, (void *)i,
                                        prio_start + i);
    }

    /*
     * Progress bar uses stderr to let users see it when
     * redirecting output. So we convert stderr to use line
     * buffering so the progress bar doesn't flicker.
     */
    setlinebuf(stderr);

    /* up our prio above all tasks */
    memset(&param, 0, sizeof(param));
    param.sched_priority = nr_tasks + prio_start;
    if (sched_setscheduler(0, SCHED_FIFO, &param))
        debug(DBG_WARN, "Warning, can't set priority of"
              "main thread !\n");
    intv.tv_sec = INTERVAL / NS_PER_SEC;
    intv.tv_nsec = INTERVAL % (1 * NS_PER_SEC);

    print_progress_bar(0);

    setup_ftrace_marker();

    for (loop = 0; loop < nr_runs; loop++) {
        unsigned long long end;

        now = rt_gettime() / NS_PER_US;

        ftrace_write("Loop %d now=%lld\n", loop, now);

        pthread_barrier_wait(&start_barrier);

        ftrace_write("All running!!!\n");

        rt_nanosleep(intv.tv_nsec);
        print_progress_bar((loop * 100) / nr_runs);

        end = rt_gettime() / NS_PER_US;
        ftrace_write("Loop %d end now=%lld diff=%lld\n",
                     loop, end, end - now);
        ret = pthread_barrier_wait(&end_barrier);

        if (stop || (check && check_times(loop))) {
            loop++;
            nr_runs = loop;
            break;
        }
    }
    putc('\n', stderr);

    pthread_barrier_wait(&start_barrier);
    done = 1;
    pthread_barrier_wait(&end_barrier);

    join_threads();
    print_results();

    if (stop) {
        /*
         * We use this test in bash while loops
         * So if we hit Ctrl-C then let the while
         * loop know to break.
         */
        if (check < 0)
            exit(-1);
        else
            exit(1);
    }
    if (check < 0)
        exit(-1);
    else
        exit(0);

    return 0;
}
	/* avoid HT sibilings if possible */
	if (cpumask_empty(tmp))
		cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
	if (cpumask_empty(tmp)) {
		mutex_unlock(&round_robin_lock);
		return;
	}
	for_each_cpu(cpu, tmp) {
		if (cpu_weight[cpu] < min_weight) {
			min_weight = cpu_weight[cpu];
			preferred_cpu = cpu;
		}
	}

	if (tsk_in_cpu[tsk_index] != -1)
		cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
	tsk_in_cpu[tsk_index] = preferred_cpu;
	cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
	cpu_weight[preferred_cpu]++;
	mutex_unlock(&round_robin_lock);

	set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
}

static void exit_round_robin(unsigned int tsk_index)
{
	struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
	cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
	tsk_in_cpu[tsk_index] = -1;
}

static unsigned int idle_pct = 5; /* percentage */
static unsigned int round_robin_time = 10; /* second */
static int power_saving_thread(void *data)
{
	struct sched_param param = {.sched_priority = 1};
	int do_sleep;
	unsigned int tsk_index = (unsigned long)data;
	u64 last_jiffies = 0;

	sched_setscheduler(current, SCHED_RR, &param);

	while (!kthread_should_stop()) {
		int cpu;
		u64 expire_time;

		try_to_freeze();

		/* round robin to cpus */
		if (last_jiffies + round_robin_time * HZ < jiffies) {
			last_jiffies = jiffies;
			round_robin_cpu(tsk_index);
		}

		do_sleep = 0;

		expire_time = jiffies + HZ * (100 - idle_pct) / 100;

		while (!need_resched()) {
			if (tsc_detected_unstable && !tsc_marked_unstable) {
				/* TSC could halt in idle, so notify users */
				mark_tsc_unstable("TSC halts in idle");
				tsc_marked_unstable = 1;
			}
			if (lapic_detected_unstable && !lapic_marked_unstable) {
				int i;
				/* LAPIC could halt in idle, so notify users */
				for_each_online_cpu(i)
					clockevents_notify(
						CLOCK_EVT_NOTIFY_BROADCAST_ON,
						&i);
				lapic_marked_unstable = 1;
			}
			local_irq_disable();
			cpu = smp_processor_id();
			if (lapic_marked_unstable)
				clockevents_notify(
					CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
			stop_critical_timings();

			__monitor((void *)&current_thread_info()->flags, 0, 0);
			smp_mb();
			if (!need_resched())
				__mwait(power_saving_mwait_eax, 1);

			start_critical_timings();
			if (lapic_marked_unstable)
				clockevents_notify(
					CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
			local_irq_enable();

			if (jiffies > expire_time) {
				do_sleep = 1;
				break;
			}
		}

		/*
		 * current sched_rt has threshold for rt task running time.
		 * When a rt task uses 95% CPU time, the rt thread will be
		 * scheduled out for 5% CPU time to not starve other tasks. But
		 * the mechanism only works when all CPUs have RT task running,
		 * as if one CPU hasn't RT task, RT task from other CPUs will
		 * borrow CPU time from this CPU and cause RT task use > 95%
		 * CPU time. To make 'avoid starvation' work, takes a nap here.
		 */
		if (do_sleep)
			schedule_timeout_killable(HZ * idle_pct / 100);
	}

	exit_round_robin(tsk_index);
	return 0;
}

static struct task_struct *ps_tsks[NR_CPUS];
static unsigned int ps_tsk_num;
static int create_power_saving_task(void)
{
	int rc = -ENOMEM;

	ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
		(void *)(unsigned long)ps_tsk_num,
		"power_saving/%d", ps_tsk_num);
	rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
	if (!rc)
		ps_tsk_num++;
	else
		ps_tsks[ps_tsk_num] = NULL;

	return rc;
}
static ssize_t lpa_if_write(struct file *file, const char __user *buf,
		size_t count, loff_t *pos)
{
	struct lpa_if *lpa_if = file->private_data;
	struct audio_buffer *ab;
	const char __user *start = buf;
	int xfer, rc;
	struct sched_param s = { .sched_priority = 1 };
	int old_prio = current->rt_priority;
	int old_policy = current->policy;
	int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);

	 /* just for this write, set us real-time */
	if (!task_has_rt_policy(current)) {
		struct cred *new = prepare_creds();
		cap_raise(new->cap_effective, CAP_SYS_NICE);
		commit_creds(new);
		if ((sched_setscheduler(current, SCHED_RR, &s)) < 0)
			pr_err("sched_setscheduler failed\n");
	}
	mutex_lock(&lpa_if->lock);

	if (dma_buf_index < 2) {

		ab = lpa_if->audio_buf + dma_buf_index;

		if (copy_from_user(ab->data, buf, count)) {
			pr_err("copy from user failed\n");
			rc = 0;
			goto end;

		}
		mb();
		pr_debug("prefill: count %u  audio_buf[%u].size %u\n",
			 count, dma_buf_index, ab->size);

		ab->used = 1;
		dma_buf_index++;
		rc =  count;
		goto end;
	}

	if (lpa_if->config != 1) {
		pr_err("AUDIO_START did not happen\n");
		rc = 0;
		goto end;
	}

	while (count > 0) {

		ab = lpa_if->audio_buf + lpa_if->cpu_buf;

		rc = wait_event_timeout(lpa_if->wait, (ab->used == 0), 10 * HZ);
		if (!rc) {
			pr_err("wait_event_timeout failed\n");
			rc =  buf - start;
			goto end;
		}

		xfer = count;

		if (xfer > lpa_if->dma_period_sz)
			xfer = lpa_if->dma_period_sz;

		if (copy_from_user(ab->data, buf, xfer)) {
			pr_err("copy from user failed\n");
			rc = buf - start;
			goto end;
		}

		mb();
		buf += xfer;
		count -= xfer;
		ab->used = 1;

		pr_debug("xfer %d, size %d, used %d cpu_buf %d\n",
			xfer, ab->size, ab->used, lpa_if->cpu_buf);
		lpa_if->cpu_buf++;
		lpa_if->cpu_buf = lpa_if->cpu_buf % lpa_if->cfg.buffer_count;
	}
	rc = buf - start;
end:
	mutex_unlock(&lpa_if->lock);
	/* restore old scheduling policy */
	if (!rt_policy(old_policy)) {
		struct sched_param v = { .sched_priority = old_prio };
		if ((sched_setscheduler(current, old_policy, &v)) < 0)
			pr_err("sched_setscheduler failed\n");
		if (likely(!cap_nice)) {
			struct cred *new = prepare_creds();
			cap_lower(new->cap_effective, CAP_SYS_NICE);
			commit_creds(new);
		}
	}
	return rc;
}

static int lpa_if_release(struct inode *inode, struct file *file)
{
	struct lpa_if *lpa_if = file->private_data;

	hdmi_audio_packet_enable(0);

	wait_for_dma_cnt_stop(lpa_if->dma_ch);

	hdmi_audio_enable(0, HDMI_AUDIO_FIFO_WATER_MARK);

	if (lpa_if->config) {
		unregister_dma_irq_handler(lpa_if->dma_ch);
		dai_stop_hdmi(lpa_if->dma_ch);
		lpa_if->config = 0;
	}
	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 0, 0);

	if (hdmi_msm_audio_get_sample_rate() != HDMI_SAMPLE_RATE_48KHZ)
		hdmi_msm_audio_sample_rate_reset(HDMI_SAMPLE_RATE_48KHZ);

	return 0;
}

static const struct file_operations lpa_if_fops = {
	.owner = THIS_MODULE,
	.open = lpa_if_open,
	.write = lpa_if_write,
	.release = lpa_if_release,
	.unlocked_ioctl = lpa_if_ioctl,
};

struct miscdevice lpa_if_misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "msm_lpa_if_out",
	.fops = &lpa_if_fops,
};

static int __init lpa_if_init(void)
{
	int rc;

	lpa_if_ptr = kzalloc(sizeof(struct lpa_if), GFP_KERNEL);
	if (!lpa_if_ptr) {
		pr_info("No mem for lpa-if\n");
		return -ENOMEM;
	}

	mutex_init(&lpa_if_ptr->lock);
	init_waitqueue_head(&lpa_if_ptr->wait);

	lpa_if_ptr->buffer = dma_alloc_coherent(NULL, DMA_ALLOC_BUF_SZ,
				    &(lpa_if_ptr->buffer_phys), GFP_KERNEL);
	if (!lpa_if_ptr->buffer) {
		pr_err("dma_alloc_coherent failed\n");
		kfree(lpa_if_ptr);
		return -ENOMEM;
	}

	pr_info("lpa_if_ptr 0x%08x   buf_vir 0x%08x   buf_phy 0x%08x "
		" buf_zise %u\n", (u32)lpa_if_ptr,
		(u32)(lpa_if_ptr->buffer), lpa_if_ptr->buffer_phys,
		DMA_ALLOC_BUF_SZ);

	rc =  misc_register(&lpa_if_misc);
	if (rc < 0) {
		pr_err("misc_register failed\n");

		dma_free_coherent(NULL, DMA_ALLOC_BUF_SZ, lpa_if_ptr->buffer,
				lpa_if_ptr->buffer_phys);
		kfree(lpa_if_ptr);
	}
	return rc;
}

device_initcall(lpa_if_init);
Beispiel #15
0
/* The main test function. */
int main(int argc, char * argv[])
{
	int ret, param, status;
	pid_t child, ctl;

	struct sched_param sp;

	/* Initialize output */
	output_init();

	/* Change process policy and parameters */
	sp.sched_priority = param = sched_get_priority_max(POLICY);

	if (sp.sched_priority == -1)
	{
		UNRESOLVED(errno, "Failed to get max priority value");
	}

	ret = sched_setscheduler(0, POLICY, &sp);

	if (ret == -1)
	{
		UNRESOLVED(errno, "Failed to change process scheduling policy");
	}

	/* Create the child */
	child = fork();

	if (child == -1)
	{
		UNRESOLVED(errno, "Failed to fork");
	}

	/* child */
	if (child == 0)
	{

		/* Check the scheduling policy */
		ret = sched_getscheduler(0);

		if (ret == -1)
		{
			UNRESOLVED(errno, "Failed to read scheduling policy in child");
		}

		if (ret != POLICY)
		{
			FAILED("The scheduling policy was not inherited");
		}

		ret = sched_getparam(0, &sp);

		if (ret != 0)
		{
			UNRESOLVED(errno, "Failed to read scheduling parameter in child");
		}

		if (sp.sched_priority != param)
		{
			FAILED("The scheduling parameter was not inherited");
		}

		/* We're done */
		exit(PTS_PASS);
	}

	/* Parent joins the child */
	ctl = waitpid(child, &status, 0);

	if (ctl != child)
	{
		UNRESOLVED(errno, "Waitpid returned the wrong PID");
	}

	if (!WIFEXITED(status) || (WEXITSTATUS(status) != PTS_PASS))
	{
		FAILED("Child exited abnormally");
	}

	/* Test passed */
#if VERBOSE > 0
	output("Test passed\n");

#endif
	PASSED;
}
Beispiel #16
0
static void create_kthread(struct kthread_create_info *create)
{
	int pid;

	/* We want our own signal handler (we take no signals by default). */
	pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
	if (pid < 0) {
		create->result = ERR_PTR(pid);
	} else {
		struct sched_param param = { .sched_priority = 0 };
		wait_for_completion(&create->started);
		read_lock(&tasklist_lock);
		create->result = find_task_by_pid_ns(pid, &init_pid_ns);
		read_unlock(&tasklist_lock);
		/*
		 * root may have changed our (kthreadd's) priority or CPU mask.
		 * The kernel thread should not inherit these properties.
		 */
		sched_setscheduler(create->result, SCHED_NORMAL, &param);
		set_user_nice(create->result, KTHREAD_NICE_LEVEL);
		set_cpus_allowed_ptr(create->result, CPU_MASK_ALL_PTR);
	}
	complete(&create->done);
}

/**
 * kthread_create - create a kthread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @namefmt: printf-style name for the thread.
 *
 * Description: This helper function creates and names a kernel
 * thread.  The thread will be stopped: use wake_up_process() to start
 * it.  See also kthread_run(), kthread_create_on_cpu().
 *
 * When woken, the thread will run @threadfn() with @data as its
 * argument. @threadfn() can either call do_exit() directly if it is a
 * standalone thread for which noone will call kthread_stop(), or
 * return when 'kthread_should_stop()' is true (which means
 * kthread_stop() has been called).  The return value should be zero
 * or a negative error number; it will be passed to kthread_stop().
 *
 * Returns a task_struct or ERR_PTR(-ENOMEM).
 */
struct task_struct *kthread_create(int (*threadfn)(void *data),
				   void *data,
				   const char namefmt[],
				   ...)
{
	struct kthread_create_info create;

	create.threadfn = threadfn;
	create.data = data;
	init_completion(&create.started);
	init_completion(&create.done);

	spin_lock(&kthread_create_lock);
	list_add_tail(&create.list, &kthread_create_list);
	spin_unlock(&kthread_create_lock);

	wake_up_process(kthreadd_task);
	wait_for_completion(&create.done);

	if (!IS_ERR(create.result)) {
		va_list args;
		va_start(args, namefmt);
		vsnprintf(create.result->comm, sizeof(create.result->comm),
			  namefmt, args);
		va_end(args);
	}
	return create.result;
}
EXPORT_SYMBOL(kthread_create);

/**
 * kthread_bind - bind a just-created kthread to a cpu.
 * @k: thread created by kthread_create().
 * @cpu: cpu (might not be online, must be possible) for @k to run on.
 *
 * Description: This function is equivalent to set_cpus_allowed(),
 * except that @cpu doesn't need to be online, and the thread must be
 * stopped (i.e., just returned from kthread_create()).
 */
void kthread_bind(struct task_struct *k, unsigned int cpu)
{
	if (k->state != TASK_UNINTERRUPTIBLE) {
		WARN_ON(1);
		return;
	}
	/* Must have done schedule() in kthread() before we set_task_cpu */
	wait_task_inactive(k, 0);
	set_task_cpu(k, cpu);
	k->cpus_allowed = cpumask_of_cpu(cpu);
	k->flags |= PF_THREAD_BOUND;
}
EXPORT_SYMBOL(kthread_bind);

/**
 * kthread_stop - stop a thread created by kthread_create().
 * @k: thread created by kthread_create().
 *
 * Sets kthread_should_stop() for @k to return true, wakes it, and
 * waits for it to exit.  Your threadfn() must not call do_exit()
 * itself if you use this function!  This can also be called after
 * kthread_create() instead of calling wake_up_process(): the thread
 * will exit without calling threadfn().
 *
 * Returns the result of threadfn(), or %-EINTR if wake_up_process()
 * was never called.
 */
int kthread_stop(struct task_struct *k)
{
	int ret;

	mutex_lock(&kthread_stop_lock);

	/* It could exit after stop_info.k set, but before wake_up_process. */
	get_task_struct(k);

	/* Must init completion *before* thread sees kthread_stop_info.k */
	init_completion(&kthread_stop_info.done);
	smp_wmb();

	/* Now set kthread_should_stop() to true, and wake it up. */
	kthread_stop_info.k = k;
	wake_up_process(k);
	put_task_struct(k);

	/* Once it dies, reset stop ptr, gather result and we're done. */
	wait_for_completion(&kthread_stop_info.done);
	kthread_stop_info.k = NULL;
	ret = kthread_stop_info.err;
	mutex_unlock(&kthread_stop_lock);

	return ret;
}