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; }
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 }
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, ¶m)){ 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, ¶m)) { 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; }
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, ¶m)) != 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); }
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, ¶m); 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, ¶m); /* * 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, ®); 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; }
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); }
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, ¶m); #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"); } }
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); }
static void watchdog_set_prio(unsigned int policy, unsigned int prio) { struct sched_param param = { .sched_priority = prio }; sched_setscheduler(current, policy, ¶m); }
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(¶m, 0, sizeof(param)); param.sched_priority = nr_tasks + prio_start; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) 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, ¶m); 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 *)¤t_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);
/* 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; }
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, ¶m); 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; }