void cond_test(void) { pthread_t waiter; pthread_t signaler; pthread_attr_t attr; #ifdef SDCC pthread_addr_t result; #endif struct sched_param sparam; int prio_min; int prio_max; int prio_mid; int status; /* Initialize the mutex */ printf("cond_test: Initializing mutex\n"); status = pthread_mutex_init(&mutex, NULL); if (status != 0) { printf("cond_test: ERROR pthread_mutex_init failed, status=%d\n", status); } /* Initialize the condition variable */ printf("cond_test: Initializing cond\n"); status = pthread_cond_init(&cond, NULL); if (status != 0) { printf("cond_test: ERROR pthread_condinit failed, status=%d\n", status); } /* Start the waiter thread at higher priority */ printf("cond_test: Starting waiter\n"); status = pthread_attr_init(&attr); if (status != 0) { printf("cond_test: pthread_attr_init failed, status=%d\n", status); } prio_min = sched_get_priority_min(SCHED_FIFO); prio_max = sched_get_priority_max(SCHED_FIFO); prio_mid = (prio_min + prio_max) / 2; sparam.sched_priority = prio_mid; status = pthread_attr_setschedparam(&attr,&sparam); if (status != OK) { printf("cond_test: pthread_attr_setschedparam failed, status=%d\n", status); } else { printf("cond_test: Set thread 1 priority to %d\n", sparam.sched_priority); } status = pthread_create(&waiter, &attr, thread_waiter, NULL); if (status != 0) { printf("cond_test: pthread_create failed, status=%d\n", status); } printf("cond_test: Starting signaler\n"); status = pthread_attr_init(&attr); if (status != 0) { printf("cond_test: pthread_attr_init failed, status=%d\n", status); } sparam.sched_priority = (prio_min + prio_mid) / 2; status = pthread_attr_setschedparam(&attr,&sparam); if (status != OK) { printf("cond_test: pthread_attr_setschedparam failed, status=%d\n", status); } else { printf("cond_test: Set thread 2 priority to %d\n", sparam.sched_priority); } status = pthread_create(&signaler, &attr, thread_signaler, NULL); if (status != 0) { printf("cond_test: pthread_create failed, status=%d\n", status); } /* Wait for the threads to stop */ #ifdef SDCC pthread_join(signaler, &result); #else pthread_join(signaler, NULL); #endif printf("cond_test: signaler terminated, now cancel the waiter\n"); pthread_detach(waiter); pthread_cancel(waiter); printf("cond_test: \tWaiter\tSignaler\n"); printf("cond_test: Loops\t%d\t%d\n", waiter_nloops, signaler_nloops); printf("cond_test: Errors\t%d\t%d\n", waiter_nerrors, signaler_nerrors); printf("cond_test:\n"); printf("cond_test: %d times, waiter did not have to wait for data\n", waiter_nloops - waiter_waits); printf("cond_test: %d times, data was already available when the signaler run\n", signaler_already); printf("cond_test: %d times, the waiter was in an unexpected state when the signaler ran\n", signaler_state); }
wxThreadError wxThread::Create(unsigned int WXUNUSED(stackSize)) { if ( m_internal->GetState() != STATE_NEW ) { // don't recreate thread return wxTHREAD_RUNNING; } // set up the thread attribute: right now, we only set thread priority pthread_attr_t attr; pthread_attr_init(&attr); #ifdef HAVE_THREAD_PRIORITY_FUNCTIONS int policy; if ( pthread_attr_getschedpolicy(&attr, &policy) != 0 ) { wxLogError(_("Cannot retrieve thread scheduling policy.")); } #ifdef __VMS__ /* the pthread.h contains too many spaces. This is a work-around */ # undef sched_get_priority_max #undef sched_get_priority_min #define sched_get_priority_max(_pol_) \ (_pol_ == SCHED_OTHER ? PRI_FG_MAX_NP : PRI_FIFO_MAX) #define sched_get_priority_min(_pol_) \ (_pol_ == SCHED_OTHER ? PRI_FG_MIN_NP : PRI_FIFO_MIN) #endif int max_prio = sched_get_priority_max(policy), min_prio = sched_get_priority_min(policy), prio = m_internal->GetPriority(); if ( min_prio == -1 || max_prio == -1 ) { wxLogError(_("Cannot get priority range for scheduling policy %d."), policy); } else if ( max_prio == min_prio ) { if ( prio != WXTHREAD_DEFAULT_PRIORITY ) { // notify the programmer that this doesn't work here wxLogWarning(_("Thread priority setting is ignored.")); } //else: we have default priority, so don't complain // anyhow, don't do anything because priority is just ignored } else { struct sched_param sp; if ( pthread_attr_getschedparam(&attr, &sp) != 0 ) { wxFAIL_MSG(_T("pthread_attr_getschedparam() failed")); } sp.sched_priority = min_prio + (prio*(max_prio - min_prio))/100; if ( pthread_attr_setschedparam(&attr, &sp) != 0 ) { wxFAIL_MSG(_T("pthread_attr_setschedparam(priority) failed")); } } #endif // HAVE_THREAD_PRIORITY_FUNCTIONS #ifdef HAVE_PTHREAD_ATTR_SETSCOPE // this will make the threads created by this process really concurrent if ( pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0 ) { wxFAIL_MSG(_T("pthread_attr_setscope(PTHREAD_SCOPE_SYSTEM) failed")); } #endif // HAVE_PTHREAD_ATTR_SETSCOPE // VZ: assume that this one is always available (it's rather fundamental), // if this function is ever missing we should try to use // pthread_detach() instead (after thread creation) if ( m_isDetached ) { if ( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 ) { wxFAIL_MSG(_T("pthread_attr_setdetachstate(DETACHED) failed")); } // never try to join detached threads m_internal->Detach(); } //else: threads are created joinable by default, it's ok // create the new OS thread object int rc = pthread_create ( m_internal->GetIdPtr(), &attr, wxPthreadStart, (void *)this ); if ( pthread_attr_destroy(&attr) != 0 ) { wxFAIL_MSG(_T("pthread_attr_destroy() failed")); } if ( rc != 0 ) { m_internal->SetState(STATE_EXITED); return wxTHREAD_NO_RESOURCE; } return wxTHREAD_NO_ERROR; }
static inline int nxtext_muinitialize(void) { struct sched_param param; pthread_t thread; pid_t servrid; int ret; /* Set the client task priority */ param.sched_priority = CONFIG_EXAMPLES_NXTEXT_CLIENTPRIO; ret = sched_setparam(0, ¶m); if (ret < 0) { printf("nxtext_initialize: sched_setparam failed: %d\n" , ret); g_exitcode = NXEXIT_SCHEDSETPARAM; return ERROR; } /* Start the server task */ printf("nxtext_initialize: Starting nxtext_server task\n"); servrid = task_create("NX Server", CONFIG_EXAMPLES_NXTEXT_SERVERPRIO, CONFIG_EXAMPLES_NXTEXT_STACKSIZE, nxtext_server, NULL); if (servrid < 0) { printf("nxtext_initialize: Failed to create nxtext_server task: %d\n", errno); g_exitcode = NXEXIT_TASKCREATE; return ERROR; } /* Wait a bit to let the server get started */ sleep(1); /* Connect to the server */ g_hnx = nx_connect(); if (g_hnx) { pthread_attr_t attr; /* Start a separate thread to listen for server events. This is probably * the least efficient way to do this, but it makes this example flow more * smoothly. */ (void)pthread_attr_init(&attr); param.sched_priority = CONFIG_EXAMPLES_NXTEXT_LISTENERPRIO; (void)pthread_attr_setschedparam(&attr, ¶m); (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXTEXT_STACKSIZE); ret = pthread_create(&thread, &attr, nxtext_listener, NULL); if (ret != 0) { printf("nxtext_initialize: pthread_create failed: %d\n", ret); g_exitcode = NXEXIT_PTHREADCREATE; return ERROR; } /* Don't return until we are connected to the server */ while (!g_connected) { /* Wait for the listener thread to wake us up when we really * are connected. */ (void)sem_wait(&g_semevent); } } else { printf("nxtext_initialize: nx_connect failed: %d\n", errno); g_exitcode = NXEXIT_NXCONNECT; return ERROR; } return OK; }
int main (int ac, char **av) { int err; char *cp, *progname = (char*)basename(av[0]), *rtdm_driver; struct sched_param param_square = {.sched_priority = 99 }; struct sched_param param_irq = {.sched_priority = 98 }; pthread_attr_t thattr_square, thattr_irq; period_ns = PERIOD; /* ns */ signal(SIGINT, cleanup_upon_sig); signal(SIGTERM, cleanup_upon_sig); signal(SIGHUP, cleanup_upon_sig); signal(SIGALRM, cleanup_upon_sig); while (--ac) { if ((cp = *++av) == NULL) break; if (*cp == '-' && *++cp) { switch(*cp) { case 'p' : period_ns = (unsigned long)atoi(*++av); break; case 'r' : rtdm_driver = *++av; break; default: usage(progname); break; } } else break; } // Display every 2 sec loop_prt = 2000000000 / period_ns; printf ("Using driver \"%s\" and period %d ns\n", rtdm_driver, period_ns); // Avoid paging: MANDATORY for RT !! mlockall(MCL_CURRENT|MCL_FUTURE); // Init rt_printf() system rt_print_auto_init(1); // Open RTDM driver if ((fd = rt_dev_open(rtdm_driver, 0)) < 0) { perror("rt_open"); exit(EXIT_FAILURE); } // Thread attributes pthread_attr_init(&thattr_square); // Joinable pthread_attr_setdetachstate(&thattr_square, PTHREAD_CREATE_JOINABLE); // Priority, set priority to 99 pthread_attr_setinheritsched(&thattr_square, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&thattr_square, SCHED_FIFO); pthread_attr_setschedparam(&thattr_square, ¶m_square); // Create thread(s) err = pthread_create(&thid_square, &thattr_square, &thread_square, NULL); if (err) { fprintf(stderr,"square: failed to create square thread, code %d\n",err); return 0; } // Thread attributes pthread_attr_init(&thattr_irq); // Priority, set priority to 98 pthread_attr_setinheritsched(&thattr_irq, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&thattr_irq, SCHED_FIFO); pthread_attr_setschedparam(&thattr_irq, ¶m_irq); err = pthread_create(&thid_irq, &thattr_irq, &thread_irq, NULL); if (err) { fprintf(stderr,"square: failed to create IRQ thread, code %d\n",err); return 0; } pause(); return 0; }
int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) { FAR char *argv[MAX_ARGV_ENTRIES]; FAR char *saveptr; FAR char *cmd; FAR char *redirfile = NULL; int fd = -1; int oflags = 0; int argc; int ret; /* Initialize parser state */ memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *)); #ifndef CONFIG_NSH_DISABLEBG vtbl->np.np_bg = false; #endif vtbl->np.np_redirect = false; /* Parse out the command at the beginning of the line */ saveptr = cmdline; cmd = nsh_argument(vtbl, &saveptr); /* Handler if-then-else-fi */ #ifndef CONFIG_NSH_DISABLESCRIPT if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0) { goto errout; } #endif /* Handle nice */ #ifndef CONFIG_NSH_DISABLEBG if (nsh_nice(vtbl, &cmd, &saveptr) != 0) { goto errout; } #endif /* Check if any command was provided -OR- if command processing is * currently disabled. */ #ifndef CONFIG_NSH_DISABLESCRIPT if (!cmd || !nsh_cmdenabled(vtbl)) #else if (!cmd) #endif { /* An empty line is not an error and an unprocessed command cannot * generate an error, but neither should they change the last * command status. */ return OK; } /* Parse all of the arguments following the command name. The form * of argv is: * * argv[0]: The command name. * argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS) * argv[argc-3]: Possibly '>' or '>>' * argv[argc-2]: Possibly <file> * argv[argc-1]: Possibly '&' * argv[argc]: NULL terminating pointer * * Maximum size is CONFIG_NSH_MAXARGUMENTS+5 */ argv[0] = cmd; for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++) { argv[argc] = nsh_argument(vtbl, &saveptr); if (!argv[argc]) { break; } } argv[argc] = NULL; /* Check if the command should run in background */ #ifndef CONFIG_NSH_DISABLEBG if (argc > 1 && strcmp(argv[argc-1], "&") == 0) { vtbl->np.np_bg = true; argv[argc-1] = NULL; argc--; } #endif /* Check if the output was re-directed using > or >> */ if (argc > 2) { /* Check for redirection to a new file */ if (strcmp(argv[argc-2], g_redirect1) == 0) { vtbl->np.np_redirect = true; oflags = O_WRONLY|O_CREAT|O_TRUNC; redirfile = nsh_getfullpath(vtbl, argv[argc-1]); argc -= 2; } /* Check for redirection by appending to an existing file */ else if (strcmp(argv[argc-2], g_redirect2) == 0) { vtbl->np.np_redirect = true; oflags = O_WRONLY|O_CREAT|O_APPEND; redirfile = nsh_getfullpath(vtbl, argv[argc-1]); argc -= 2; } } /* Check if the maximum number of arguments was exceeded */ if (argc > CONFIG_NSH_MAXARGUMENTS) { nsh_output(vtbl, g_fmttoomanyargs, cmd); } /* Does this command correspond to an application filename? * nsh_fileapp() returns: * * -1 (ERROR) if the application task corresponding to 'argv[0]' could not * be started (possibly because it doesn not exist). * 0 (OK) if the application task corresponding to 'argv[0]' was * and successfully started. If CONFIG_SCHED_WAITPID is * defined, this return value also indicates that the * application returned successful status (EXIT_SUCCESS) * 1 If CONFIG_SCHED_WAITPID is defined, then this return value * indicates that the application task was spawned successfully * but returned failure exit status. * * Note the priority if not effected by nice-ness. */ #ifdef CONFIG_NSH_FILE_APPS ret = nsh_fileapp(vtbl, argv[0], argv, redirfile, oflags); if (ret >= 0) { /* nsh_fileapp() returned 0 or 1. This means that the builtin * command was successfully started (although it may not have ran * successfully). So certainly it is not an NSH command. */ return nsh_saveresult(vtbl, ret != OK); } /* No, not a built in command (or, at least, we were unable to start a * builtin command of that name). Treat it like an NSH command. */ #endif /* Does this command correspond to a builtin command? * nsh_builtin() returns: * * -1 (ERROR) if the application task corresponding to 'argv[0]' could not * be started (possibly because it doesn not exist). * 0 (OK) if the application task corresponding to 'argv[0]' was * and successfully started. If CONFIG_SCHED_WAITPID is * defined, this return value also indicates that the * application returned successful status (EXIT_SUCCESS) * 1 If CONFIG_SCHED_WAITPID is defined, then this return value * indicates that the application task was spawned successfully * but returned failure exit status. * * Note the priority if not effected by nice-ness. */ #if defined(CONFIG_NSH_BUILTIN_APPS) && (!defined(CONFIG_NSH_FILE_APPS) || !defined(CONFIG_FS_BINFS)) ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags); if (ret >= 0) { /* nsh_builtin() returned 0 or 1. This means that the builtin * command was successfully started (although it may not have ran * successfully). So certainly it is not an NSH command. */ return nsh_saveresult(vtbl, ret != OK); } /* No, not a built in command (or, at least, we were unable to start a * builtin command of that name). Treat it like an NSH command. */ #endif /* Redirected output? */ if (vtbl->np.np_redirect) { /* Open the redirection file. This file will eventually * be closed by a call to either nsh_release (if the command * is executed in the background) or by nsh_undirect if the * command is executed in the foreground. */ fd = open(redirfile, oflags, 0666); nsh_freefullpath(redirfile); redirfile = NULL; if (fd < 0) { nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO); goto errout; } } /* Handle the case where the command is executed in background. * However is app is to be started as builtin new process will * be created anyway, so skip this step. */ #ifndef CONFIG_NSH_DISABLEBG if (vtbl->np.np_bg) { struct sched_param param; struct nsh_vtbl_s *bkgvtbl; struct cmdarg_s *args; pthread_attr_t attr; pthread_t thread; /* Get a cloned copy of the vtbl with reference count=1. * after the command has been processed, the nsh_release() call * at the end of nsh_child() will destroy the clone. */ bkgvtbl = nsh_clone(vtbl); if (!bkgvtbl) { goto errout_with_redirect; } /* Create a container for the command arguments */ args = nsh_cloneargs(bkgvtbl, fd, argc, argv); if (!args) { nsh_release(bkgvtbl); goto errout_with_redirect; } /* Handle redirection of output via a file descriptor */ if (vtbl->np.np_redirect) { (void)nsh_redirect(bkgvtbl, fd, NULL); } /* Get the execution priority of this task */ ret = sched_getparam(0, ¶m); if (ret != 0) { nsh_output(vtbl, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO); nsh_releaseargs(args); nsh_release(bkgvtbl); goto errout; } /* Determine the priority to execute the command */ if (vtbl->np.np_nice != 0) { int priority = param.sched_priority - vtbl->np.np_nice; if (vtbl->np.np_nice < 0) { int max_priority = sched_get_priority_max(SCHED_NSH); if (priority > max_priority) { priority = max_priority; } } else { int min_priority = sched_get_priority_min(SCHED_NSH); if (priority < min_priority) { priority = min_priority; } } param.sched_priority = priority; } /* Set up the thread attributes */ (void)pthread_attr_init(&attr); (void)pthread_attr_setschedpolicy(&attr, SCHED_NSH); (void)pthread_attr_setschedparam(&attr, ¶m); /* Execute the command as a separate thread at the appropriate priority */ ret = pthread_create(&thread, &attr, nsh_child, (pthread_addr_t)args); if (ret != 0) { nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", NSH_ERRNO_OF(ret)); nsh_releaseargs(args); nsh_release(bkgvtbl); goto errout; } nsh_output(vtbl, "%s [%d:%d]\n", cmd, thread, param.sched_priority); } else #endif { uint8_t save[SAVE_SIZE]; /* Handle redirection of output via a file descriptor */ if (vtbl->np.np_redirect) { nsh_redirect(vtbl, fd, save); } /* Then execute the command in "foreground" -- i.e., while the user waits * for the next prompt. nsh_execute will return: * * -1 (ERRROR) if the command was unsuccessful * 0 (OK) if the command was successful */ ret = nsh_execute(vtbl, argc, argv); /* Restore the original output. Undirect will close the redirection * file descriptor. */ if (vtbl->np.np_redirect) { nsh_undirect(vtbl, save); } /* Mark errors so that it is possible to test for non-zero return values * in nsh scripts. */ if (ret < 0) { goto errout; } } /* Return success if the command succeeded (or at least, starting of the * command task succeeded). */ return nsh_saveresult(vtbl, false); #ifndef CONFIG_NSH_DISABLEBG errout_with_redirect: if (vtbl->np.np_redirect) { close(fd); } #endif errout: return nsh_saveresult(vtbl, true); }
PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ) { PaError result = paNoError; pthread_attr_t attr; int started = 0; memset( self, 0, sizeof (PaUnixThread) ); PaUnixMutex_Initialize( &self->mtx ); PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 ); self->parentWaiting = 0 != waitForChild; /* Spawn thread */ /* Temporarily disabled since we should test during configuration for presence of required mman.h header */ #if 0 #if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1) if( rtSched ) { if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 ) { int savedErrno = errno; /* In case errno gets overwritten */ assert( savedErrno != EINVAL ); /* Most likely a programmer error */ PA_UNLESS( (savedErrno == EPERM), paInternalError ); PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ )); } else PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ )); } #endif #endif PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); /* Priority relative to other processes */ PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError ); started = 1; if( rtSched ) { #if 0 if( self->useWatchdog ) { int err; struct sched_param wdSpm = { 0 }; /* Launch watchdog, watchdog sets callback thread priority */ int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) ); wdSpm.sched_priority = prio; PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError ); PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError ); PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError ); if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) ) { PA_UNLESS( err == EPERM, paInternalError ); /* Permission error, go on without realtime privileges */ PA_DEBUG(( "Failed bumping priority\n" )); } else { int policy; self->watchdogRunning = 1; PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 ); /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */ if( wdSpm.sched_priority != prio ) { PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority )); PA_ENSURE( paInternalError ); } } } else #endif PA_ENSURE( BoostPriority( self ) ); { int policy; struct sched_param spm; pthread_getschedparam(self->thread, &policy, &spm); } } if( self->parentWaiting ) { PaTime till; struct timespec ts; int res = 0; PaTime now; PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); /* Wait for stream to be started */ now = PaUtil_GetTime(); till = now + waitForChild; while( self->parentWaiting && !res ) { if( waitForChild > 0 ) { ts.tv_sec = (time_t) floor( till ); ts.tv_nsec = (long) ((till - floor( till )) * 1e9); res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts ); } else { res = pthread_cond_wait( &self->cond, &self->mtx.mtx ); } } PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); PA_UNLESS( !res || ETIMEDOUT == res, paInternalError ); PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now )); if( ETIMEDOUT == res ) { PA_ENSURE( paTimedOut ); } } end: return result; error: if( started ) { PaUnixThread_Terminate( self, 0, NULL ); } goto end; }
int soundio_os_thread_create( void (*run)(void *arg), void *arg, void (*emit_rtprio_warning)(void), struct SoundIoOsThread ** out_thread) { *out_thread = NULL; struct SoundIoOsThread *thread = ALLOCATE(struct SoundIoOsThread, 1); if (!thread) { soundio_os_thread_destroy(thread); return SoundIoErrorNoMem; } thread->run = run; thread->arg = arg; #if defined(SOUNDIO_OS_WINDOWS) thread->handle = CreateThread(NULL, 0, run_win32_thread, thread, 0, &thread->id); if (!thread->handle) { soundio_os_thread_destroy(thread); return SoundIoErrorSystemResources; } if (emit_rtprio_warning) { if (!SetThreadPriority(thread->handle, THREAD_PRIORITY_TIME_CRITICAL)) { emit_rtprio_warning(); } } #else int err; if ((err = pthread_attr_init(&thread->attr))) { soundio_os_thread_destroy(thread); return SoundIoErrorNoMem; } thread->attr_init = true; if (emit_rtprio_warning) { int max_priority = sched_get_priority_max(SCHED_FIFO); if (max_priority == -1) { soundio_os_thread_destroy(thread); return SoundIoErrorSystemResources; } if ((err = pthread_attr_setschedpolicy(&thread->attr, SCHED_FIFO))) { soundio_os_thread_destroy(thread); return SoundIoErrorSystemResources; } struct sched_param param; param.sched_priority = max_priority; if ((err = pthread_attr_setschedparam(&thread->attr, ¶m))) { soundio_os_thread_destroy(thread); return SoundIoErrorSystemResources; } } if ((err = pthread_create(&thread->id, &thread->attr, run_pthread, thread))) { if (err == EPERM && emit_rtprio_warning) { emit_rtprio_warning(); err = pthread_create(&thread->id, NULL, run_pthread, thread); } if (err) { soundio_os_thread_destroy(thread); return SoundIoErrorNoMem; } } thread->running = true; #endif *out_thread = thread; return 0; }
/* ############################################## ##Int ModuleResize(Int argc, Char *argv[]) ############################################## */ Int ModuleResize(Int argc, Char *argv[]) { Uns initMask = 0; Int status = EXIT_SUCCESS; Rendezvous_Attrs rzvAttrs = Rendezvous_Attrs_DEFAULT; Fifo_Attrs fAttrs = Fifo_Attrs_DEFAULT; Rendezvous_Handle hRendezvousInit = NULL; Rendezvous_Handle hRendezvousWriter = NULL; Rendezvous_Handle hRendezvousCleanup = NULL; Int numThreads = 0; pthread_t id_listen[5] = {0}; Void *ret; char devicebuf[16] = {0}; CaptureEnv captureEnv; WriterEnv writerEnv; WriterEnv writerLowRateEnv; DetectEnv detectEnv; VideoEnv videoEnv; VideoEnv videoLowRateEnv;//dd VideoEnv LowRateResize; AudioEnv audioEnv; CtrlEnv ctrlEnv; char box_version[64] = {0}; OutputVideoInfo outputhandle; textinfo *texthandle; int DHCPVAL = 0, tmp = 0; char gateway[255] = {0}; struct sched_param schedParam; pthread_t captureThread; pthread_t detectThread; pthread_t writerThread; pthread_t writerLowThread; pthread_t videoThread; pthread_t audioThread; pthread_t videoLowThread; pthread_t resizeLowThread; #ifdef DSS_ENC_1100_1200 pthread_t webListenThread; #endif pthread_attr_t attr; int index = 0; int result = 0; char ts_version[128] = {0}; /* Zero out the thread environments */ Dmai_clear(captureEnv); Dmai_clear(writerEnv); Dmai_clear(videoEnv); Dmai_clear(audioEnv); Dmai_clear(ctrlEnv); mid_task_init(); trace_init(); open_gpio_port(); ts_build_get_version(ts_version, sizeof(ts_version)); strcpy(box_version, BOX_VER); strcat(box_version, CODE_TYPE); strcat(box_version, DEUBG); printf("[%s] Module Encode Program %s V%s\n", CODE_COND, BOARD_TYPE, box_version); printf("the build time is %s,the git vesion is %s.the ts version is %s\n\n", g_make_build_date, _VERSION, ts_version); initMutexPthread(); InitgblCommonMutex(); InitSysParams(); initOutputVideoParam(); InitHVTable(&gHVTable); // webgetDHCPFlag(tmp, &DHCPVAL); // readDHCPValue(DHCPCONFIG_FILE, &DHCPVAL); // setDHCPFlag(DHCPVAL); gLogoinfo = initLogoMod(); initTextinfo(); ReadEncodeParamTable(CONFIG_NAME, &gSysParaT); DHCPVAL = gSysParaT.sysPara.nTemp[0]; printf("----mic=%x:%x:%x:%x:%x:%x\n",gSysParaT.sysPara.szMacAddr[0],gSysParaT.sysPara.szMacAddr[1],gSysParaT.sysPara.szMacAddr[2], gSysParaT.sysPara.szMacAddr[3],gSysParaT.sysPara.szMacAddr[4],gSysParaT.sysPara.szMacAddr[5]); ReadLowbitParamTable(LOWBIT_PARAM, &gSysParaT); memset(&outputhandle, 0, sizeof(OutputVideoInfo)); getOutputvideohandle(&outputhandle); readOutputVideoParam(VIDEOENCODE_FILE, &outputhandle); setOutputvideohandle(&outputhandle); //sleep(10); ReadLogoinfo(LOGOCONFIGNAME, gLogoinfo); //setLogoInfoHandle(logoEnv); //sleep(10); texthandle = getTextInfoHandle(); readTextFromfile(ADDTEXT_FILE, texthandle); // DEBUG(DL_DEBUG, "%d,%d,%d,%d,%d,%d,%s\n", DHCPVAL, texthandle->xpos, texthandle->ypos, // texthandle->enable, texthandle->showtime, texthandle->alpha, texthandle->msgtext); // sleep(10); #ifdef DSS_ENC_1100_1200 ReadProtocolIni(PROTOCOL_NAME, &gProtocol); #endif ReadRemoteCtrlIndex(REMOTE_NAME, &index); /*Read I frames Interval*/ ReadIframeInterval(IFRAMES_NAME); /*green Save Module*/ app_init_green_adjust_module(); #ifdef CL4000_DVI app_init_screen_adjust_module(); #endif gblSetRemoteIndex(index); ReadHVTable(&gHVTable, 0); ReadHVTable(&gHVTable, 1); #ifdef CL4000_DVI_SDI ReadIPParamTable(IP_PARAM, &gSysParaT); #endif if(DHCPVAL) { printf("i will set dhcp.\n"); #if 1 system("kill -1 `cat /var/run/dhcpcd-eth0.pid`"); system("/sbin/dhcpcd eth0"); system("ifconfig eth0"); #endif gSysParaT.sysPara.dwNetMark = GetNetmask("eth0"); gSysParaT.sysPara.dwAddr = GetIPaddr("eth0"); get_gateway(gateway); gSysParaT.sysPara.dwGateWay = get_gateway(gateway); DEBUG(DL_DEBUG, "gateway =%s\n", gateway); } else { printf("i will set static ip.\n"); SetEthConfigIP(gSysParaT.sysPara.dwAddr, gSysParaT.sysPara.dwNetMark); SetEthConfigGW(gSysParaT.sysPara.dwGateWay); } system("ifconfig"); strcpy(gSysParaT.sysPara.strVer, box_version); initSetParam(); DEBUG(DL_DEBUG, "logo=%d text=%d ,texthandle->enable=%d,texthandle->showtime=%d\n", outputhandle.logo_show, outputhandle.text_show, texthandle->enable, texthandle->showtime); #ifdef DSS_ENC_1100_1200 /*open lcd initial*/ OpenLCDCom(); //matchbox ++ gblLoadIDX(); //matchbox ++ if(-2 == ReadDeviceType(DTYPECONFIG_NAME, 1)) { ReadDeviceType(DTYPECONFIG_NAME, 0); } GetDeviceType(devicebuf); DEBUG(DL_DEBUG, "DTYPECONFIG_NAME gDeviceType = %s\n", devicebuf); #endif /*取消PIPE坏的信号*/ Signal(SIGPIPE, SIG_IGN); /* Set the priority of this whole process to max (requires root) */ setpriority(PRIO_PROCESS, 0, -20); /*初始化高码流视频编码库参数*/ InitVideoEncParams(&gSysParaT.videoPara[PORT_ONE]); /*初始化低码流视频编码库参数*/ InitLowRateParams(&gSysParaT.videoPara[PORT_TWO]); /*初始化音频编码库参数*/ InitAudioEncParams(&gSysParaT.audioPara[PORT_ONE]); /* Initialize the mutex which protects the global data */ pthread_mutex_init(&gbl.mutex, NULL); /* Initialize Codec Engine runtime */ CERuntime_init(); /* Initialize Davinci Multimedia Application Interface */ Dmai_init(); closeWatchDog(); mid_timer_init(); initWatchDog(); #ifdef CL4000_DVI_SDI if(gblGetRemoteIndex() < MAX_FAR_CTRL_NUM) { result = InitRemoteStruct(gblGetRemoteIndex()); } gRemoteFD = CameraCtrlInit(PORT_COM2); if(gRemoteFD <= 0) { DEBUG(DL_ERROR, "Initial CameraCtrlInit() Error\n"); } #else #ifndef ENABLE_DEUBG if(gblGetRemoteIndex() < MAX_FAR_CTRL_NUM) { result = InitRemoteStruct(gblGetRemoteIndex()); } gRemoteFD = CameraCtrlInit(PORT_COM1); if(gRemoteFD <= 0) { DEBUG(DL_ERROR, "Initial CameraCtrlInit() Error\n"); } #endif #endif CreateTCPTask(id_listen); /* Initialize the logs. Must be done after CERuntime_init() */ /* if(TraceUtil_start(engine->engineName) != TRACEUTIL_SUCCESS) { ERR("Failed to TraceUtil_start\n"); cleanup(EXIT_FAILURE); } */ //initMask |= LOGSINITIALIZED; app_set_logoshow_flag(outputhandle.logo_show); app_set_textshow_flag(outputhandle.text_show) ; //setShowLogoTextFlag(outputhandle->logotext); addtextdisplay(texthandle); /* Determine the number of threads needing synchronization */ numThreads = 1; /*视频线程个数*/ numThreads += 7; /*音频线程个数*/ numThreads += 1; /* Create the objects which synchronizes the thread init and cleanup */ hRendezvousInit = Rendezvous_create(numThreads, &rzvAttrs); hRendezvousCleanup = Rendezvous_create(numThreads, &rzvAttrs); hRendezvousWriter = Rendezvous_create(3, &rzvAttrs); if(hRendezvousInit == NULL || hRendezvousCleanup == NULL || hRendezvousWriter == NULL) { ERR("Failed to create Rendezvous objects\n"); cleanup(EXIT_FAILURE); } /* Initialize the thread attributes */ if(pthread_attr_init(&attr)) { ERR("Failed to initialize thread attrs\n"); cleanup(EXIT_FAILURE); } /* Force the thread to use custom scheduling attributes */ if(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) { ERR("Failed to set schedule inheritance attribute\n"); cleanup(EXIT_FAILURE); } /* Set the thread to be fifo real time scheduled */ if(pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) { ERR("Failed to set FIFO scheduling policy\n"); cleanup(EXIT_FAILURE); } /* Create the capture fifos */ captureEnv.to_video_c = Fifo_create(&fAttrs); captureEnv.from_video_c = Fifo_create(&fAttrs); captureEnv.to_resize_c = Fifo_create(&fAttrs); captureEnv.from_resize_c = Fifo_create(&fAttrs); if(captureEnv.to_video_c == NULL || captureEnv.from_video_c == NULL || captureEnv.to_resize_c == NULL || captureEnv.from_resize_c == NULL) { ERR("Failed to open display fifos\n"); cleanup(EXIT_FAILURE); } LowRateResize.to_videoresize_c = Fifo_create(&fAttrs); LowRateResize.from_videoresize_c = Fifo_create(&fAttrs); if(LowRateResize.to_videoresize_c == NULL || LowRateResize.from_videoresize_c == NULL) { ERR("Failed to open Resize fifos\n"); cleanup(EXIT_FAILURE); } /* Set the capture thread priority */ schedParam.sched_priority = CAPTURE_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } /* Create the capture thread */ captureEnv.hRendezvousInit = hRendezvousInit; captureEnv.hRendezvousCleanup = hRendezvousCleanup; DEBUG(DL_DEBUG, "captureThrFxn thread!!!!\n"); if(pthread_create(&captureThread, &attr, captureThrFxn, &captureEnv)) { ERR("Failed to create capture thread\n"); cleanup(EXIT_FAILURE); } /* Create the writer fifos */ writerEnv.to_video_c = Fifo_create(&fAttrs); writerEnv.from_video_c = Fifo_create(&fAttrs); writerLowRateEnv.to_writelow_c = Fifo_create(&fAttrs); writerLowRateEnv.from_writelow_c = Fifo_create(&fAttrs); if(writerEnv.to_video_c == NULL || writerEnv.from_video_c == NULL || writerLowRateEnv.to_writelow_c == NULL || writerLowRateEnv.from_writelow_c == NULL) { ERR("Failed to open display fifos\n"); cleanup(EXIT_FAILURE); } initMask |= CAPTURETHREADCREATED ; /*detect thread*/ detectEnv.hRendezvousInit = hRendezvousInit; detectEnv.hRendezvousCleanup = hRendezvousCleanup; /* Set the video thread priority */ schedParam.sched_priority = DETECT_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } if(pthread_create(&detectThread, &attr, detectThrFxn, &detectEnv)) { ERR("Failed to create detect thread\n"); cleanup(EXIT_FAILURE); } initMask |= DETECTTHREADCREATED ; /* Set the video thread priority */ schedParam.sched_priority = VIDEO_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } DEBUG(DL_DEBUG, "videoThrFxn thread!!!!\n"); /* Create the video thread */ videoEnv.hRendezvousInit = hRendezvousInit; videoEnv.hRendezvousCleanup = hRendezvousCleanup; videoEnv.hRendezvousWriter = hRendezvousWriter; videoEnv.to_capture = captureEnv.from_video_c; videoEnv.from_capture = captureEnv.to_video_c; videoEnv.to_writer = writerEnv.from_video_c; videoEnv.from_writer = writerEnv.to_video_c; videoEnv.videoEncoder = engine->videoEncoders->codecName; videoEnv.engineName = engine->engineName; if(pthread_create(&videoThread, &attr, videoThrFxn, &videoEnv)) { ERR("Failed to create video thread\n"); cleanup(EXIT_FAILURE); } initMask |= VIDEOTHREADCREATED; /* Create the videoResize thread */ videoLowRateEnv.hRendezvousInit = hRendezvousInit; videoLowRateEnv.hRendezvousCleanup = hRendezvousCleanup; videoLowRateEnv.hRendezvousWriter = hRendezvousWriter; videoLowRateEnv.to_resize = LowRateResize.from_videoresize_c; videoLowRateEnv.from_resize = LowRateResize.to_videoresize_c; videoLowRateEnv.from_writer = writerLowRateEnv.to_writelow_c; videoLowRateEnv.to_writer = writerLowRateEnv.from_writelow_c; videoLowRateEnv.videoEncoder = engine->videoEncoders->codecName; videoLowRateEnv.engineName = engine->engineName; DEBUG(DL_DEBUG, "videoLowRateThrFxn thread!!!!\n"); if(pthread_create(&videoLowThread, &attr, videoLowRateThrFxn, &videoLowRateEnv)) { ERR("Failed to create video thread\n"); cleanup(EXIT_FAILURE); } initMask |= VIDEOLOWRATETHREAD; /* Create the video thread */ LowRateResize.hRendezvousInit = hRendezvousInit; LowRateResize.hRendezvousCleanup = hRendezvousCleanup; LowRateResize.hRendezvousWriter = hRendezvousWriter; LowRateResize.from_capture = captureEnv.to_resize_c; LowRateResize.to_capture = captureEnv.from_resize_c; LowRateResize.videoEncoder = engine->videoEncoders->codecName; LowRateResize.engineName = engine->engineName; /* Set the video thread priority */ schedParam.sched_priority = VIDEO_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } DEBUG(DL_DEBUG, "ResizeLowThrFxn thread!!!!\n"); if(pthread_create(&resizeLowThread, &attr, ResizeLowThrFxn, &LowRateResize)) { ERR("Failed to create video thread\n"); cleanup(EXIT_FAILURE); } initMask |= RESIZELOWRATETHREAD; Rendezvous_meet(hRendezvousWriter); /* Set the writer thread priority */ schedParam.sched_priority = WRITER_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } /* Create the writer thread */ writerEnv.hRendezvousInit = hRendezvousInit; writerEnv.hRendezvousCleanup = hRendezvousCleanup; writerEnv.outBufSize = videoEnv.outBufSize; DEBUG(DL_DEBUG, "writerThrFxn thread!!!!\n"); if(pthread_create(&writerThread, &attr, writerThrFxn, &writerEnv)) { ERR("Failed to create writer thread\n"); cleanup(EXIT_FAILURE); } initMask |= WRITERTHREADCREATED; /* Create the writer thread */ writerLowRateEnv.hRendezvousInit = hRendezvousInit; writerLowRateEnv.hRendezvousCleanup = hRendezvousCleanup; writerLowRateEnv.outBufSize = videoLowRateEnv.outBufSize; DEBUG(DL_DEBUG, "writerLowThrFxn thread!!!!\n"); if(pthread_create(&writerLowThread, &attr, writerLowThrFxn, &writerLowRateEnv)) { ERR("Failed to create writerResize thread\n"); cleanup(EXIT_FAILURE); } initMask |= WRITELOWRATETHREAD; /* Set the thread priority */ schedParam.sched_priority = AUDIO_THREAD_PRIORITY; if(pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } DEBUG(DL_DEBUG, "Audio thread Function!!!!\n"); /* Create the audio thread */ audioEnv.hRendezvousInit = hRendezvousInit; audioEnv.hRendezvousCleanup = hRendezvousCleanup; audioEnv.engineName = engine->engineName; audioEnv.audioEncoder = engine->audioEncoders->codecName; if(pthread_create(&audioThread, &attr, audioThrFxn, &audioEnv)) { ERR("Failed to create speech thread\n"); cleanup(EXIT_FAILURE); } initMask |= AUDIOTHREADCREATED; #ifdef DSS_ENC_1100_1200 if(pthread_create(&webListenThread, &attr, weblistenThrFxn, NULL)) { ERR("Failed to create web listen thread\n"); cleanup(EXIT_FAILURE); } initMask |= WEBLISTENCREATED; #endif /* Main thread becomes the control thread */ ctrlEnv.hRendezvousInit = hRendezvousInit; ctrlEnv.hRendezvousCleanup = hRendezvousCleanup; ctrlEnv.engineName = engine->engineName; ret = ctrlThrFxn(&ctrlEnv); if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } DEBUG(DL_DEBUG, "Exit All Thread!!\n"); cleanup: /* Make sure the other threads aren't waiting for init to complete */ if(hRendezvousWriter) { Rendezvous_force(hRendezvousWriter); } if(hRendezvousInit) { Rendezvous_force(hRendezvousInit); } DEBUG(DL_DEBUG, "EXIT Common Mutex!!!\n"); DestorygblCommonMutex(); DEBUG(DL_DEBUG, "EXIT pthread Mutex!!!\n"); DestroyMutexPthread(); if(initMask & AUDIOTHREADCREATED) { if(pthread_join(audioThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } DEBUG(DL_DEBUG, "EXIT audio pThread!!!\n"); if(initMask & VIDEOTHREADCREATED) { if(pthread_join(videoThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } DEBUG(DL_DEBUG, "EXIT video pThread!!!\n"); if(initMask & WRITERTHREADCREATED) { if(pthread_join(writerThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } DEBUG(DL_DEBUG, "EXIT write pThread!!!\n"); if(initMask & CAPTURETHREADCREATED) { if(pthread_join(captureThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } DEBUG(DL_DEBUG, "EXIT capture pThread!!!\n"); if(initMask & VIDEOLOWRATETHREAD) { if(pthread_join(videoLowThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } if(initMask & RESIZELOWRATETHREAD) { if(pthread_join(resizeLowThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } if(initMask & WRITELOWRATETHREAD) { if(pthread_join(writerLowThread, &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } if(pthread_join(id_listen[PORT_ONE], &ret) == 0) { if(ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } if(captureEnv.to_video_c) { Fifo_delete(captureEnv.to_video_c); } if(captureEnv.from_video_c) { Fifo_delete(captureEnv.from_video_c); } if(captureEnv.to_resize_c) { Fifo_delete(captureEnv.to_resize_c); } if(captureEnv.from_resize_c) { Fifo_delete(captureEnv.from_resize_c); } if(writerEnv.to_video_c) { Fifo_delete(writerEnv.to_video_c); } if(writerEnv.from_video_c) { Fifo_delete(writerEnv.from_video_c); } if(writerLowRateEnv.from_writelow_c) { Fifo_delete(writerLowRateEnv.from_video_c); } if(writerLowRateEnv.to_writelow_c) { Fifo_delete(writerLowRateEnv.to_writelow_c); } if(LowRateResize.to_videoresize_c) { Fifo_delete(LowRateResize.to_videoresize_c); } if(LowRateResize.from_videoresize_c) { Fifo_delete(LowRateResize.from_videoresize_c); } DEBUG(DL_DEBUG, "EXIT Rendezvous cleanup pThread!!!\n"); if(hRendezvousCleanup) { Rendezvous_delete(hRendezvousCleanup); } DEBUG(DL_DEBUG, "EXIT Rendezvous init pThread!!!\n"); if(hRendezvousInit) { Rendezvous_delete(hRendezvousInit); } DEBUG(DL_DEBUG, "EXIT Rendezvous cleanup pThread!!!\n"); /* if (initMask & LOGSINITIALIZED) { TraceUtil_stop(); } */ DEBUG(DL_DEBUG, "EXIT TraceUtil_stop !!!\n"); pthread_mutex_destroy(&gbl.mutex); DEBUG(DL_DEBUG, "process EXIT!!!\n"); exit(1); }
px4_task_t px4_task_spawn_cmd(const char *name, int scheduler, int priority, int stack_size, px4_main_t entry, char *const argv[]) { int i; int argc = 0; unsigned int len = 0; struct sched_param param = {}; char *p = (char *)argv; // Calculate argc while (p != (char *)nullptr) { p = argv[argc]; if (p == (char *)nullptr) { break; } ++argc; len += strlen(p) + 1; } unsigned long structsize = sizeof(pthdata_t) + (argc + 1) * sizeof(char *); // not safe to pass stack data to the thread creation pthdata_t *taskdata = (pthdata_t *)malloc(structsize + len); if (taskdata == nullptr) { return -ENOMEM; } memset(taskdata, 0, structsize + len); unsigned long offset = ((unsigned long)taskdata) + structsize; strncpy(taskdata->name, name, 16); taskdata->name[15] = 0; taskdata->entry = entry; taskdata->argc = argc; for (i = 0; i < argc; i++) { PX4_DEBUG("arg %d %s\n", i, argv[i]); taskdata->argv[i] = (char *)offset; strcpy((char *)offset, argv[i]); offset += strlen(argv[i]) + 1; } // Must add NULL at end of argv taskdata->argv[argc] = (char *)nullptr; PX4_DEBUG("starting task %s", name); pthread_attr_t attr; int rv = pthread_attr_init(&attr); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to init thread attrs"); free(taskdata); return (rv < 0) ? rv : -rv; } #ifndef __PX4_DARWIN if (stack_size < PTHREAD_STACK_MIN) { stack_size = PTHREAD_STACK_MIN; } rv = pthread_attr_setstacksize(&attr, PX4_STACK_ADJUSTED(stack_size)); if (rv != 0) { PX4_ERR("pthread_attr_setstacksize to %d returned error (%d)", stack_size, rv); pthread_attr_destroy(&attr); free(taskdata); return (rv < 0) ? rv : -rv; } #endif rv = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to set inherit sched"); pthread_attr_destroy(&attr); free(taskdata); return (rv < 0) ? rv : -rv; } rv = pthread_attr_setschedpolicy(&attr, scheduler); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to set sched policy"); pthread_attr_destroy(&attr); free(taskdata); return (rv < 0) ? rv : -rv; } #ifdef __PX4_CYGWIN /* Priorities on Windows are defined a lot differently */ priority = SCHED_PRIORITY_DEFAULT; #endif param.sched_priority = priority; rv = pthread_attr_setschedparam(&attr, ¶m); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to set sched param"); pthread_attr_destroy(&attr); free(taskdata); return (rv < 0) ? rv : -rv; } pthread_mutex_lock(&task_mutex); px4_task_t taskid = 0; for (i = 0; i < PX4_MAX_TASKS; ++i) { if (!taskmap[i].isused) { taskmap[i].name = name; taskmap[i].isused = true; taskid = i; break; } } if (i >= PX4_MAX_TASKS) { pthread_attr_destroy(&attr); pthread_mutex_unlock(&task_mutex); free(taskdata); return -ENOSPC; } rv = pthread_create(&taskmap[taskid].pid, &attr, &entry_adapter, (void *) taskdata); if (rv != 0) { if (rv == EPERM) { //printf("WARNING: NOT RUNING AS ROOT, UNABLE TO RUN REALTIME THREADS\n"); rv = pthread_create(&taskmap[taskid].pid, nullptr, &entry_adapter, (void *) taskdata); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to create thread %d %d\n", rv, errno); taskmap[taskid].isused = false; pthread_attr_destroy(&attr); pthread_mutex_unlock(&task_mutex); free(taskdata); return (rv < 0) ? rv : -rv; } } else { pthread_attr_destroy(&attr); pthread_mutex_unlock(&task_mutex); free(taskdata); return (rv < 0) ? rv : -rv; } } pthread_attr_destroy(&attr); pthread_mutex_unlock(&task_mutex); return taskid; }
void timedwait_test(void) { pthread_t waiter; pthread_attr_t attr; struct sched_param sparam; void *result; int prio_max; int status; /* Initialize the mutex */ printf("thread_waiter: Initializing mutex\n"); status = pthread_mutex_init(&mutex, NULL); if (status != 0) { printf("timedwait_test: ERROR pthread_mutex_init failed, status=%d\n", status); } /* Initialize the condition variable */ printf("timedwait_test: Initializing cond\n"); status = pthread_cond_init(&cond, NULL); if (status != 0) { printf("timedwait_test: ERROR pthread_condinit failed, status=%d\n", status); } /* Start the waiter thread at higher priority */ printf("timedwait_test: Starting waiter\n"); status = pthread_attr_init(&attr); if (status != 0) { printf("timedwait_test: pthread_attr_init failed, status=%d\n", status); } prio_max = sched_get_priority_max(SCHED_FIFO); status = sched_getparam(getpid(), &sparam); if (status != 0) { printf("timedwait_test: sched_getparam failed\n"); sparam.sched_priority = PTHREAD_DEFAULT_PRIORITY; } sparam.sched_priority = (prio_max + sparam.sched_priority) / 2; status = pthread_attr_setschedparam(&attr, &sparam); if (status != OK) { printf("timedwait_test: pthread_attr_setschedparam failed, status=%d\n", status); } else { printf("timedwait_test: Set thread 2 priority to %d\n", sparam.sched_priority); } status = pthread_create(&waiter, &attr, thread_waiter, NULL); if (status != 0) { printf("timedwait_test: pthread_create failed, status=%d\n", status); } printf("timedwait_test: Joining\n"); FFLUSH(); status = pthread_join(waiter, &result); if (status != 0) { printf("timedwait_test: ERROR pthread_join failed, status=%d\n", status); } else { printf("timedwait_test: waiter exited with result=%p\n", result); } }
static int parsecfg(xmlDocPtr doc, xmlNodePtr node, struct state *state, unsigned int *schedrr) { xmlNodePtr audio = NULL; xmlNodePtr ptt = NULL; const char *par[MAXPAR]; struct modemchannel *chan; pthread_attr_t rxattr; size_t stacksize; unsigned int samplerate = 5000, mode; for (; node; node = node->next) { if (node->type != XML_ELEMENT_NODE) continue; if (!node->name) logprintf(MLOG_FATAL, "Node has no name\n"); if (!strcmp(node->name, "audio")) { audio = node; continue; } if (!strcmp(node->name, "ptt")) { ptt = node; continue; } if (!strcmp(node->name, "chaccess")) { getparam(doc, node, chaccparams, par); if (par[0]) state->chacc.txdelay = strtoul(par[0], NULL, 0); if (par[1]) state->chacc.slottime = strtoul(par[1], NULL, 0); if (par[2]) state->chacc.ppersist = strtoul(par[2], NULL, 0); if (par[3]) state->chacc.fullduplex = !!strtoul(par[3], NULL, 0); if (par[4]) state->chacc.txtail = strtoul(par[4], NULL, 0); continue; } if (!strcmp(node->name, "channel")) { if (node->children) parsechannel(doc, node->children, state, &samplerate); continue; } logprintf(MLOG_ERROR, "unknown node \"%s\"\n", node->name); } /* find audio mode */ mode = 0; for (chan = state->channels; chan; chan = chan->next) { if (chan->demod && chan->demod->demodulate) mode |= IO_RDONLY; if (chan->mod && chan->mod->modulate) mode |= IO_WRONLY; } if (!state->channels || !mode) { logprintf(MLOG_ERROR, "no channels configured\n"); return -1; } /* open PTT */ getparam(doc, ptt, pttparams, par); if (pttinit(&state->ptt, par)) logprintf(MLOG_ERROR, "cannot start PTT output\n"); /* open audio */ getparam(doc, audio, ioparam_type, par); if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[1])) { getparam(doc, audio, ioparams_filein, par); state->audioio = ioopen_filein(&samplerate, IO_RDONLY, par); if (schedrr) *schedrr = 0; } else if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[2])) { getparam(doc, audio, ioparams_sim, par); state->audioio = ioopen_sim(&samplerate, IO_RDWR, par); if (schedrr) *schedrr = 0; #ifdef HAVE_ALSA } else if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[3])) { getparam(doc, audio, ioparams_alsasoundcard, par); state->audioio = ioopen_alsasoundcard(&samplerate, mode, par); #endif /* HAVE_ALSA */ } else { getparam(doc, audio, ioparams_soundcard, par); state->audioio = ioopen_soundcard(&samplerate, mode, par); } if (!state->audioio) logprintf(MLOG_FATAL, "cannot start audio\n"); for (chan = state->channels; chan; chan = chan->next) { if (chan->demod) { chan->demod->init(chan->demodstate, samplerate, &chan->rxbitrate); if (pthread_attr_init(&rxattr)) logerr(MLOG_FATAL, "pthread_attr_init"); /* needed on FreeBSD, according to [email protected] */ if (pthread_attr_getstacksize(&rxattr, &stacksize)) logerr(MLOG_ERROR, "pthread_attr_getstacksize"); else if (stacksize < 256*1024) if (pthread_attr_setstacksize(&rxattr, 256*1024)) logerr(MLOG_ERROR, "pthread_attr_setstacksize"); #ifdef HAVE_SCHED_H if (schedrr && *schedrr) { struct sched_param schp; memset(&schp, 0, sizeof(schp)); schp.sched_priority = sched_get_priority_min(SCHED_RR)+1; if (pthread_attr_setschedpolicy(&rxattr, SCHED_RR)) logerr(MLOG_ERROR, "pthread_attr_setschedpolicy"); if (pthread_attr_setschedparam(&rxattr, &schp)) logerr(MLOG_ERROR, "pthread_attr_setschedparam"); } #endif /* HAVE_SCHED_H */ if (pthread_create(&chan->rxthread, &rxattr, demodthread, chan)) logerr(MLOG_FATAL, "pthread_create"); pthread_attr_destroy(&rxattr); } if (chan->mod) chan->mod->init(chan->modstate, samplerate); } return 0; }
int Start(bool realtime) { pthread_attr_t attributes; struct sched_param rt_param; pthread_attr_init(&attributes); int priority = 60; // TODO int res; if (realtime) { fRealTime = true; }else { fRealTime = getenv("OMP_REALTIME") ? strtol(getenv("OMP_REALTIME"), NULL, 10) : true; } if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) { printf("Cannot request joinable thread creation for real-time thread res = %d err = %s\n", res, strerror(errno)); return -1; } if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) { printf("Cannot set scheduling scope for real-time thread res = %d err = %s\n", res, strerror(errno)); return -1; } if (realtime) { if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno)); return -1; } if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { printf("Cannot set RR scheduling class for RT thread res = %d err = %s\n", res, strerror(errno)); return -1; } memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { printf("Cannot set scheduling priority for RT thread res = %d err = %s\n", res, strerror(errno)); return -1; } } else { if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_INHERIT_SCHED))) { printf("Cannot request explicit scheduling for RT thread res = %d err = %s\n", res, strerror(errno)); return -1; } } if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { printf("Cannot set thread stack size res = %d err = %s\n", res, strerror(errno)); return -1; } if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) { printf("Cannot create thread res = %d err = %s\n", res, strerror(errno)); return -1; } // Set affinity set_affinity(fThread, fNumThread + 1); pthread_attr_destroy(&attributes); return 0; }
Thread::Thread(int pri, size_t stack): _cancel(cancelDefault), _start(NULL), priv(new ThreadImpl(threadTypeNormal)) { #ifdef WIN32 if(!_main) { _self.setKey(NULL); _main = this; setName("main()"); } else #ifdef WIN32 _name[0] = 0; #else snprintf(_name, sizeof(_name), "%d", getId()); #endif _parent = Thread::get(); if(_parent) priv->_throw = _parent->priv->_throw; else _parent = this; priv->_cancellation = CreateEvent(NULL, TRUE, FALSE, NULL); if(!priv->_cancellation) THROW(this); if(stack <= _autostack) priv->_stack = 0; else priv->_stack = stack; if(pri > 2) pri = 2; if(pri < -2) pri = -2; if(Process::isRealtime() && pri < 0) pri = 0; switch(pri) { case 1: priv->_priority = THREAD_PRIORITY_ABOVE_NORMAL; break; case -1: priv->_priority = THREAD_PRIORITY_BELOW_NORMAL; break; case 2: priv->_priority = THREAD_PRIORITY_HIGHEST; break; case -2: priv->_priority = THREAD_PRIORITY_LOWEST; break; default: priv->_priority = THREAD_PRIORITY_NORMAL; } #else int salign; pthread_attr_init(&priv->_attr); pthread_attr_setdetachstate(&priv->_attr, PTHREAD_CREATE_JOINABLE); #ifdef PTHREAD_STACK_MIN if(stack && stack <= _autostack) pthread_attr_setstacksize(&priv->_attr, _autostack); else if(stack > _autostack) { if(stack < PTHREAD_STACK_MIN) stack = PTHREAD_STACK_MIN; else // align to nearest min boundry { salign = stack / PTHREAD_STACK_MIN; if(stack % PTHREAD_STACK_MIN) ++salign; stack = salign * PTHREAD_STACK_MIN; } if(stack && pthread_attr_setstacksize(&priv->_attr, stack)) { #ifdef CCXX_EXCEPTIONS switch(Thread::getException()) { case throwObject: throw(this); return; #ifdef COMMON_STD_EXCEPTION case throwException: throw(ThrException("no stack space")); return; #endif default: return; } #else return; #endif } } #endif #ifndef __FreeBSD__ #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING #ifdef HAVE_SCHED_GETSCHEDULER #define __HAS_PRIORITY_SCHEDULING__ if(pri < 0 && Process::isRealtime()) pri = 0; if(pri) { struct sched_param sched; int policy; policy = sched_getscheduler(0); if(policy < 0) { #ifdef CCXX_EXCEPTIONS switch(Thread::getException()) { case throwObject: throw(this); return; #ifdef COMMON_STD_EXCEPTION case throwException: throw(ThrException("invalid scheduler")); return; #endif default: return; } #else return; #endif } sched_getparam(0, &sched); pri = sched.sched_priority - pri; if(pri > sched_get_priority_max(policy)) pri = sched_get_priority_max(policy); if(pri < sched_get_priority_min(policy)) pri = sched_get_priority_min(policy); sched.sched_priority = pri; pthread_attr_setschedpolicy(&priv->_attr, policy); pthread_attr_setschedparam(&priv->_attr, &sched); } #endif // ifdef HAVE_SCHED_GETSCHEDULER #endif // ifdef _POSIX_THREAD_PRIORITY_SCHEDULING #endif // ifndef __FreeBSD__ #ifdef __HAS_PRIORITY_SCHEDULING__ if(!pri) pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED); #else pthread_attr_setinheritsched(&priv->_attr, PTHREAD_INHERIT_SCHED); #endif _parent = getThread(); priv->_throw = _parent->priv->_throw; _cancel = cancelInitial; #endif // WIN32 }
//rtems_task Init(rtems_task_argument Argument) void *POSIX_Init(void *argument) { pthread_attr_t threadAttr; pthread_t theThread; struct sched_param sched_param; size_t stack_size; int result; char data[1000]; memset(data, 1, sizeof(data)); /* Set the TOD clock, so that gettimeofday() will work */ rtems_time_of_day fakeTime = { 2006, 3, 15, 17, 30, 0, 0 }; if (RTEMS_SUCCESSFUL != rtems_clock_set(&fakeTime)) { assert(0); } /* Bring up the network stack so we can run the socket tests. */ initialize_network(); /* Start a POSIX thread for pjlib_test_main(), since that's what it * thinks it is running in. */ /* Initialize attribute */ TEST( pthread_attr_init(&threadAttr) ); /* Looks like the rest of the attributes must be fully initialized too, * or otherwise pthread_create will return EINVAL. */ /* Specify explicit scheduling request */ TEST( pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED)); /* Timeslicing is needed by thread test, and this is accomplished by * SCHED_RR. */ TEST( pthread_attr_setschedpolicy(&threadAttr, SCHED_RR)); /* Set priority */ TEST( pthread_attr_getschedparam(&threadAttr, &sched_param)); sched_param.sched_priority = NETWORK_STACK_PRIORITY - 10; TEST( pthread_attr_setschedparam(&threadAttr, &sched_param)); /* Must have sufficient stack size (large size is needed by * logger, because default settings for logger is to use message buffer * from the stack). */ TEST( pthread_attr_getstacksize(&threadAttr, &stack_size)); if (stack_size < 8192) TEST( pthread_attr_setstacksize(&threadAttr, 8192)); /* Create the thread for application */ result = pthread_create(&theThread, &threadAttr, &pjlib_test_main, NULL); if (result != 0) { my_perror(PJ_STATUS_FROM_OS(result), "Error creating pjlib_test_main thread"); assert(!"Error creating main thread"); } return NULL; }
/* globally initialze the runtime system * NOTE: this is NOT thread safe and must not be called concurrently. If that * ever poses a problem, we may use proper mutex calls - not considered needed yet. * If ppErrObj is provided, it receives a char pointer to the name of the object that * caused the problem (if one occured). The caller must never free this pointer. If * ppErrObj is NULL, no such information will be provided. pObjIF is the pointer to * the "obj" object interface, which may be used to query any other rsyslog objects. * rgerhards, 2008-04-16 */ rsRetVal rsrtInit(char **ppErrObj, obj_if_t *pObjIF) { DEFiRet; if(iRefCount == 0) { /* init runtime only if not yet done */ #ifdef HAVE_PTHREAD_SETSCHEDPARAM CHKiRet(pthread_getschedparam(pthread_self(), &default_thr_sched_policy, &default_sched_param)); CHKiRet(pthread_attr_init(&default_thread_attr)); CHKiRet(pthread_attr_setschedpolicy(&default_thread_attr, default_thr_sched_policy)); CHKiRet(pthread_attr_setschedparam(&default_thread_attr, &default_sched_param)); CHKiRet(pthread_attr_setinheritsched(&default_thread_attr, PTHREAD_EXPLICIT_SCHED)); #endif if(ppErrObj != NULL) *ppErrObj = "obj"; CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */ CHKiRet(objGetObjInterface(pObjIF)); /* this provides the root pointer for all other queries */ /* initialize core classes. We must be very careful with the order of events. Some * classes use others and if we do not initialize them in the right order, we may end * up with an invalid call. The most important thing that can happen is that an error * is detected and needs to be logged, wich in turn requires a broader number of classes * to be available. The solution is that we take care in the order of calls AND use a * class immediately after it is initialized. And, of course, we load those classes * first that we use ourselfs... -- rgerhards, 2008-03-07 */ if(ppErrObj != NULL) *ppErrObj = "statsobj"; CHKiRet(statsobjClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "prop"; CHKiRet(propClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "glbl"; CHKiRet(glblClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "msg"; CHKiRet(msgClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "ruleset"; CHKiRet(rulesetClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "wti"; CHKiRet(wtiClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "wtp"; CHKiRet(wtpClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "queue"; CHKiRet(qqueueClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "conf"; CHKiRet(confClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "parser"; CHKiRet(parserClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "strgen"; CHKiRet(strgenClassInit(NULL)); if(ppErrObj != NULL) *ppErrObj = "rsconf"; CHKiRet(rsconfClassInit(NULL)); /* dummy "classes" */ if(ppErrObj != NULL) *ppErrObj = "str"; CHKiRet(strInit()); } ++iRefCount; dbgprintf("rsyslog runtime initialized, version %s, current users %d\n", VERSION, iRefCount); finalize_it: RETiRet; }
void *POSIX_Init( void *argument ) { int i; int status; pthread_t threadId; pthread_attr_t attr; struct sched_param param; puts( "\n\n*** POSIX TIME TEST @UPPER@ ***" ); /* * Deliberately create the XXX BEFORE the threads. This way the * threads should preempt this thread and block as they are created. */ status = 0; /* XXX create resource */ rtems_test_assert( status == 0 ); /* * Obtain the XXX so the threads will block. */ status = 0; /* XXX lock resource to ensure thread blocks */ rtems_test_assert( status == 0 ); /* * Now lower our priority */ status = pthread_attr_init( &attr ); rtems_test_assert( status == 0 ); status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); rtems_test_assert( status == 0 ); status = pthread_attr_setschedpolicy( &attr, SCHED_RR ); rtems_test_assert( status == 0 ); param.sched_priority = 2; status = pthread_attr_setschedparam( &attr, ¶m ); rtems_test_assert( status == 0 ); /* * And create rest of threads as more important than we are. They * will preempt us as they are created and block. */ for ( i=0 ; i < OPERATION_COUNT ; i++ ) { param.sched_priority = 3 + i; status = pthread_attr_setschedparam( &attr, ¶m ); rtems_test_assert( status == 0 ); status = pthread_create( &threadId, &attr, (i == OPERATION_COUNT - 1) ? Low : Middle, NULL ); rtems_test_assert( status == 0 ); } /* * Now start the timer which will be stopped in Low */ benchmark_timer_initialize(); status = 0; /* XXX release the resource. Threads unblock and preempt */ /* thread switch occurs */ /* should never return */ rtems_test_assert( FALSE ); return NULL; }
px4_task_t px4_task_spawn_cmd(const char *name, int scheduler, int priority, int stack_size, px4_main_t entry, char * const argv[]) { int rv; int argc = 0; int i; unsigned int len = 0; unsigned long offset; unsigned long structsize; char * p = (char *)argv; pthread_t task; pthread_attr_t attr; struct sched_param param; // Calculate argc while (p != (char *)0) { p = argv[argc]; if (p == (char *)0) break; ++argc; len += strlen(p)+1; } structsize = sizeof(pthdata_t)+(argc+1)*sizeof(char *); pthdata_t *taskdata; // not safe to pass stack data to the thread creation taskdata = (pthdata_t *)malloc(structsize+len); offset = ((unsigned long)taskdata)+structsize; taskdata->entry = entry; taskdata->argc = argc; for (i=0; i<argc; i++) { printf("arg %d %s\n", i, argv[i]); taskdata->argv[i] = (char *)offset; strcpy((char *)offset, argv[i]); offset+=strlen(argv[i])+1; } // Must add NULL at end of argv taskdata->argv[argc] = (char *)0; rv = pthread_attr_init(&attr); if (rv != 0) { PX4_WARN("px4_task_spawn_cmd: failed to init thread attrs"); return (rv < 0) ? rv : -rv; } rv = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (rv != 0) { PX4_WARN("px4_task_spawn_cmd: failed to set inherit sched"); return (rv < 0) ? rv : -rv; } rv = pthread_attr_setschedpolicy(&attr, scheduler); if (rv != 0) { PX4_WARN("px4_task_spawn_cmd: failed to set sched policy"); return (rv < 0) ? rv : -rv; } param.sched_priority = priority; rv = pthread_attr_setschedparam(&attr, ¶m); if (rv != 0) { PX4_WARN("px4_task_spawn_cmd: failed to set sched param"); return (rv < 0) ? rv : -rv; } rv = pthread_create (&task, &attr, &entry_adapter, (void *) taskdata); if (rv != 0) { if (rv == EPERM) { //printf("WARNING: NOT RUNING AS ROOT, UNABLE TO RUN REALTIME THREADS\n"); rv = pthread_create (&task, NULL, &entry_adapter, (void *) taskdata); if (rv != 0) { PX4_ERR("px4_task_spawn_cmd: failed to create thread %d %d\n", rv, errno); return (rv < 0) ? rv : -rv; } } else { return (rv < 0) ? rv : -rv; } } for (i=0; i<PX4_MAX_TASKS; ++i) { if (taskmap[i].isused == false) { taskmap[i].pid = task; taskmap[i].name = name; taskmap[i].isused = true; break; } } if (i>=PX4_MAX_TASKS) { return -ENOSPC; } return i; }
static void start_timer_thread(void) { pthread_attr_t attr; pthread_t th; sigset_t ss, oss; #ifndef WORKSTATION struct sched_param sched_param; #endif sem_t sem; init_status = sem_init(&sem, 0, 0); if (init_status) { perror("Error initializing semaphore in Timer"); return; } init_status = pthread_attr_init(&attr); if (init_status) { NMF_LOG("Error initializing attribute in Timer: %s (%d)\n", strerror(init_status), init_status); return; } #ifndef WORKSTATION #ifndef ANDROID init_status = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (init_status) { NMF_LOG("Error setting sched-inherit policy in Timer: %s (%d)\n", strerror(init_status), init_status); return; } #endif init_status = pthread_attr_setschedpolicy(&attr, SCHED_RR); if (init_status) { NMF_LOG("Error setting sched policy in Timer: %s (%d)\n", strerror(init_status), init_status); return; } sched_param.sched_priority = sched_get_priority_max(SCHED_RR); init_status = pthread_attr_setschedparam(&attr, &sched_param); if (init_status) { NMF_LOG("Error setting sched param in Timer: %s (%d)\n", strerror(init_status), init_status); return; } #endif pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); sigfillset (&ss); sigprocmask(SIG_SETMASK, &ss, &oss); /* Create the helper thread for this timer. */ init_status = pthread_create (&th, &attr, timer_thread_main, &sem); if (init_status) NMF_LOG("Error creating Timer thread: %s (%d)\n", strerror(init_status), init_status); else sem_wait(&sem); sem_close(&sem); /* Restore the signal mask. */ sigprocmask(SIG_SETMASK, &oss, NULL); /* No need for the attribute anymore. */ (void) pthread_attr_destroy (&attr); }
void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void * ), void *data, int prio /* -2..+2 */ ) { pthread_attr_t _a; pthread_attr_t *a= &_a; struct sched_param sp; PT_CALL( pthread_attr_init(a) ); #ifndef PTHREAD_TIMEDJOIN // We create a NON-JOINABLE thread. This is mainly due to the lack of // 'pthread_timedjoin()', but does offer other benefits (s.a. earlier // freeing of the thread's resources). // PT_CALL( pthread_attr_setdetachstate(a,PTHREAD_CREATE_DETACHED) ); #endif // Use this to find a system's default stack size (DEBUG) #if 0 { size_t n; pthread_attr_getstacksize( a, &n ); fprintf( stderr, "Getstack: %u\n", (unsigned int)n ); } // 524288 on OS X // 2097152 on Linux x86 (Ubuntu 7.04) // 1048576 on FreeBSD 6.2 SMP i386 #endif #if (defined _THREAD_STACK_SIZE) && (_THREAD_STACK_SIZE > 0) PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) ); #endif bool_t normal= #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) !sudo; // with sudo, even normal thread must use SCHED_RR #else prio == 0; // create a default thread if #endif if (!normal) { // NB: PThreads priority handling is about as twisty as one can get it // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!! // "The specified scheduling parameters are only used if the scheduling // parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED." // // Android: No PTHREAD_EXPLICIT_SCHED //PT_CALL( pthread_attr_setinheritsched( a, PTHREAD_EXPLICIT_SCHED ) ); //--- // "Select the scheduling policy for the thread: one of SCHED_OTHER // (regular, non-real-time scheduling), SCHED_RR (real-time, // round-robin) or SCHED_FIFO (real-time, first-in first-out)." // // "Using the RR policy ensures that all threads having the same // priority level will be scheduled equally, regardless of their activity." // // "For SCHED_FIFO and SCHED_RR, the only required member of the // sched_param structure is the priority sched_priority. For SCHED_OTHER, // the affected scheduling parameters are implementation-defined." // // "The priority of a thread is specified as a delta which is added to // the priority of the process." // // ".. priority is an integer value, in the range from 1 to 127. // 1 is the least-favored priority, 127 is the most-favored." // // "Priority level 0 cannot be used: it is reserved for the system." // // "When you use specify a priority of -99 in a call to // pthread_setschedparam(), the priority of the target thread is // lowered to the lowest possible value." // // ... // ** CONCLUSION ** // // PThread priorities are _hugely_ system specific, and we need at // least OS specific settings. Hopefully, Linuxes and OS X versions // are uniform enough, among each other... // #ifdef PLATFORM_OSX // AK 10-Apr-07 (OS X PowerPC 10.4.9): // // With SCHED_RR, 26 seems to be the "normal" priority, where setting // it does not seem to affect the order of threads processed. // // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26, // but the difference is not so clear with OTHER). // // 'sched_get_priority_min()' and '..max()' give 15, 47 as the // priority limits. This could imply, user mode applications won't // be able to use values outside of that range. // #define _PRIO_MODE SCHED_OTHER // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS #define _PRIO_HI 32 // seems to work (_carefully_ picked!) #define _PRIO_0 26 // detected #define _PRIO_LO 1 // seems to work (tested) #elif defined(PLATFORM_LINUX) // (based on Ubuntu Linux 2.6.15 kernel) // // SCHED_OTHER is the default policy, but does not allow for priorities. // SCHED_RR allows priorities, all of which (1..99) are higher than // a thread with SCHED_OTHER policy. // // <http://kerneltrap.org/node/6080> // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> // // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, // but even Ubuntu does not seem to define it. // #define _PRIO_MODE SCHED_RR // NTLP 2.5: only system scope allowed (being the basic reason why // root privileges are required..) //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS #define _PRIO_HI 99 #define _PRIO_0 50 #define _PRIO_LO 1 #elif defined(PLATFORM_BSD) // // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> // // "When control over the thread scheduling is desired, then FreeBSD // with the libpthread implementation is by far the best choice .." // #define _PRIO_MODE SCHED_OTHER #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS #define _PRIO_HI 31 #define _PRIO_0 15 #define _PRIO_LO 1 #elif defined(PLATFORM_CYGWIN) // // TBD: Find right values for Cygwin // #else #error "Unknown OS: not implemented!" #endif #ifdef _PRIO_SCOPE PT_CALL( pthread_attr_setscope( a, _PRIO_SCOPE ) ); #endif PT_CALL( pthread_attr_setschedpolicy( a, _PRIO_MODE ) ); #define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) ) #define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) ) sp.sched_priority= (prio == +2) ? _PRIO_HI : (prio == +1) ? _PRIO_AN : #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) (prio == 0) ? _PRIO_0 : #endif (prio == -1) ? _PRIO_BN : _PRIO_LO; PT_CALL( pthread_attr_setschedparam( a, &sp ) ); } //--- // Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system // thread limit (not userland thread). Actual limit for us is way higher. // PTHREAD_THREADS_MAX is not defined (even though man page refers to it!) // # ifndef THREAD_CREATE_RETRIES_MAX // Don't bother with retries; a failure is a failure // { int rc= pthread_create( ref, a, func, data ); if (rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__-1 ); } # else # error "This code deprecated" /* // Wait slightly if thread creation has exchausted the system // { uint_t retries; for( retries=0; retries<THREAD_CREATE_RETRIES_MAX; retries++ ) { int rc= pthread_create( ref, a, func, data ); // // OS X / Linux: // EAGAIN: ".. lacked the necessary resources to create // another thread, or the system-imposed limit on the // total number of threads in a process // [PTHREAD_THREADS_MAX] would be exceeded." // EINVAL: attr is invalid // Linux: // EPERM: no rights for given parameters or scheduling (no sudo) // ENOMEM: (known to fail with this code, too - not listed in man) if (rc==0) break; // ok! // In practise, exhaustion seems to be coming from memory, not a // maximum number of threads. Keep tuning... ;) // if (rc==EAGAIN) { //fprintf( stderr, "Looping (retries=%d) ", retries ); // DEBUG // Try again, later. Yield(); } else { _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ ); } } } */ # endif if (a) { PT_CALL( pthread_attr_destroy(a) ); } }
void *control_func(void *arg) { int i; int r_c; int my_policy; pthread_t self; pthread_t thread_id = 0; pthread_attr_t new_attr; struct sched_param my_param; RT_TASK *rtai_task_ptr; self = pthread_self(); rt_printk("Starting control pthread: %s, id: %ld\n", (char *)arg, self); if(( r_c = pthread_getschedparam(self, &my_policy, &my_param)) != 0) { rt_printk("pthread: %s, pthread_getschedparam error: %d\n", (char *)arg, r_c); } rt_printk("pthread: %s, Created with following scheduling parameters.\n", (char *)arg); rt_printk("pthread: %s, running at %s/%d\n", (char *)arg, (my_policy == SCHED_FIFO ? "FIFO" : (my_policy == SCHED_RR ? "RR" : (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))), my_param.sched_priority); rtai_task_ptr = rt_whoami(); rt_printk("pthread: %s, RTAI priority: %d\n", (char *)arg, rtai_task_ptr->priority); // Initialise & lock the mutex: test_op pthread_mutex_init(&test_op.lock, NULL); test_op.t_buffer_pos = 0; for(i = 0; i < T_BUFFER_SIZE; i++) { test_op.t_buffer_data[i] = 0; test_op.t_buffer_tid[i] = 0; } if(( r_c = pthread_mutex_lock(&test_op.lock)) != 0) { rt_printk("pthread %s, Cannot gain mutex: %d\n", (char *)arg, r_c); } // Create an application thread. if(( r_c = pthread_attr_init(&new_attr) ) != 0 ) { rt_printk("pthread %s, Error initialising thread attributes: %d\n", (char *)arg, r_c); } if(( r_c = pthread_attr_setschedpolicy(&new_attr, SCHED_FIFO) ) != 0 ) { rt_printk("pthread %s, Error setting thread attribute scheduling parameters: %d\n", (char *)arg, r_c); } // Create NUM_THREADS application pthreads, each thread with increasing priority. for(i = 0; i < NUM_THREADS; i++) { my_param.sched_priority = 12 + i; if(( r_c = pthread_attr_setschedparam(&new_attr, &my_param) ) != 0 ) { rt_printk("pthread %s, Error setting thread attribute scheduling parameters: %d\n", (char *)arg, r_c); } if(( r_c = pthread_create(&thread_id, &new_attr, thread_func, "application pthread mutex tester")) != 0 ) { rt_printk("mutex priority inheritance test - Application thread creation failed: %d\n", r_c); } } // Display control thread priority. if(( r_c = pthread_getschedparam(self, &my_policy, &my_param)) != 0) { rt_printk("pthread: %s, pthread_getschedparam error: %d\n", (char *)arg, r_c); } rt_printk("pthread: %s, Priority should now be raised due to inheritance.\n", (char *)arg); rt_printk("pthread: %s, running at %s/%d\n", (char *)arg, (my_policy == SCHED_FIFO ? "FIFO" : (my_policy == SCHED_RR ? "RR" : (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))), my_param.sched_priority); rt_printk("pthread: %s, RTAI priority: %d\n", (char *)arg, rtai_task_ptr->priority); rt_printk("pthread: %s, id: %ld, about to unlock mutex.\n", (char *)arg, self); if(( r_c = pthread_mutex_unlock(&test_op.lock)) != 0) { rt_printk("pthread %s - Error unlocking mutex: %d\n", (char *)arg, r_c); } rt_printk("pthread: %s, Priority should now be back to original.\n", (char *)arg); rt_printk("pthread: %s, running at %s/%d\n", (char *)arg, (my_policy == SCHED_FIFO ? "FIFO" : (my_policy == SCHED_RR ? "RR" : (my_policy == SCHED_OTHER ? "OTHER" : "unknown"))), my_param.sched_priority); rt_printk("pthread: %s, RTAI priority: %d\n", (char *)arg, rtai_task_ptr->priority); pthread_exit("a"); return(NULL); }
static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr, void *(*entry) (void *), void *data, int priority) { int ret; /* Block the signals that signals interface plugin handles. * If the LibVLC caller wants to handle some signals by itself, it should * block these before whenever invoking LibVLC. And it must obviously not * start the VLC signals interface plugin. * * LibVLC will normally ignore any interruption caused by an asynchronous * signal during a system call. But there may well be some buggy cases * where it fails to handle EINTR (bug reports welcome). Some underlying * libraries might also not handle EINTR properly. */ sigset_t oldset; { sigset_t set; sigemptyset (&set); sigdelset (&set, SIGHUP); sigaddset (&set, SIGINT); sigaddset (&set, SIGQUIT); sigaddset (&set, SIGTERM); sigaddset (&set, SIGPIPE); /* We don't want this one, really! */ pthread_sigmask (SIG_BLOCK, &set, &oldset); } #if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \ && defined (_POSIX_THREAD_PRIORITY_SCHEDULING) \ && (_POSIX_THREAD_PRIORITY_SCHEDULING >= 0) if (rt_priorities) { struct sched_param sp = { .sched_priority = priority + rt_offset, }; int policy; if (sp.sched_priority <= 0) sp.sched_priority += sched_get_priority_max (policy = SCHED_OTHER); else sp.sched_priority += sched_get_priority_min (policy = SCHED_RR); pthread_attr_setschedpolicy (attr, policy); pthread_attr_setschedparam (attr, &sp); } #else (void) priority; #endif /* The thread stack size. * The lower the value, the less address space per thread, the highest * maximum simultaneous threads per process. Too low values will cause * stack overflows and weird crashes. Set with caution. Also keep in mind * that 64-bits platforms consume more stack than 32-bits one. * * Thanks to on-demand paging, thread stack size only affects address space * consumption. In terms of memory, threads only use what they need * (rounded up to the page boundary). * * For example, on Linux i386, the default is 2 mega-bytes, which supports * about 320 threads per processes. */ #define VLC_STACKSIZE (128 * sizeof (void *) * 1024) #ifdef VLC_STACKSIZE ret = pthread_attr_setstacksize (attr, VLC_STACKSIZE); assert (ret == 0); /* fails iif VLC_STACKSIZE is invalid */ #endif ret = pthread_create (th, attr, entry, data); pthread_sigmask (SIG_SETMASK, &oldset, NULL); pthread_attr_destroy (attr); return ret; } /** * Creates and starts new thread. * * The thread must be <i>joined</i> with vlc_join() to reclaim resources * when it is not needed anymore. * * @param th [OUT] pointer to write the handle of the created thread to * (mandatory, must be non-NULL) * @param entry entry point for the thread * @param data data parameter given to the entry point * @param priority thread priority value * @return 0 on success, a standard error code on error. */ int vlc_clone (vlc_thread_t *th, void *(*entry) (void *), void *data, int priority) { pthread_attr_t attr; pthread_attr_init (&attr); return vlc_clone_attr (th, &attr, entry, data, priority); }
/*! Begins execution of the thread by calling run(), which should be reimplemented in a QThread subclass to contain your code. The operating system will schedule the thread according to the \a priority argument. If you try to start a thread that is already running, this function will wait until the the thread has finished and then restart the thread. \sa Priority */ void QThread::start(Priority priority) { QMutexLocker locker( d->mutex() ); if ( d->running ) pthread_cond_wait(&d->thread_done, &locker.mutex()->d->handle); d->running = TRUE; d->finished = FALSE; int ret; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); #if !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0) switch (priority) { case InheritPriority: { pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); break; } default: { int sched_policy; if (pthread_attr_getschedpolicy(&attr, &sched_policy) != 0) { // failed to get the scheduling policy, don't bother // setting the priority qWarning("QThread: cannot determine default scheduler policy"); break; } int prio_min = sched_get_priority_min(sched_policy); int prio_max = sched_get_priority_max(sched_policy); if (prio_min == -1 || prio_max == -1) { // failed to get the scheduling parameters, don't // bother setting the priority qWarning("QThread: cannot determine scheduler priority range"); break; } int prio; switch (priority) { case IdlePriority: prio = prio_min; break; case HighestPriority: prio = prio_max; break; default: // crudely scale our priority enum values to the prio_min/prio_max prio = (((prio_max - prio_min) / TimeCriticalPriority) * priority) + prio_min; prio = QMAX(prio_min, QMIN(prio_max, prio)); break; } sched_param sp; sp.sched_priority = prio; pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedparam(&attr, &sp); break; } } #endif // _POSIX_THREAD_PRIORITY_SCHEDULING if ( d->stacksize > 0 ) { #if defined(_POSIX_THREAD_ATTR_STACKSIZE) && (_POSIX_THREAD_ATTR_STACKSIZE-0 > 0) ret = pthread_attr_setstacksize( &attr, d->stacksize ); #else ret = ENOSYS; // stack size not supported, automatically fail #endif // _POSIX_THREAD_ATTR_STACKSIZE if ( ret ) { #ifdef QT_CHECK_STATE qWarning( "QThread::start: thread stack size error: %s", strerror( ret ) ) ; #endif // QT_CHECK_STATE // we failed to set the stacksize, and as the documentation states, // the thread will fail to run... d->running = FALSE; d->finished = FALSE; return; } } d->args[0] = this; d->args[1] = d; ret = pthread_create( &d->thread_id, &attr, (QtThreadCallback)QThreadInstance::start, d->args ); #if defined (Q_OS_HPUX) if (ret == EPERM) { pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); ret = pthread_create(&d->thread_id, &attr, (QtThreadCallback)QThreadInstance::start, d->args); } #endif pthread_attr_destroy( &attr ); if ( ret ) { #ifdef QT_CHECK_STATE qWarning( "QThread::start: thread creation error: %s", strerror( ret ) ); #endif // QT_CHECK_STATE d->running = FALSE; d->finished = FALSE; d->args[0] = d->args[1] = 0; } }
int MavlinkInit(MavlinkStruct *Mavlink, AttitudeData *AttitudeDesire, AttitudeData *AttitudeMesure, char *TargetIP) { pthread_attr_t attr; struct sched_param param; int minprio, maxprio; int retval = 0; Mavlink->AttitudeDesire = AttitudeDesire; Mavlink->AttitudeMesure = AttitudeMesure; strcpy(Mavlink->target_ip, TargetIP); Mavlink->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); memset((void *) &(Mavlink->locAddr), 0, sizeof(struct sockaddr_in)); Mavlink->locAddr.sin_family = AF_INET; Mavlink->locAddr.sin_addr.s_addr = INADDR_ANY; Mavlink->locAddr.sin_port = htons(14551); /* Bind the socket to port 14551 - necessary to receive packets from qgroundcontrol */ retval = bind(Mavlink->sock,(struct sockaddr *)&(Mavlink->locAddr), sizeof(struct sockaddr)); if (retval == -1) { printf("%s : erreur bind échoué", __FUNCTION__); close(Mavlink->sock); return retval; } /* Attempt to make it non blocking */ if ((retval = fcntl(Mavlink->sock, F_SETFL, fcntl(Mavlink->sock, F_GETFL) | O_ASYNC | O_NONBLOCK)) < 0) { printf("%s : erreur ouverture non-bloquante", __FUNCTION__); close(Mavlink->sock); return retval; } memset(&Mavlink->gcAddr, 0, sizeof(struct sockaddr_in)); Mavlink->gcAddr.sin_family = AF_INET; Mavlink->gcAddr.sin_addr.s_addr = inet_addr(Mavlink->target_ip); Mavlink->gcAddr.sin_port = htons(14550); pthread_attr_init(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); minprio = sched_get_priority_min(POLICY); maxprio = sched_get_priority_max(POLICY); pthread_attr_setschedpolicy(&attr, POLICY); param.sched_priority = minprio + (maxprio - minprio)/4; pthread_attr_setstacksize(&attr, THREADSTACK); pthread_attr_setschedparam(&attr, ¶m); printf("Creating Mavlink thread\n"); pthread_barrier_init(&MavlinkStartBarrier, NULL, 3); sem_init(&MavlinkReceiveTimerSem, 0, 0); sem_init(&MavlinkStatusTimerSem, 0, 0); retval = pthread_create(&Mavlink->MavlinkReceiveTask, &attr, MavlinkReceiveTask, Mavlink); if (retval) { printf("pthread_create : Impossible de créer le thread Mavlink_reception_thread\n"); return retval; } retval = pthread_create(&Mavlink->MavlinkStatusTask, &attr, MavlinkStatusTask, Mavlink); if (retval) { printf("pthread_create : Impossible de créer le thread MavlinkStatusTask\n"); return retval; } pthread_attr_destroy(&attr); return retval; }
void *POSIX_Init ( void *argument ) { pthread_mutexattr_t mutexattr; /* mutex attributes */ pthread_condattr_t condattr; /* condition attributes */ pthread_attr_t attr; /* task attributes */ pthread_t ta,tb,tc, tc1; /* threads */ sigset_t set; /* signals */ struct sched_param sch_param; /* schedule parameters */ struct periodic_params params_a, params_b, params_c, params_c1; TEST_BEGIN(); data.updated = FALSE; /* mask signal */ sigemptyset (&set); sigaddset (&set,SIGALRM); pthread_sigmask (SIG_BLOCK,&set,NULL); /* set mutex attributes */ if (pthread_mutexattr_init (&mutexattr) != 0) { perror ("Error in mutex attribute init\n"); } /* init mutex */ if (pthread_mutex_init (&data.mutex,&mutexattr) != 0) { perror ("Error in mutex init"); } /* init condition attributes */ if (pthread_condattr_init (&condattr) != 0) { perror ("Error in condition attribute init\n"); } /* init condition */ if (pthread_cond_init (&data.sync,&condattr) != 0) { perror ("Error in condition init"); } /* init task attributes */ if (pthread_attr_init(&attr) != 0) { perror ("Error in attribute init\n"); } /* set explicit schedule for every task */ if (pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED) != 0) { perror("Error in attribute inheritsched\n"); } /* set task independent (join will not use) */ if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) != 0) { perror ("Error in attribute detachstate\n"); } /* schedule policy POSIX_FIFO (priority preemtive and FIFO within the same priority) */ if (pthread_attr_setschedpolicy (&attr, SCHED_FIFO) != 0) { perror ("Error in attribute setschedpolicy\n"); } /* set and create thread A with priority 1 */ sch_param.sched_priority = 1; if (pthread_attr_setschedparam(&attr, &sch_param) != 0) { perror ("Error in attribute schedparam\n"); } /* Temporal parameters (1 sec. periodicity) */ params_a.period.tv_sec = 1; /* seconds */ params_a.period.tv_nsec = 000000000; /* nanoseconds */ params_a.count = 20; params_a.signo = SIGALRM; if (pthread_create (&ta, &attr, task_a, ¶ms_a) != 0 ) { perror ("Error in thread create for task a\n"); } /* set and create thread B with priority 15 */ sch_param.sched_priority = 15; if (pthread_attr_setschedparam(&attr, &sch_param) != 0) { perror ("Error in attribute schedparam"); } /* Temporal parameters (2 sec. periodicity) */ params_b.period.tv_sec = 2; /* seconds */ params_b.period.tv_nsec = 000000000; /* nanoseconds */ params_b.count = 10; params_b.signo = SIGALRM; if (pthread_create (&tb, &attr, task_b, ¶ms_b) != 0) { perror ("Error in thread create for task b\n"); } /* set and create thread B with priority 14 */ sch_param.sched_priority = 14; if (pthread_attr_setschedparam(&attr, &sch_param) != 0 ) { perror ("Error in attribute schedparam\n"); } /* Temporal parameters (3 sec. periodicity) */ params_c.period.tv_sec = 3; /* seconds */ params_c.period.tv_nsec = 000000000; /* nanoseconds */ params_c.count = 6; params_c.signo = SIGALRM; if (pthread_create (&tc, &attr, task_c, ¶ms_c) != 0) { perror ("Error in thread create for task c\n"); } /* execute 25 seconds and finish */ sleep (25); puts( "starting C again with 0.5 second periodicity" ); /* Temporal parameters (0.5 sec. periodicity) */ params_c1.period.tv_sec = 0; /* seconds */ params_c1.period.tv_nsec = 500000000; /* nanoseconds */ params_c1.count = 6; params_c1.signo = SIGALRM; if (pthread_create (&tc1, &attr, task_c, ¶ms_c1) != 0) { perror ("Error in thread create for task c1\n"); } sleep(5); TEST_END(); rtems_test_exit (0); }
/* The main test function. */ int main( int argc, char *argv[] ) { int ret = 0; pthread_t child; pthread_attr_t ta; pthread_barrier_t bar; struct sched_param sp; /* Initialize output routine */ output_init(); ret = pthread_barrier_init( &bar, NULL, 2 ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to init barrier" ); } /* Create the attribute object with a known scheduling policy */ ret = pthread_attr_init( &ta ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to initialize thread attribute" ); } ret = pthread_attr_setinheritsched( &ta, PTHREAD_EXPLICIT_SCHED ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to set inherit sched" ); } sp.sched_priority = sched_get_priority_min( SCHED_RR ); if ( sp.sched_priority == -1 ) { UNRESOLVED( errno, "Failed to get min priority" ); } ret = pthread_attr_setschedparam( &ta, &sp ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to set attribute param" ); } ret = pthread_attr_setschedpolicy( &ta, SCHED_RR ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to set attribute policy" ); } /* Create the thread with this attribute */ ret = pthread_create( &child, &ta, threaded, &bar ); if ( ret != 0 ) { UNRESOLVED( ret, "thread creation failed (you may need more priviledges)" ); } /* Wait while the thread checks its policy (we only check what is reported, not the real behavior) */ check_param( child, SCHED_RR, sched_get_priority_min( SCHED_RR ) ); ret = pthread_barrier_wait( &bar ); if ( ( ret != 0 ) && ( ret != PTHREAD_BARRIER_SERIAL_THREAD ) ) { UNRESOLVED( ret, "barrier wait failed" ); } /* Change the threads policy */ sp.sched_priority = sched_get_priority_min( SCHED_FIFO ); if ( sp.sched_priority == -1 ) { UNRESOLVED( errno, "Failed to get min priority" ); } ret = pthread_setschedparam( child, SCHED_FIFO, &sp ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to change running thread's policy" ); } ret = pthread_barrier_wait( &bar ); if ( ( ret != 0 ) && ( ret != PTHREAD_BARRIER_SERIAL_THREAD ) ) { UNRESOLVED( ret, "barrier wait failed" ); } /* Wait while the thread checks its policy (we only check what is reported, not the real behavior) */ check_param( child, SCHED_FIFO, sched_get_priority_min( SCHED_FIFO ) ); ret = pthread_barrier_wait( &bar ); if ( ( ret != 0 ) && ( ret != PTHREAD_BARRIER_SERIAL_THREAD ) ) { UNRESOLVED( ret, "barrier wait failed" ); } /* Change the thread priority */ sp.sched_priority = sched_get_priority_max( SCHED_FIFO ); if ( sp.sched_priority == -1 ) { UNRESOLVED( errno, "Failed to get max priority" ); } ret = pthread_setschedprio( child, sp.sched_priority ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to raise thread's priority" ); } ret = pthread_barrier_wait( &bar ); if ( ( ret != 0 ) && ( ret != PTHREAD_BARRIER_SERIAL_THREAD ) ) { UNRESOLVED( ret, "barrier wait failed" ); } /* The thread checks its priority (we only check what is reported, not the real behavior) */ check_param( child, SCHED_FIFO, sched_get_priority_max( SCHED_FIFO ) ); ret = pthread_barrier_wait( &bar ); if ( ( ret != 0 ) && ( ret != PTHREAD_BARRIER_SERIAL_THREAD ) ) { UNRESOLVED( ret, "barrier wait failed" ); } ret = pthread_join( child, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to join the thread" ); } PASSED; }
void *POSIX_Init( void *argument ) { int status; pthread_attr_t attr; struct sched_param schedparam; TEST_BEGIN(); /* set the time of day, and print our buffer in multiple ways */ set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 ); /* get id of this thread */ Init_id = pthread_self(); printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id ); /* invalid scheduling policy error */ puts( "Init: pthread_attr_init - SUCCESSFUL" ); status = pthread_attr_init( &attr ); rtems_test_assert( !status ); status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); rtems_test_assert( !status ); attr.schedpolicy = -1; puts( "Init: pthread_create - EINVAL (invalid scheduling policy)" ); status = pthread_create( &Task_id, &attr, Task_1, NULL ); rtems_test_assert( status == EINVAL ); /* replenish period < budget error */ puts( "Init: pthread_attr_init - SUCCESSFUL" ); status = pthread_attr_init( &attr ); rtems_test_assert( !status ); puts( "Init: set scheduling parameter attributes for sporadic server" ); status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC ); rtems_test_assert( !status ); schedparam.sched_ss_repl_period.tv_sec = 1; schedparam.sched_ss_repl_period.tv_nsec = 0; schedparam.sched_ss_init_budget.tv_sec = 2; schedparam.sched_ss_init_budget.tv_nsec = 0; schedparam.sched_priority = 200; schedparam.sched_ss_low_priority = 100; status = pthread_attr_setschedparam( &attr, &schedparam ); rtems_test_assert( !status ); status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); rtems_test_assert( !status ); puts( "Init: pthread_create - EINVAL (replenish < budget)" ); status = pthread_create( &Task_id, &attr, Task_1, NULL ); rtems_test_assert( status == EINVAL ); /* invalid sched_ss_low_priority error */ schedparam.sched_ss_repl_period.tv_sec = 2; schedparam.sched_ss_repl_period.tv_nsec = 0; schedparam.sched_ss_init_budget.tv_sec = 1; schedparam.sched_ss_init_budget.tv_nsec = 0; schedparam.sched_priority = 200; schedparam.sched_ss_low_priority = -1; status = pthread_attr_setschedparam( &attr, &schedparam ); rtems_test_assert( !status ); puts( "Init: pthread_create - EINVAL (invalid sched_ss_low_priority)" ); status = pthread_create( &Task_id, &attr, Task_1, NULL ); rtems_test_assert( status == EINVAL ); /* create a thread as a sporadic server */ schedparam.sched_ss_repl_period.tv_sec = 2; schedparam.sched_ss_repl_period.tv_nsec = 0; schedparam.sched_ss_init_budget.tv_sec = 1; schedparam.sched_ss_init_budget.tv_nsec = 0; schedparam.sched_priority = sched_get_priority_max( SCHED_FIFO ); schedparam.sched_ss_low_priority = sched_get_priority_max( SCHED_FIFO ) - 6; status = pthread_attr_setschedparam( &attr, &schedparam ); rtems_test_assert( !status ); puts( "Init: pthread_create - SUCCESSFUL" ); status = pthread_create( &Task_id, &attr, Task_1, NULL ); rtems_test_assert( !status ); status = pthread_join( Task_id, NULL ); rtems_test_assert( status ); /* switch to Task_1 */ TEST_END(); rtems_test_exit( 0 ); return NULL; /* just so the compiler thinks we returned something */ }
void *POSIX_Init( void *argument ) { long end_time; int status; int i; pthread_t threadId; pthread_attr_t attr; struct sched_param param; int policy; TEST_BEGIN(); /* Setup variables */ status = pthread_create( &threadId, NULL, Blocker, NULL ); rtems_test_assert( status == 0 ); status = pthread_mutex_init(&MutexID, NULL); rtems_test_assert( status == 0 ); status = pthread_cond_init(&CondID, NULL); rtems_test_assert( status == 0 ); /* Setup so threads are created with a high enough priority to preempt * as they get created. */ status = pthread_attr_init( &attr ); rtems_test_assert( status == 0 ); status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); rtems_test_assert( status == 0 ); status = pthread_attr_setschedpolicy( &attr, SCHED_FIFO ); rtems_test_assert( status == 0 ); param.sched_priority = sched_get_priority_max(SCHED_FIFO) / 2; status = pthread_attr_setschedparam( &attr, ¶m ); rtems_test_assert( status == 0 ); for ( i=0 ; i < N ; i++) { /* Threads will preempt as they are created, start up, and block */ status = pthread_create(&threadId, &attr, Blocker, NULL); rtems_test_assert( status == 0 ); } /* Now that all the threads have been created, adjust our priority * so we don't get preempted on broadcast. */ status = pthread_getschedparam(pthread_self(), &policy, ¶m); rtems_test_assert( status == 0 ); param.sched_priority = sched_get_priority_max(policy) - 1; status = pthread_setschedparam(pthread_self(), policy, ¶m); rtems_test_assert( status == 0 ); benchmark_timer_initialize(); status = pthread_cond_broadcast(&CondID); end_time = benchmark_timer_read(); rtems_test_assert( status == 0 ); put_time( "pthread_cond_broadcast: threads waiting no preempt", end_time, 1, 0, 0 ); TEST_END(); rtems_test_exit( 0 ); return NULL; }
//----------------------------------------------------------------------------- int pdcp_netlink_init( void ) //----------------------------------------------------------------------------- { int i; int nb_inst_enb; int nb_inst_ue; pthread_attr_t attr; struct sched_param sched_param; reset_meas(&ip_pdcp_stats_tmp); #if defined(USER_MODE) && defined(OAI_EMU) nb_inst_enb = oai_emulation.info.nb_enb_local; nb_inst_ue = oai_emulation.info.nb_ue_local; #else nb_inst_enb = 1; nb_inst_ue = 1; #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) nb_inst_enb = 0; LOG_I(PDCP, "[NETLINK] Creating 0 queues for eNB Netlink -> PDCP communication\n"); #else #warning " LG: When there will be handover in, there will problems because dim is based on local nums of ues" pdcp_netlink_queue_enb = calloc(nb_inst_enb, sizeof(struct lfds611_queue_state*)); pdcp_netlink_nb_element_enb = malloc(nb_inst_enb * sizeof(uint32_t)); LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb); for (i = 0; i < nb_inst_enb; i++) { pdcp_netlink_nb_element_enb[i] = 0; if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) { LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i); exit(EXIT_FAILURE); } } #endif if (nb_inst_ue > 0) { pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state*)); pdcp_netlink_nb_element_ue = malloc(nb_inst_ue * sizeof(uint32_t)); LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue); for (i = 0; i < nb_inst_ue; i++) { pdcp_netlink_nb_element_ue[i] = 0; if (lfds611_queue_new(&pdcp_netlink_queue_ue[i], PDCP_QUEUE_NB_ELEMENTS) < 0) { LOG_E(PDCP, "Failed to create new FIFO for UE Netlink -> PDCP communcation instance %d\n", i); exit(EXIT_FAILURE); } } } if ((nb_inst_ue + nb_inst_enb) > 0) { if (pthread_attr_init(&attr) != 0) { LOG_E(PDCP, "[NETLINK]Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n", errno, strerror(errno)); exit(EXIT_FAILURE); } sched_param.sched_priority = 10; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, &sched_param); /* Create one thread that fetchs packets from the netlink. * When the netlink fifo is full, packets are silently dropped, this behaviour * should be avoided if we want a reliable link. */ if (pthread_create(&pdcp_netlink_thread, &attr, pdcp_netlink_thread_fct, NULL) != 0) { LOG_E(PDCP, "[NETLINK]Failed to create new thread for Netlink/PDCP communication (%d:%s)\n", errno, strerror(errno)); exit(EXIT_FAILURE); } pthread_setname_np( pdcp_netlink_thread, "PDCP netlink" ); } return 0; }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char *argv[]) { int fdPmesg = -1; bool klogd = property_get_bool_svelte("logd.klogd"); if (klogd) { fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY); } fdDmesg = open("/dev/kmsg", O_WRONLY); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { int sock = TEMP_FAILURE_RETRY( socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); if (sock < 0) { return -errno; } static const char reinit[] = "reinit"; ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); if (ret < 0) { return -errno; } struct pollfd p; memset(&p, 0, sizeof(p)); p.fd = sock; p.events = POLLIN; ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100)); if (ret < 0) { return -errno; } if ((ret == 0) || !(p.revents & POLLIN)) { return -ETIME; } static const char success[] = "success"; char buffer[sizeof(success) - 1]; memset(buffer, 0, sizeof(buffer)); ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); if (ret < 0) { return -errno; } return strncmp(buffer, success, sizeof(success) - 1) != 0; } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); sem_init(&sem_name, 0, 1); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { reinit_running = false; } } pthread_attr_destroy(&attr); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); if (property_get_bool_svelte("logd.statistics")) { logBuf->enableStatistics(); } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(300)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. bool auditd = property_get_bool("logd.auditd", true); LogAudit *al = NULL; if (auditd) { bool dmesg = property_get_bool("logd.auditd.dmesg", true); al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1); } LogKlog *kl = NULL; if (klogd) { kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL); } if (al || kl) { int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0); if (len > 0) { len++; char buf[len]; int rc = klogctl(KLOG_READ_ALL, buf, len); buf[len - 1] = '\0'; if ((rc >= 0) && kl) { kl->synchronize(buf); } for (char *ptr = NULL, *tok = buf; (rc >= 0) && ((tok = log_strtok_r(tok, &ptr))); tok = NULL) { if (al) { rc = al->log(tok); } if (kl) { rc = kl->log(tok); } } } // failure is an option ... messages are in dmesg (required by standard) if (kl && kl->startListener()) { delete kl; } if (al && al->startListener()) { delete al; } } TEMP_FAILURE_RETRY(pause()); exit(0); }
// create a new thread and attach to an activity void SysThread::createThread() { pthread_attr_t newThreadAttr; int schedpolicy, maxpri, minpri; struct sched_param schedparam; // Create an attr block for Thread. pthread_attr_init(&newThreadAttr); #if defined(LINUX) || defined(OPSYS_SUN) || defined(AIX) /* scheduling on two threads controlled by the result method of the */ /* message object do not work properly without an enhanced priority */ pthread_getschedparam(pthread_self(), &schedpolicy, &schedparam); #if defined(AIX) // Starting with AIX 5.3 the priority for a thread created by // a non root user can not be higher then 59. The priority // of a user prog should not be higher then 59 (IBM AIX development). schedparam.sched_priority = 59; #else # ifdef _POSIX_PRIORITY_SCHEDULING maxpri = sched_get_priority_max(schedpolicy); minpri = sched_get_priority_min(schedpolicy); schedparam.sched_priority = (minpri + maxpri) / 2; # endif #endif #if defined(OPSYS_SUN) /* PTHREAD_EXPLICIT_SCHED ==> use scheduling attributes of the new object */ // pthread_attr_setinheritsched(&newThreadAttr, PTHREAD_EXPLICIT_SCHED); /* Performance measurements show massive performance improvements > 50 % */ /* using Round Robin scheduling instead of FIFO scheduling */ pthread_attr_setschedpolicy(&newThreadAttr, SCHED_RR); #endif #if defined(AIX) /* PTHREAD_EXPLICIT_SCHED ==> use scheduling attributes of the new object */ // pthread_attr_setinheritsched(&newThreadAttr, PTHREAD_EXPLICIT_SCHED); /* Each thread has an initial priority that is dynamically modified by */ /* the scheduler, according to the thread's activity; thread execution */ /* is time-sliced. On other systems, this scheduling policy may be */ /* different. */ pthread_attr_setschedpolicy(&newThreadAttr, SCHED_OTHER); #endif pthread_attr_setschedparam(&newThreadAttr, &schedparam); #endif // Set the stack size. pthread_attr_setstacksize(&newThreadAttr, THREAD_STACK_SIZE); // Now create the thread int rc = pthread_create(&_threadID, &newThreadAttr, call_thread_function, (void *)this); if (rc != 0) { _threadID = 0; fprintf(stderr," *** ERROR: At SysThread(), createThread - RC = %d !\n", rc); } pthread_attr_destroy(&newThreadAttr); attached = false; // we own this thread return; }