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;
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #5
0
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
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #24
0
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;
}
Exemple #25
0
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;
}
Exemple #28
0
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);
}
Exemple #29
0
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;
}