/*************************************************************************** Name: get_next_task Description: retrieves tasks for proc_loop() The fist time, we get the task and check task_mode() Input: none Output: none Returns: process status (set to LOGOUT if no tasks found) ***************************************************************************/ static int get_next_task(Arb_connection* dbp) { /* Loop until time to perform a task */ for (;;) { if (logout_requested()) break; /* Check the next scheduled processing task */ if (process_config(dbp) == Failure) { ModLog->batchLog(XPRMOD, XPR_NO_TASK); arb_put_state(dbp, ARB_STATUS_LOGOUT); break; } bWroteCtlRpt = FALSE; Proc_mode = (tProcMode)task_mode(); if (Proc_mode != MOD_PRODUCTION && Proc_mode != MOD_BACKOUT) { ModLog->batchLog(XPRMOD,XPR_FAIL_INFO_INT,(char*)"invalid proc mode:",Proc_mode); arb_put_state(dbp,ARB_STATUS_LOGOUT); break; } if (task_idle_time() <= 0) break; arb_put_state(dbp, ARB_STATUS_IDLE); goto_idle(dbp, task_idle_time()); } return arb_get_current_state(); }
void* rt_thread(void *tcontext) { struct thread_context *ctx = (struct thread_context *) tcontext; struct rt_task param; /* set up litmus real-time task*/ be_migrate_to_domain(ctx->cpu); init_rt_task_param(¶m); param.priority = ctx->priority; param.cpu = ctx->cpu; param.exec_cost = ms2ns(3000); param.period = ms2ns(10000); param.relative_deadline = ms2ns(15000); param.budget_policy = NO_ENFORCEMENT; param.cls = RT_CLASS_HARD; param.enable_help = helping; param.non_preemption_after_migrate = non_preemption; init_rt_thread(); if (set_rt_task_param(gettid(), ¶m) != 0) printf("set_rt_task_param error. \n "); task_mode(LITMUS_RT_TASK); lock_1 = litmus_open_lock(7, 1, "b", init_prio_per_cpu(4, 10, 10, 10, 10)); do { lt_sleep(10); job(ctx); count_first++; if (count_first >= executions) exit_program = 1; } while (exit_program != 1); task_mode(BACKGROUND_TASK); return NULL; }
int main(int argc, char** argv) { int ret; int opt; int wait = 0; int test_loop = 0; int skip_config = 0; int verbose = 0; double wcet_ms; double duration, start; struct rt_task rt; FILE *file; progname = argv[0]; while ((opt = getopt(argc, argv, OPTSTR)) != -1) { switch (opt) { case 'w': wait = 1; break; case 'l': test_loop = 1; break; case 'd': /* manually configure delay per loop iteration * unit: microseconds */ loop_length = atof(optarg) / 1000000; skip_config = 1; break; case 'v': verbose = 1; break; case ':': usage("Argument missing."); break; case '?': default: usage("Bad argument."); break; } } if (!skip_config) configure_loop(); if (test_loop) { debug_delay_loop(); return 0; } if (argc - optind < 2) usage("Arguments missing."); if ((file = fopen(argv[optind + 0], "r")) == NULL) { fprintf(stderr, "Cannot open %s\n", argv[1]); return -1; } duration = atof(argv[optind + 1]); memset(&rt, 0, sizeof(struct rt_task)); if (parse_hime_ts_file(file, &rt) < 0) bail_out("Could not parse file\n"); if (sporadic_task_ns_semi(&rt) < 0) bail_out("could not setup rt task params"); fclose(file); if (verbose) show_loop_length(); init_litmus(); ret = task_mode(LITMUS_RT_TASK); if (ret != 0) bail_out("could not become RT task"); if (wait) { ret = wait_for_ts_release(); if (ret != 0) bail_out("wait_for_ts_release()"); } wcet_ms = ((double) rt.exec_cost ) / __NS_PER_MS; start = wctime(); while (start + duration > wctime()) { job(wcet_ms * 0.0009); /* 90% wcet, in seconds */ } return 0; }
int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVFrame *pFrameRGB = NULL; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer = NULL; AVDictionary *optionsDict = NULL; struct SwsContext *sws_ctx = NULL; // Real-Time Setup int do_exit; int count = 0; /* rt_task defined in rt_param.h struct rt_task { lt_t exec_cost; lt_t period; lt_t relative_deadline; lt_t phase; unsigned int cpu; unsigned int priority; task_class_t cls; budget_policy_t budget_policy; release_policy_t release_policy; */ struct rt_task param; /* Setup task parameters */ init_rt_task_param(¶m); param.exec_cost = ms2ns(EXEC_COST); param.period = ms2ns(PERIOD); param.relative_deadline = ms2ns(RELATIVE_DEADLINE); /* What to do in the case of budget overruns? */ param.budget_policy = NO_ENFORCEMENT; /* The task class parameter is ignored by most plugins. */ param.cls = RT_CLASS_SOFT; /* The priority parameter is only used by fixed-priority plugins. */ param.priority = LITMUS_LOWEST_PRIORITY; /* The task is in background mode upon startup. */ // END REAL TIME SETUP /***** * 1) Command line paramter parsing would be done here. */ if(argc < 2) { printf("Please provide a movie file\n"); return -1; } /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ // Register all formats and codecs av_register_all(); // Open video file if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(avformat_find_stream_info(pFormatCtx, NULL)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, argv[1], 0); /***** * End Work Environment Setup */ // Find the first video stream videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoStream=i; break; } if(videoStream==-1) return -1; // Didn't find a video stream // Get a pointer to the codec context for the video stream pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return -1; // Codec not found } // Open codec if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) return -1; // Could not open codec // Allocate video frame pFrame=av_frame_alloc(); // Allocate an AVFrame structure pFrameRGB=av_frame_alloc(); if(pFrameRGB==NULL) return -1; // Determine required buffer size and allocate buffer numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); sws_ctx = sws_getContext ( pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL ); // Assign appropriate parts of buffer to image planes in pFrameRGB // Note that pFrameRGB is an AVFrame, but AVFrame is a superset // of AVPicture avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); // Defined in litmus.h /* To specify a partition, do * * param.cpu = CPU; * be_migrate_to(CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1 before calling * set_rt_task_param(). */ CALL( set_rt_task_param(gettid(), ¶m) ); // Defined in litmus.h /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); // Defined in litmus.h /* The task is now executing as a real-time task if the call didn't fail. */ // Read frames and save first five frames to disk i=0; while(av_read_frame(pFormatCtx, &packet)>=0) { /* Wait until the next job is released. */ sleep_next_period(); // Print frame number printf("Frame %d\n", i); // Is this a packet from the video stream? if(packet.stream_index==videoStream) { // Decode video frame avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); // Did we get a video frame? if(frameFinished) { // Convert the image from its native format to RGB sws_scale ( sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize ); // Save the frame to disk if(++i<=5) SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); // Free the RGB image av_free(buffer); av_free(pFrameRGB); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file avformat_close_input(&pFormatCtx); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }
/* A real-time thread is very similar to the main function of a single-threaded * real-time app. Notice, that init_rt_thread() is called to initialized per-thread * data structures of the LITMUS^RT user space libary. */ void* rt_thread(void *tcontext) { int do_exit; struct thread_context *ctx = (struct thread_context *) tcontext; struct rt_task param; /* Set up task parameters */ memset(¶m, 0, sizeof(param)); param.exec_cost = EXEC_COST * NS_PER_MS; param.period = PERIOD * NS_PER_MS; param.relative_deadline = RELATIVE_DEADLINE * NS_PER_MS; /* What to do in the case of budget overruns? */ param.budget_policy = NO_ENFORCEMENT; /* The task class parameter is ignored by most plugins. */ param.cls = RT_CLASS_SOFT; /* The priority parameter is only used by fixed-priority plugins. */ param.priority = LITMUS_LOWEST_PRIORITY; /* Make presence visible. */ printf("RT Thread %d active.\n", ctx->id); /***** * 1) Initialize real-time settings. */ CALL( init_rt_thread() ); /* To specify a partition, do * * param.cpu = CPU; * be_migrate_to(CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1 before calling * set_rt_task_param(). */ CALL( set_rt_task_param(gettid(), ¶m) ); /***** * 2) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ /***** * 3) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(); } while (!do_exit); /***** * 4) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); return NULL; }
int main(int argc, char** argv) { int do_exit, ret; struct rt_task param; sprintf(myPID,"%d",getpid()); strcat(filePath,myPID); //argv 1. wcet(ms) 2. period(ms) 3. duration(s) 4. mode (1 for cali sar, 4 for cali kalman) 5. appName 6. size/iter wcet_f = atoi(argv[1]); // in ms period_f = atof(argv[2]); // in ms size_iter = atof(argv[6]); wcet_us = (int)(wcet_f*1000); // Convert ms to us // wcet_frac = modf(wcet_f,&int_temp); // wcet_int = (int)(int_temp); dur = 1000 * atoi(argv[3]); // in seconds -> to ms mode = atoi(argv[4]); count = (dur / period_f); // printf("wcet_f: %f\tperiod_f: %f\twcet_us: %ld\tcount: %d\n", // wcet_f,period_f,wcet_us,count); if(argc > 6) { strncpy(myName,argv[5],40); } else { strncpy(myName,"NoNameSet",40); } printf("Name set: %s\n",myName); /* Setup task parameters */ memset(¶m, 0, sizeof(param)); // param.exec_cost = wcet_f * NS_PER_MS; // param.period = period_f * NS_PER_MS; param.exec_cost = wcet_f * NS_PER_MS; param.period = period_f * NS_PER_MS; // printf("param.exec: %ld\tparam.period: %ld\n",param.exec_cost, param.period); // return 0; param.relative_deadline = period_f * NS_PER_MS; /* What to do in the case of budget overruns? */ param.budget_policy = NO_ENFORCEMENT; /* The task class parameter is ignored by most plugins. */ param.cls = RT_CLASS_SOFT; param.cls = RT_CLASS_HARD; /* The priority parameter is only used by fixed-priority plugins. */ param.priority = LITMUS_LOWEST_PRIORITY; /* The task is in background mode upon startup. */ /***** * 1) Command line paramter parsing would be done here. */ /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); /* To specify a partition, do * * param.cpu = CPU; * be_migrate_to(CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1 before calling * set_rt_task_param(). */ CALL( set_rt_task_param(gettid(), ¶m) ); /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ pCtrlPage = get_ctrl_page(); ret = wait_for_ts_release(); if (ret != 0) printf("ERROR: wait_for_ts_release()"); /***** * 5) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(); } while (!do_exit); /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }
/* typically, main() does a couple of things: * 1) parse command line parameters, etc. * 2) Setup work environment. * 3) Setup real-time parameters. * 4) Transition to real-time mode. * 5) Invoke periodic or sporadic jobs. * 6) Transition to background mode. * 7) Clean up and exit. * * The following main() function provides the basic skeleton of a single-threaded * LITMUS^RT real-time task. In a real program, all the return values should be * checked for errors. */ int main(int argc, char** argv) { int do_exit; /* The task is in background mode upon startup. */ /***** * 1) Command line paramter parsing would be done here. */ /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); CALL( sporadic_global(EXEC_COST, PERIOD) ); /* To specify a partition, use sporadic_partitioned(). * Example: * * sporadic_partitioned(EXEC_COST, PERIOD, CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1. */ /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ /***** * 5) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(); } while (!do_exit); /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }
/* typically, main() does a couple of things: * 1) parse command line parameters, etc. * 2) Setup work environment. * 3) Setup real-time parameters. * 4) Transition to real-time mode. * 5) Invoke periodic or sporadic jobs. * 6) Transition to background mode. * 7) Clean up and exit. * * The following main() function provides the basic skeleton of a single-threaded * LITMUS^RT real-time task. In a real program, all the return values should be * checked for errors. */ int main(int argc, char** argv) { int do_exit, ret; struct rt_task param; wcet = atoi(argv[1]); // in ms period = atoi(argv[2]); // in ms dur = 1000 * atoi(argv[3]); // in seconds count = (dur / period) + 1; /* Setup task parameters */ memset(¶m, 0, sizeof(param)); param.exec_cost = wcet * NS_PER_MS; param.period = period * NS_PER_MS; param.relative_deadline = period * NS_PER_MS; /* What to do in the case of budget overruns? */ param.budget_policy = NO_ENFORCEMENT; /* The task class parameter is ignored by most plugins. */ param.cls = RT_CLASS_SOFT; param.cls = RT_CLASS_HARD; /* The priority parameter is only used by fixed-priority plugins. */ param.priority = LITMUS_LOWEST_PRIORITY; /* The task is in background mode upon startup. */ /***** * 1) Command line paramter parsing would be done here. */ /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); /* To specify a partition, do * * param.cpu = CPU; * be_migrate_to(CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1 before calling * set_rt_task_param(). */ CALL( set_rt_task_param(gettid(), ¶m) ); /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ ret = wait_for_ts_release(); if (ret != 0) printf("ERROR: wait_for_ts_release()"); /***** * 5) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(); } while (!do_exit); /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }
void proc_loop(void) { int status; static char trname[17]; int prev_total_accounts; int loop = FALSE; int bLoggedIntoTHS = FALSE; int process_log_initialized = 0; int bNormalExit = FALSE; /* ** Begin the main processing loop. This loop is executed ** until an error condition is encountered or an EXIT/ABORT ** interrupt is received. */ while ((get_next_task() != ARB_STATUS_LOGOUT)) { Est_mode = task_mode(); Proc_mode=0; /* ** Initialize task mode field for Process Logging */ switch (Est_mode) { case MODE_ACNT_EST: strncpy(proclogmode,PROCLOG_ACCNT_ESTIMATE_KEY,80); break; case REDO: strncpy(proclogmode,PROCLOG_REESTIMATE_KEY,80); break; default: strncpy(proclogmode,PROCLOG_ESTIMATE_KEY,80); break; } /* **log in to THS_Client */ if (InitSendToTHS_SocketBackend(dbadmin,arb_get_process_id()) != Success) break; bLoggedIntoTHS = TRUE; message = (THS_CHR_MSG*)calloc (1,sizeof(THS_CHR_MSG)); if(!message) { emit(BIPMOD, BIP_MEM_ALLOC_ERR,1, sizeof(THS_CHR_MSG), "send_ths_message"); break; } /* ** Create the task identifier from the process ID and the ** current time. Clear the counts of successful and errored ** estimates. */ make_task_id(); Total_successes = 0; Total_skips = 0; Total_in_error = 0; Total_accounts = 0; /* ** Fetch the list of account identifiers for the accounts ** to be processed. */ emit(BIPMOD, BIP_TASK_QUERY, MODULE,task_sql_query()); timer_set = set_perf_timer((char *)"TOTAL: charge estimation"); incr_perf_nest(); while (get_next_hq_group() != Failure) { prev_total_accounts = Total_accounts; if (get_account_ids(task_sql_query()) == Failure) { emit(BIPMOD, BIP_ACCOUNT_LIST_ERR); goto unlock_quit; } if (!process_log_initialized) { init_process_log_sys(); process_log_initialized = 1; } proc_work_upd(proclogmode,PROCLOG_PROCACC_KEY,NULL,PROCLOG_PROCACC_CV,Total_accounts,Total_successes+Total_in_error,Total_successes,Total_in_error); /* ** Load the static configuration data for the process. ** This function no-ops after being once loaded. */ set_large_db_notification_on(Thresh_for_large_db_op); if (load_static_data() == Failure) { set_large_db_notification_off(); goto unlock_quit; } set_large_db_notification_off(); /* ** Before entering the account list processing loop, check to ** see if a STOP command has been issued against the ** process; if not, set the peformance timer to measure the ** timer to calculate the bill for each account on the list. */ if (logout_requested() == ARB_STATUS_LOGOUT) goto unlock_quit; /* ** LOOP through the account list and estimate charge for ** each account (or otherwise process the account). */ while (!loop) { if (logout_requested() == ARB_STATUS_LOGOUT) goto unlock_quit; Invoice_status = Success; trname[0] = '\0'; Dboutput_transaction[0] = '\0'; if (get_next_account(Timer_on) == Failure) { /* * Normal break out of the loop is done here. */ break; } clear_account_info(); free_estimated_charges(); #ifdef MODULE_RCE /* clean Rce_contract_list * if necessary */ if (Rce_contract_list) free_rce_contract_list(); #endif Balance_ref_no = 0; Balance_ref_resets = 0; if (!In_transaction) In_transaction = TRUE; /* ** Calculate the bill for the account. Make Invoice_status ** and be non-resettable to Success after a ** previous failure. */ proc_work_resume(proclogmode,PROCLOG_BILLACC_KEY,NULL,PROCLOG_BILLACC_CV); status =rce_bill_account(); proc_work_incr(proclogmode,PROCLOG_BILLACC_KEY,NULL,PROCLOG_BILLACC_CV,0,0,0,0); proc_work_suspend(proclogmode,PROCLOG_BILLACC_KEY,NULL,PROCLOG_BILLACC_CV); if ((status == Success &&Invoice_status == Success) &&Estimated_charges) if (send_ths_message(dbupdate) != Success) Invoice_status=Failure; if (status != Success && Invoice_status == Success) Invoice_status = status; /* Commit and report each account * separately. */ commit_and_report(trname); /* This is the end of all accounts */ if (logout_requested() == ARB_STATUS_LOGOUT) { goto unlock_quit; } } } /* Finish the process logging */ if (process_log_initialized) { proc_work_end(proclogmode,PROCLOG_PROCACC_KEY,NULL,PROCLOG_PROCACC_CV,Total_accounts,Total_successes+Total_in_error,Total_successes,Total_in_error,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_BILLACC_KEY,NULL,PROCLOG_BILLACC_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,NULL,PROCLOG_BILLDATA_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_EQUPCHRG_KEY,NULL,PROCLOG_EQUPCHRG_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_RCS_KEY,NULL,PROCLOG_RCS_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_NRCS_KEY,NULL,PROCLOG_NRCS_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,PROCLOG_GETEQUIP_KEY,PROCLOG_GETEQUIP_CV,0,0,0,0,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,PROCLOG_RCDISC_KEY,PROCLOG_RCDISC_CV,0,0,0,0,PROCLOG_SUCCESS); } Proc_run_status = PROCLOG_SUCCESS; bNormalExit = TRUE; /* ** At this point, all accounts on the task list have been processed, * or we've bailed out due to an error. ** Log the results in various places: ** -Timing report to screen and activity log ** -Error/Success summary to activity log ** -Control report */ if (bip_per_task_log() != Success) { break; } /* ** Update the task status as completed in PROCESS_SCHED table. ** Free the memory associated with the accout list. */ if (wrapup_task(dbfetch) == Failure) { emit(BIPMOD, BIP_TASK_UPDATE_ERR); break; } clear_accounts(); /* * Shut down THS_Client */ if (bLoggedIntoTHS) Shutdown_SendToTHS (); if(message)free(message); } unlock_quit: /* ** At this point, the main process loop has been exited. Return ** the process state. */ /* If proc log timers still active then we have exited the loop above in error */ if (bNormalExit == FALSE ) { if (process_log_initialized) { proc_work_end(proclogmode,PROCLOG_PROCACC_KEY,NULL,PROCLOG_PROCACC_CV,Total_accounts,Total_successes+Total_in_error,Total_successes,Total_in_error,PROCLOG_SUCCESS); proc_work_incr_end(proclogmode,PROCLOG_BILLACC_KEY,NULL,PROCLOG_BILLACC_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,NULL,PROCLOG_BILLDATA_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_EQUPCHRG_KEY,NULL,PROCLOG_EQUPCHRG_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_RCS_KEY,NULL,PROCLOG_RCS_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_NRCS_KEY,NULL,PROCLOG_NRCS_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,PROCLOG_GETEQUIP_KEY,PROCLOG_GETEQUIP_CV,0,0,0,0,PROCLOG_ERROR); proc_work_incr_end(proclogmode,PROCLOG_BILLDATA_KEY,PROCLOG_RCDISC_KEY,PROCLOG_RCDISC_CV,0,0,0,0,PROCLOG_ERROR); } Proc_run_status = PROCLOG_ERROR; } arb_put_state(dbfetch, ARB_STATUS_LOGOUT); }
/* typically, main() does a couple of things: * 1) parse command line parameters, etc. * 2) Setup work environment. * 3) Setup real-time parameters. * 4) Transition to real-time mode. * 5) Invoke periodic or sporadic jobs. * 6) Transition to background mode. * 7) Clean up and exit. * * The following main() function provides the basic skeleton of a single-threaded * LITMUS^RT real-time task. In a real program, all the return values should be * checked for errors. */ int main(int argc, char** argv) { int do_exit; int PERIOD, EXEC_COST, CPU; int sCounter; int counter; int pCounter; int ret; /* The task is in background mode upon startup. */ /***** * 1) Command line paramter parsing would be done here. */ if (argc !=5){ fprintf(stderr, "Usage: base_task EXEC_COST PERIOD COUNTER CPU \n COUNTER: print info every COUNTER times called \n"); exit(1); } EXEC_COST = atoi(argv[1]); PERIOD = atoi(argv[2]); sCounter = atoi(argv[3]); CPU = atoi(argv[4]); /***** * 2) Work environment (e.g., global data structures, file data, etc.) would * be setup here. */ counter = 0; pCounter = 0; /***** * 3) Setup real-time parameters. * In this example, we create a sporadic task that does not specify a * target partition (and thus is intended to run under global scheduling). * If this were to execute under a partitioned scheduler, it would be assigned * to the first partition (since partitioning is performed offline). */ CALL( init_litmus() ); /* CALL( sporadic_global(EXEC_COST, PERIOD) ); */ /* To specify a partition, use sporadic_partitioned(). * Example: * * sporadic_partitioned(EXEC_COST, PERIOD, CPU); * * where CPU ranges from 0 to "Number of CPUs" - 1. */ CALL( sporadic_partitioned(EXEC_COST, PERIOD, CPU) ); /***** * 4) Transition to real-time mode. */ CALL( task_mode(LITMUS_RT_TASK) ); /* The task is now executing as a real-time task if the call didn't fail. */ this_rt_id = gettid(); ret = wait_for_ts_release(); /***** * 5) Invoke real-time jobs. */ do { /* Wait until the next job is released. */ sleep_next_period(); /* Invoke job. */ do_exit = job(&counter, &pCounter, sCounter ); } while (!do_exit); /***** * 6) Transition to background mode. */ CALL( task_mode(BACKGROUND_TASK) ); /***** * 7) Clean up, maybe print results and stats, and exit. */ return 0; }