int clock_getres(clockid_t clock_id, struct timespec *res) { int ret = OK; sdbg("clock_id=%d\n", clock_id); /* Only CLOCK_REALTIME is supported */ if (clock_id != CLOCK_REALTIME) { sdbg("Returning ERROR\n"); set_errno(EINVAL); ret = ERROR; } else { /* Form the timspec using clock resolution in nanoseconds */ res->tv_sec = 0; res->tv_nsec = NSEC_PER_TICK; sdbg("Returning res=(%d,%d)\n", (int)res->tv_sec, (int)res->tv_nsec); } return ret; }
void _exit(int status) { struct tcb_s* tcb; sdbg("TCB=%p exitting\n", tcb); /* Destroy the task at the head of the ready to run list. */ (void)task_deletecurrent(); /* Now, perform the context switch to the new ready-to-run task at the * head of the list. */ tcb = (struct tcb_s*)g_readytorun.head; sdbg("New Active Task TCB=%p\n", tcb); /* The way that we handle signals in the simulation is kind of * a kludge. This would be unsafe in a truly multi-threaded, interrupt * driven environment. */ if (tcb->xcp.sigdeliver) { sdbg("Delivering signals TCB=%p\n", tcb); ((sig_deliver_t)tcb->xcp.sigdeliver)(tcb); tcb->xcp.sigdeliver = NULL; } /* Then switch contexts */ up_longjmp(tcb->xcp.regs, 1); }
void sem_destroyholder(FAR sem_t *sem) { /* It is an error if a semaphore is destroyed while there are any holders * (except perhaps the thread release the semaphore itself). Hmmm.. but * we actually have to assume that the caller knows what it is doing because * could have killed another thread that is the actual holder of the semaphore. * We cannot make any assumptions about the state of the semaphore or the * state of any of the holder threads. * * So just recover any stranded holders and hope the task knows what it is * doing. */ #if CONFIG_SEM_PREALLOCHOLDERS > 0 if (sem->hhead) { sdbg("Semaphore destroyed with holders\n"); (void)sem_foreachholder(sem, sem_recoverholders, NULL); } #else if (sem->holder.htcb) { sdbg("Semaphore destroyed with holder\n"); } sem->holder.htcb = NULL; #endif }
int pthread_getschedparam(pthread_t thread, FAR int *policy, FAR struct sched_param *param) { int ret; sdbg("Thread ID=%d policy=0x%p param=0x%p\n", thread, policy, param); if (!policy || !param) { ret = EINVAL; } else { /* Get the schedparams of the thread. */ ret = sched_getparam((pid_t)thread, param); if (ret != OK) { ret = EINVAL; } /* Return the policy. */ *policy = sched_getscheduler((pid_t)thread); if (*policy == ERROR) { ret = get_errno(); } } sdbg("Returning %d\n", ret); return ret; }
void up_sigdeliver(void) { #ifndef CONFIG_DISABLE_SIGNALS FAR _TCB *rtcb = (_TCB*)g_readytorun.head; chipreg_t regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; up_ledon(LED_SIGNAL); sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ ez80_copystate(regs, rtcb->xcp.regs); regs[XCPT_PC] = rtcb->xcp.saved_pc; regs[XCPT_I] = rtcb->xcp.saved_i; /* Get a local copy of the sigdeliver function pointer. We do this so * that we can nullify the sigdeliver function pointer in the TCB and * accept more signal deliveries while processing the current pending * signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state. */ irqrestore(regs[XCPT_I]); /* Deliver the signals */ sigdeliver(rtcb); /* Output any debug messages BEFORE restoring errno (because they may * alter errno), then disable interrupts again and restore the original * errno that is needed by the user logic (it is probably EINTR). */ sdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of * execution. */ up_ledoff(LED_SIGNAL); ez80_restorecontext(regs); #endif }
static inline int mod_filelen(FAR struct mod_loadinfo_s *loadinfo, FAR const char *filename) { struct stat buf; int ret; /* Get the file stats */ ret = stat(filename, &buf); if (ret < 0) { int errval = errno; sdbg("Failed to stat file: %d\n", errval); return -errval; } /* Verify that it is a regular file */ if (!S_ISREG(buf.st_mode)) { sdbg("Not a regular file. mode: %d\n", buf.st_mode); return -ENOENT; } /* TODO: Verify that the file is readable. Not really important because * we will detect this when we try to open the file read-only. */ /* Return the size of the file in the loadinfo structure */ loadinfo->filelen = buf.st_size; return OK; }
int clock_settime(clockid_t clock_id, FAR const struct timespec *tp) { irqstate_t flags; int ret = OK; sdbg("clock_id=%d\n", clock_id); DEBUGASSERT(tp != NULL); /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall * time clock. */ #ifdef CONFIG_RTC if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_ACTIVETIME) #else if (clock_id == CLOCK_REALTIME) #endif { /* Interrupts are disabled here so that the in-memory time * representation and the RTC setting will be as close as * possible. */ flags = irqsave(); /* Save the new base time. */ g_basetime.tv_sec = tp->tv_sec; g_basetime.tv_nsec = tp->tv_nsec; /* Get the elapsed time since power up (in milliseconds) biased * as appropriate. */ g_tickbias = g_system_timer; /* Setup the RTC (lo- or high-res) */ #ifdef CONFIG_RTC if (g_rtc_enabled && clock_id != CLOCK_ACTIVETIME) { up_rtc_settime(tp); } #endif irqrestore(flags); sdbg("basetime=(%d,%d) tickbias=%d\n", (int)g_basetime.tv_sec, (int)g_basetime.tv_nsec, (int)g_tickbias); } else { sdbg("Returning ERROR\n"); set_errno(EINVAL); ret = ERROR; } return ret; }
int sigqueue(int pid, int signo, void *sival_ptr) #endif { #ifdef CONFIG_SCHED_HAVE_PARENT FAR struct tcb_s *rtcb = this_task(); #endif siginfo_t info; int ret; #ifdef CONFIG_CAN_PASS_STRUCTS sdbg("pid=0x%08x signo=%d value=%d\n", pid, signo, value.sival_int); #else sdbg("pid=0x%08x signo=%d value=%p\n", pid, signo, sival_ptr); #endif /* Sanity checks */ if (!GOOD_SIGNO(signo)) { ret = -EINVAL; goto errout; } /* Create the siginfo structure */ info.si_signo = signo; info.si_code = SI_QUEUE; info.si_errno = OK; #ifdef CONFIG_CAN_PASS_STRUCTS info.si_value = value; #else info.si_value.sival_ptr = sival_ptr; #endif #ifdef CONFIG_SCHED_HAVE_PARENT info.si_pid = rtcb->pid; info.si_status = OK; #endif /* Send the signal */ sched_lock(); ret = sig_dispatch(pid, &info); sched_unlock(); /* Check for errors */ if (ret < 0) { goto errout; } return OK; errout: set_errno(-ret); return ERROR; }
FAR struct tm *gmtime_r(FAR const time_t *timer, FAR struct tm *result) { time_t epoch; time_t jdn; int year; int month; int day; int hour; int min; int sec; /* Get the seconds since the EPOCH */ epoch = *timer; sdbg("timer=%d\n", (int)epoch); /* Convert to days, hours, minutes, and seconds since the EPOCH */ jdn = epoch / SEC_PER_DAY; epoch -= SEC_PER_DAY * jdn; hour = epoch / SEC_PER_HOUR; epoch -= SEC_PER_HOUR * hour; min = epoch / SEC_PER_MIN; epoch -= SEC_PER_MIN * min; sec = epoch; sdbg("hour=%d min=%d sec=%d\n", (int)hour, (int)min, (int)sec); /* Convert the days since the EPOCH to calendar day */ clock_utc2calendar(jdn, &year, &month, &day); sdbg("jdn=%d year=%d month=%d day=%d\n", (int)jdn, (int)year, (int)month, (int)day); /* Then return the struct tm contents */ result->tm_year = (int)year - 1900; /* Relative to 1900 */ result->tm_mon = (int)month - 1; /* zero-based */ result->tm_mday = (int)day; /* one-based */ result->tm_hour = (int)hour; result->tm_min = (int)min; result->tm_sec = (int)sec; #if defined(CONFIG_TIME_EXTENDED) result->tm_wday = clock_dayoftheweek(day, month, year); result->tm_yday = day + clock_daysbeforemonth(result->tm_mon, clock_isleapyear(year)); result->tm_isdst = 0; #endif return result; }
int pthread_cond_broadcast(FAR pthread_cond_t *cond) { int ret = OK; int sval; sdbg("cond=0x%p\n", cond); if (!cond) { ret = EINVAL; } else { /* Disable pre-emption until all of the waiting threads have been * restarted. This is necessary to assure that the sval behaves as * expected in the following while loop */ sched_lock(); /* Get the current value of the semaphore */ if (sem_getvalue((sem_t*)&cond->sem, &sval) != OK) { ret = EINVAL; } else { /* Loop until all of the waiting threads have been restarted. */ while (sval < 0) { /* If the value is less than zero (meaning that one or more * thread is waiting), then post the condition semaphore. * Only the highest priority waiting thread will get to execute */ ret = pthread_givesemaphore((sem_t*)&cond->sem); /* Increment the semaphore count (as was done by the * above post). */ sval++; } } /* Now we can let the restarted threads run */ sched_unlock(); } sdbg("Returning %d\n", ret); return ret; }
void up_release_pending(void) { struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head; sdbg("From TCB=%p\n", rtcb); /* Merge the g_pendingtasks list into the g_readytorun task list */ /* sched_lock(); */ if (sched_mergepending()) { /* The currently active task has changed! We will need to switch * contexts. * * Update scheduler parameters. */ sched_suspend_scheduler(rtcb); /* Copy the exception context into the TCB of the task that was * currently active. if up_setjmp returns a non-zero value, then * this is really the previously running task restarting! */ if (!up_setjmp(rtcb->xcp.regs)) { /* Restore the exception context of the rtcb at the (new) head * of the g_readytorun task list. */ rtcb = (struct tcb_s*)g_readytorun.head; sdbg("New Active Task TCB=%p\n", rtcb); /* The way that we handle signals in the simulation is kind of * a kludge. This would be unsafe in a truly multi-threaded, interrupt * driven environment. */ if (rtcb->xcp.sigdeliver) { sdbg("Delivering signals TCB=%p\n", rtcb); ((sig_deliver_t)rtcb->xcp.sigdeliver)(rtcb); rtcb->xcp.sigdeliver = NULL; } /* Update scheduler parameters */ sched_resume_scheduler(rtcb); /* Then switch contexts */ up_longjmp(rtcb->xcp.regs, 1); } } }
void up_sigdeliver(void) { struct tcb_s *rtcb = this_task(); uint32_t regs[XCPTCONTEXT_REGS]; sig_deliver_t sigdeliver; /* Save the errno. This must be preserved throughout the signal handling * so that the user code final gets the correct errno value (probably * EINTR). */ int saved_errno = rtcb->pterrno; board_autoled_on(LED_SIGNAL); sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n", rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head); ASSERT(rtcb->xcp.sigdeliver != NULL); /* Save the real return state on the stack. */ up_copyfullstate(regs, rtcb->xcp.regs); regs[REG_PC] = rtcb->xcp.saved_pc; regs[REG_CPSR] = rtcb->xcp.saved_cpsr; /* Get a local copy of the sigdeliver function pointer. we do this so that * we can nullify the sigdeliver function pointer in the TCB and accept * more signal deliveries while processing the current pending signals. */ sigdeliver = rtcb->xcp.sigdeliver; rtcb->xcp.sigdeliver = NULL; /* Then restore the task interrupt state */ irqrestore(regs[REG_CPSR]); /* Deliver the signals */ sigdeliver(rtcb); /* Output any debug messages BEFORE restoring errno (because they may * alter errno), then disable interrupts again and restore the original * errno that is needed by the user logic (it is probably EINTR). */ sdbg("Resuming\n"); (void)irqsave(); rtcb->pterrno = saved_errno; /* Then restore the correct state for this thread of execution. */ board_autoled_off(LED_SIGNAL); up_fullcontextrestore(regs); }
int mod_load(FAR struct mod_loadinfo_s *loadinfo) { int ret; svdbg("loadinfo: %p\n", loadinfo); DEBUGASSERT(loadinfo && loadinfo->filfd >= 0); /* Load section headers into memory */ ret = mod_loadshdrs(loadinfo); if (ret < 0) { sdbg("ERROR: mod_loadshdrs failed: %d\n", ret); goto errout_with_buffers; } /* Determine total size to allocate */ mod_elfsize(loadinfo); /* Allocate (and zero) memory for the ELF file. */ /* Allocate memory to hold the ELF image */ loadinfo->textalloc = (uintptr_t)kmm_zalloc(loadinfo->textsize + loadinfo->datasize); if (!loadinfo->textalloc) { sdbg("ERROR: Failed to allocate memory for the module\n"); ret = -ENOMEM; goto errout_with_buffers; } loadinfo->datastart = loadinfo->textalloc + loadinfo->textsize; /* Load ELF section data into memory */ ret = mod_loadfile(loadinfo); if (ret < 0) { sdbg("ERROR: mod_loadfile failed: %d\n", ret); goto errout_with_buffers; } return OK; /* Error exits */ errout_with_buffers: mod_unload(loadinfo); return ret; }
FAR struct tm *gmtime_r(FAR const time_t *timer, FAR struct tm *result) { time_t epoch; time_t jdn; int year; int month; int day; int hour; int min; int sec; /* Get the seconds since the EPOCH */ epoch = *timer; sdbg("timer=%d\n", (int)epoch); /* Convert to days, hours, minutes, and seconds since the EPOCH */ jdn = epoch / SEC_PER_DAY; epoch -= SEC_PER_DAY * jdn; hour = epoch / SEC_PER_HOUR; epoch -= SEC_PER_HOUR * hour; min = epoch / SEC_PER_MIN; epoch -= SEC_PER_MIN * min; sec = epoch; sdbg("hour=%d min=%d sec=%d\n", (int)hour, (int)min, (int)sec); /* Convert the days since the EPOCH to calendar day */ clock_utc2calendar(jdn, &year, &month, &day); sdbg("jdn=%d year=%d month=%d day=%d\n", (int)jdn, (int)year, (int)month, (int)day); /* Then return the struct tm contents */ result->tm_year = (int)year - 1900; /* Relative to 1900 */ result->tm_mon = (int)month - 1; /* zero-based */ result->tm_mday = (int)day; /* one-based */ result->tm_hour = (int)hour; result->tm_min = (int)min; result->tm_sec = (int)sec; return result; }
int pthread_condattr_destroy(FAR pthread_condattr_t *attr) { int ret = OK; sdbg("attr=0x%p\n", attr); if (!attr) { ret = EINVAL; } sdbg("Returning %d\n", ret); return ret; }
int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR pthread_mutexattr_t *attr) { int pshared = 0; #ifdef CONFIG_MUTEX_TYPES uint8_t type = PTHREAD_MUTEX_DEFAULT; #endif int ret = OK; int status; sdbg("mutex=0x%p attr=0x%p\n", mutex, attr); if (!mutex) { ret = EINVAL; } else { /* Were attributes specified? If so, use them */ if (attr) { pshared = attr->pshared; #ifdef CONFIG_MUTEX_TYPES type = attr->type; #endif } /* Indicate that the semaphore is not held by any thread. */ mutex->pid = 0; /* Initialize the mutex like a semaphore with initial count = 1 */ status = sem_init((sem_t*)&mutex->sem, pshared, 1); if (status != OK) { ret = EINVAL; } /* Set up attributes unique to the mutex type */ #ifdef CONFIG_MUTEX_TYPES mutex->type = type; mutex->nlocks = 0; #endif } sdbg("Returning %d\n", ret); return ret; }
int pthread_detach(pthread_t thread) { FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; FAR struct task_group_s *group = rtcb->group; FAR struct join_s *pjoin; int ret; sdbg("Thread=%d group=%p\n", thread, group); DEBUGASSERT(group); /* Find the entry associated with this pthread. */ (void)pthread_takesemaphore(&group->tg_joinsem); pjoin = pthread_findjoininfo(group, (pid_t)thread); if (!pjoin) { sdbg("Could not find thread entry\n"); ret = EINVAL; } else { /* Has the thread already terminated? */ if (pjoin->terminated) { /* YES.. just remove the thread entry. */ pthread_destroyjoin(group, pjoin); } else { /* NO.. Just mark the thread as detached. It * will be removed and deallocated when the * thread exits */ pjoin->detached = true; } /* Either case is successful */ ret = OK; } (void)pthread_givesemaphore(&group->tg_joinsem); sdbg("Returning %d\n", ret); return ret; }
int pthread_cond_signal(FAR pthread_cond_t *cond) { int ret = OK; int sval; sdbg("cond=0x%p\n", cond); if (!cond) { ret = EINVAL; } else { /* Get the current value of the semaphore */ if (sem_getvalue((FAR sem_t *)&cond->sem, &sval) != OK) { ret = EINVAL; } /* If the value is less than zero (meaning that one or more * thread is waiting), then post the condition semaphore. * Only the highest priority waiting thread will get to execute */ else { /* One of my objectives in this design was to make pthread_cond_signal * usable from interrupt handlers. However, from interrupt handlers, * you cannot take the associated mutex before signaling the condition. * As a result, I think that there could be a race condition with * the following logic which assumes that the if sval < 0 then the * thread is waiting. Without the mutex, there is no atomic, protected * operation that will guarantee this to be so. */ sdbg("sval=%d\n", sval); if (sval < 0) { sdbg("Signalling...\n"); ret = pthread_givesemaphore((FAR sem_t *)&cond->sem); } } } sdbg("Returning %d\n", ret); return ret; }
int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) { int ret; sdbg("cond=0x%p mutex=0x%p\n", cond, mutex); /* Make sure that non-NULL references were provided. */ if (!cond || !mutex) { ret = EINVAL; } /* Make sure that the caller holds the mutex */ else if (mutex->pid != (int)getpid()) { ret = EPERM; } else { /* Give up the mutex */ sdbg("Give up mutex / take cond\n"); sched_lock(); mutex->pid = 0; ret = pthread_givesemaphore((sem_t*)&mutex->sem); /* Take the semaphore */ ret |= pthread_takesemaphore((sem_t*)&cond->sem); sched_unlock(); /* Reacquire the mutex */ sdbg("Reacquire mutex...\n"); ret |= pthread_takesemaphore((sem_t*)&mutex->sem); if (!ret) { mutex->pid = getpid();; } } sdbg("Returning %d\n", ret); return ret; }
int execv(FAR const char *path, FAR char * const argv[]) { FAR const struct symtab_s *symtab; int nsymbols; int ret; /* Get the current symbol table selection */ exec_getsymtab(&symtab, &nsymbols); /* Start the task */ ret = exec(path, (FAR char * const *)argv, symtab, nsymbols); if (ret < 0) { sdbg("exec failed: %d\n", errno); return ERROR; } /* Then exit */ exit(0); /* We should not get here, but might be needed by some compilers. Other, * smarter compilers might complain that this code is unreachable. You just * can't win. */ return ERROR; }
int mod_registry_del(FAR struct module_s *modp) { FAR struct module_s *prev; FAR struct module_s *curr; for (prev = NULL, curr = g_mod_registry; curr != NULL && curr != modp; prev = curr, curr = curr->flink); if (curr == NULL) { sdbg("ERROR: Could not find module entry\n"); return -ENOENT; } if (prev == NULL) { g_mod_registry = modp->flink; } else { prev->flink = modp->flink; } modp->flink = NULL; return OK; }
int pthread_mutex_trylock(FAR pthread_mutex_t *mutex) { int ret = OK; sdbg("mutex=0x%p\n", mutex); if (!mutex) { ret = EINVAL; } else { /* Make sure the semaphore is stable while we make the following * checks. This all needs to be one atomic action. */ sched_lock(); /* Try to get the semaphore. */ if (sem_trywait((sem_t*)&mutex->sem) == OK) { /* If we succussfully obtained the semaphore, then indicate * that we own it. */ mutex->pid = (int)getpid(); } /* Was it not available? */ else if (get_errno() == EAGAIN) { ret = EBUSY; } else { ret = EINVAL; } sched_unlock(); } sdbg("Returning %d\n", ret); return ret; }
int pthread_mutexattr_destroy(FAR pthread_mutexattr_t *attr) { int ret = OK; sdbg("attr=0x%p\n", attr); if (!attr) { ret = EINVAL; } else { attr->pshared = 0; } sdbg("Returning %d\n", ret); return ret; }
int sig_mqnotempty(int pid, int signo, void *sival_ptr) #endif { #ifdef CONFIG_SCHED_HAVE_PARENT FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; #endif siginfo_t info; int ret; #ifdef CONFIG_CAN_PASS_STRUCTS sdbg("pid=%p signo=%d value=%d\n", pid, signo, value.sival_int); #else sdbg("pid=%p signo=%d sival_ptr=%p\n", pid, signo, sival_ptr); #endif /* Verify that we can perform the signalling operation */ if (!GOOD_SIGNO(signo)) { return -EINVAL; } /* Create the siginfo structure */ info.si_signo = signo; info.si_code = SI_MESGQ; #ifdef CONFIG_CAN_PASS_STRUCTS info.si_value = value; #else info.si_value.sival_ptr = sival_ptr; #endif #ifdef CONFIG_SCHED_HAVE_PARENT info.si_pid = rtcb->pid; info.si_status = OK; #endif /* Process the receipt of the signal */ sched_lock(); ret = sig_dispatch(pid, &info); sched_unlock(); return ret; }
static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) { #if CONFIG_NFILE_DESCRIPTORS > 0 FAR struct filelist *filelist; #if CONFIG_NFILE_STREAMS > 0 FAR struct streamlist *streamlist; #endif int i; #endif sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); #if CONFIG_NFILE_DESCRIPTORS > 0 filelist = tcb->group->tg_filelist; for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) { struct inode *inode = filelist->fl_files[i].f_inode; if (inode) { sdbg(" fd=%d refcount=%d\n", i, inode->i_crefs); } } #endif #if CONFIG_NFILE_STREAMS > 0 streamlist = tcb->group->tg_streamlist; for (i = 0; i < CONFIG_NFILE_STREAMS; i++) { struct file_struct *filep = &streamlist->sl_streams[i]; if (filep->fs_fd >= 0) { #if CONFIG_STDIO_BUFFER_SIZE > 0 sdbg(" fd=%d nbytes=%d\n", filep->fs_fd, filep->fs_bufpos - filep->fs_bufstart); #else sdbg(" fd=%d\n", filep->fs_fd); #endif } } #endif }
int pthread_attr_getschedpolicy(FAR pthread_attr_t *attr, int *policy) { int ret; sdbg("attr=0x%p policy=0x%p\n", attr, policy); if (!attr || !policy) { ret = EINVAL; } else { *policy = attr->policy; ret = OK; } sdbg("Returning %d\n", ret); return ret; }
int pthread_attr_setstacksize(FAR pthread_attr_t *attr, long stacksize) { int ret; sdbg("attr=0x%p stacksize=%ld\n", attr, stacksize); if (!attr || stacksize < PTHREAD_STACK_MIN) { ret = EINVAL; } else { attr->stacksize = stacksize; ret = OK; } sdbg("Returning %d\n", ret); return ret; }
static snd_mixer_elem_t *sound_get_elem(const char *name, snd_mixer_t **mixer_handle) { int ret; snd_mixer_t *handle; snd_mixer_selem_id_t *sid; setenv("PULSE_INTERNAL", "0", 1); snd_mixer_selem_id_alloca(&sid); if (parse_simple_id(name, sid)) { fprintf(stderr, "Wrong scontrol identifier: %s\n", name); return NULL; } if ((ret = snd_mixer_open(&handle, 0)) < 0) { sdbg("Mixer %s open error: %s\n", card, snd_strerror(ret)); return NULL; } if (smixer_level == 0 && (ret = snd_mixer_attach(handle, card)) < 0) { sdbg("Mixer attach %s error: %s", card, snd_strerror(ret)); snd_mixer_close(handle); handle = NULL; return NULL; } if ((ret = snd_mixer_selem_register(handle, smixer_level > 0 ? &smixer_options : NULL, NULL)) < 0) { sdbg("Mixer register error: %s", snd_strerror(ret)); snd_mixer_close(handle); handle = NULL; return NULL; } ret = snd_mixer_load(handle); if (ret < 0) { sdbg("Mixer %s load error: %s", card, snd_strerror(ret)); snd_mixer_close(handle); handle = NULL; return NULL; } *mixer_handle = handle; return snd_mixer_find_selem(handle, sid); }
static int posix_spawn_exec(FAR pid_t *pidp, FAR const char *path, FAR const posix_spawnattr_t *attr, FAR char * const argv[]) { FAR const struct symtab_s *symtab; int nsymbols; int pid; int ret = OK; DEBUGASSERT(path); /* Get the current symbol table selection */ exec_getsymtab(&symtab, &nsymbols); /* Disable pre-emption so that we can modify the task parameters after * we start the new task; the new task will not actually begin execution * until we re-enable pre-emption. */ sched_lock(); /* Start the task */ pid = exec(path, (FAR char * const *)argv, symtab, nsymbols); if (pid < 0) { ret = get_errno(); sdbg("ERROR: exec failed: %d\n", ret); goto errout; } /* Return the task ID to the caller */ if (pid) { *pidp = pid; } /* Now set the attributes. Note that we ignore all of the return values * here because we have already successfully started the task. If we * return an error value, then we would also have to stop the task. */ if (attr) { (void)spawn_execattrs(pid, attr); } /* Re-enable pre-emption and return */ errout: sched_unlock(); return ret; }
int pthread_mutex_destroy(FAR pthread_mutex_t *mutex) { int ret = OK; int status; sdbg("mutex=0x%p\n", mutex); if (!mutex) { ret = EINVAL; } else { /* Make sure the semaphore is stable while we make the following * checks */ sched_lock(); /* Is the semaphore available? */ if (mutex->pid != 0) { ret = EBUSY; } else { /* Destroy the semaphore */ status = sem_destroy((sem_t*)&mutex->sem); if (status != OK) { ret = EINVAL; } } sched_unlock(); } sdbg("Returning %d\n", ret); return ret; }