Ejemplo n.º 1
0
void mq_desblockalloc(void)
{
  FAR struct mq_des_block_s *mqdesblock;

  /* Allocate a block of message descriptors */

  mqdesblock = (FAR struct mq_des_block_s *)kmm_malloc(sizeof(struct mq_des_block_s));
  if (mqdesblock)
    {
      int i;

      /* Add the block to the list of allocated blocks (in case
       * we ever need to reclaim the memory.
       */

      sq_addlast((FAR sq_entry_t*)&mqdesblock->queue, &g_desalloc);

      /* Then add each message queue descriptor to the free list */

      for (i = 0; i < NUM_MSG_DESCRIPTORS; i++)
        {
          sq_addlast((FAR sq_entry_t*)&mqdesblock->mqdes[i], &g_desfree);
        }
    }
}
Ejemplo n.º 2
0
void mq_msgfree(FAR mqmsg_t *mqmsg)
{
  irqstate_t saved_state;

  /* If this is a generally available pre-allocated message,
   * then just put it back in the free list.
   */

  if (mqmsg->type == MQ_ALLOC_FIXED)
    {
      /* Make sure we avoid concurrent access to the free
       * list from interrupt handlers.
       */

      saved_state = irqsave();
      sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfree);
      irqrestore(saved_state);
    }

  /* If this is a message pre-allocated for interrupts,
   * then put it back in the correct  free list.
   */

  else if (mqmsg->type == MQ_ALLOC_IRQ)
    {
      /* Make sure we avoid concurrent access to the free
       * list from interrupt handlers.
       */

      saved_state = irqsave();
      sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfreeirq);
      irqrestore(saved_state);
    }

  /* Otherwise, deallocate it.  Note:  interrupt handlers
   * will never deallocate messages because they will not
   * received them.
   */

  else if (mqmsg->type == MQ_ALLOC_DYN)
    {
      sched_kfree(mqmsg);
    }
  else
    {
      PANIC();
    }
}
Ejemplo n.º 3
0
static inline void timer_free(struct posix_timer_s *timer)
{
  irqstate_t flags;

  /* Remove the timer from the allocated list */

  flags = irqsave();
  sq_rem((FAR sq_entry_t *)timer, (FAR sq_queue_t *)&g_alloctimers);

  /* Return it to the free list if it is one of the preallocated timers */

#if CONFIG_PREALLOC_TIMERS > 0
  if ((timer->pt_flags & PT_FLAGS_PREALLOCATED) != 0)
    {
      sq_addlast((FAR sq_entry_t *)timer, (FAR sq_queue_t *)&g_freetimers);
      irqrestore(flags);
    }
  else
#endif
    {
      /* Otherwise, return it to the heap */

      irqrestore(flags);
      sched_kfree(timer);
    }
}
Ejemplo n.º 4
0
static int
enqueue_work_item_and_wait_for_result(work_q_item_t *item)
{
	/* put the work item at the end of the work queue */
	lock_queue(&g_work_q);
	sq_addlast(&item->link, &(g_work_q.q));

	/* Adjust the queue size and potentially the maximum queue size */
	if (++g_work_q.size > g_work_q.max_size) {
		g_work_q.max_size = g_work_q.size;
	}

	unlock_queue(&g_work_q);

	/* tell the work thread that work is available */
	px4_sem_post(&g_work_queued_sema);

	/* wait for the result */
	px4_sem_wait(&item->wait_sem);

	int result = item->result;

	destroy_work_item(item);

	return result;
}
Ejemplo n.º 5
0
void wd_initialize(void)
{
  /* Initialize the free watchdog list */

  sq_init(&g_wdfreelist);

  /* The g_wdfreelist must be loaded at initialization time to hold the
   * configured number of watchdogs.
   */

  g_wdpool = (FAR wdog_t*)kmalloc(sizeof(wdog_t) * CONFIG_PREALLOC_WDOGS);
  if (g_wdpool)
    {
      FAR wdog_t *wdog = g_wdpool;
      int i;

      for (i = 0; i < CONFIG_PREALLOC_WDOGS; i++)
        {
          sq_addlast((FAR sq_entry_t*)wdog++, &g_wdfreelist);
        }
    }

  /* The g_wdactivelist queue must be reset at initialization time. */

  sq_init(&g_wdactivelist);
}
Ejemplo n.º 6
0
static void vnc_add_queue(FAR struct vnc_session_s *session,
                          FAR struct vnc_fbupdate_s *rect)
{
  /* Lock the scheduler to assure that the sq_addlast() and the sem_post()
   * are atomic.
   */

  sched_lock();
  vnc_sem_debug(session, "Before add", 1);

  /* Put the entry into the list of queued rectangles. */

  sq_addlast((FAR sq_entry_t *)rect, &session->updqueue);

  /* Post the semaphore to indicate the availability of one more rectangle
   * in the queue.  This may wakeup the updater.
   */

  sem_post(&session->queuesem);

  vnc_sem_debug(session, "After add", 0);
  DEBUGASSERT(session->queuesem.semcount <= CONFIG_VNCSERVER_NUPDATES);

  sched_unlock();
}
Ejemplo n.º 7
0
static struct mqueue_msg_s *
mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs,
                 uint8_t alloc_type)
{
  struct mqueue_msg_s *mqmsgblock;

  /* The g_msgfree must be loaded at initialization time to hold the
   * configured number of messages.
   */

  mqmsgblock = (FAR struct mqueue_msg_s*)
    kmm_malloc(sizeof(struct mqueue_msg_s) * nmsgs);

  if (mqmsgblock)
    {
      struct mqueue_msg_s *mqmsg = mqmsgblock;
      int      i;

      for (i = 0; i < nmsgs; i++)
        {
          mqmsg->type = alloc_type;
          sq_addlast((FAR sq_entry_t*)mqmsg++, queue);
        }
    }

  return mqmsgblock;
}
int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask,
                 uip_ipaddr_t router)
{
  FAR struct net_route_s *route;
  uip_lock_t save;

  /* Allocate a route entry */

  route = net_allocroute();
  if (!route)
    {
      ndbg("ERROR:  Failed to allocate a route\n");
      return -ENOMEM;
    }

  /* Format the new route table entry */

  uip_ipaddr_copy(route->target, target);
  uip_ipaddr_copy(route->netmask, netmask);
  uip_ipaddr_copy(route->router, router);

  /* Get exclusive address to the networking data structures */

  save = uip_lock();

  /* Then add the new entry to the table */

  sq_addlast((FAR sq_entry_t *)route, (FAR sq_queue_t *)&g_routes);
  uip_unlock(save);
  return OK;
}
Ejemplo n.º 9
0
int wd_delete(WDOG_ID wdog)
{
  irqstate_t state;

  DEBUGASSERT(wdog);

  /* The following steps are atomic... the watchdog must not be active when
   * it is being deallocated.
   */

  state = irqsave();

  /* Check if the watchdog has been started. */

  if (WDOG_ISACTIVE(wdog))
    {
      /* Yes.. stop it */

      wd_cancel(wdog);
    }

  /* Did this watchdog come from the pool of pre-allocated timers?  Or, was
   * it allocated from the heap?
   */

  if (WDOG_ISALLOCED(wdog))
    {
      /* It was allocated from the heap.  Use sched_kfree() to release the
       * memory.  If the timer was released from an interrupt handler,
       * sched_kfree() will defer the actual deallocation of the memory
       * until a more appropriate time.
       *
       * We don't need interrupts disabled to do this.
       */

      irqrestore(state);
      sched_kfree(wdog);
    }

  /* This was a pre-allocated timer.  This function should not be called for
   * statically allocated timers.
   */

  else if (!WDOG_ISSTATIC(wdog))
    {
      /* Put the timer back on the free list and increment the count of free
       * timers, all with interrupts disabled.
       */

      sq_addlast((FAR sq_entry_t *)wdog, &g_wdfreelist);
      g_wdnfree++;
      DEBUGASSERT(g_wdnfree <= CONFIG_PREALLOC_WDOGS);
      irqrestore(state);
    }

  /* Return success */

  return OK;
}
Ejemplo n.º 10
0
/**
 * @brief Put the node to the back of the queue.
 *
 * @param queue The target queue to put.
 * @param node The pointer to node.
 * @return None.
 */
static void put_node_back(sq_queue_t *queue, struct buf_node *node)
{
    irqstate_t flags = irqsave();

    sq_addlast(&node->entry, queue);

    irqrestore(flags);
}
Ejemplo n.º 11
0
void sig_releasependingsignal(FAR sigpendq_t *sigpend)
{
  irqstate_t saved_state;

  /* If this is a generally available pre-allocated structyre,
   * then just put it back in the free list.
   */

  if (sigpend->type == SIG_ALLOC_FIXED)
    {
      /* Make sure we avoid concurrent access to the free
       * list from interrupt handlers.
       */

      saved_state = irqsave();
      sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingsignal);
      irqrestore(saved_state);
    }

  /* If this is a message pre-allocated for interrupts,
   * then put it back in the correct free list.
   */

  else if (sigpend->type == SIG_ALLOC_IRQ)
    {
      /* Make sure we avoid concurrent access to the free
       * list from interrupt handlers.
       */

      saved_state = irqsave();
      sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingirqsignal);
      irqrestore(saved_state);
    }

  /* Otherwise, deallocate it.  Note:  interrupt handlers
   * will never deallocate signals because they will not
   * receive them.
   */

  else if (sigpend->type == SIG_ALLOC_DYN)
    {
      sched_kfree(sigpend);
    }
}
Ejemplo n.º 12
0
int uip_backlogdelete(FAR struct uip_conn *conn, FAR struct uip_conn *blconn)
{
  FAR struct uip_backlog_s     *bls;
  FAR struct uip_blcontainer_s *blc;
  FAR struct uip_blcontainer_s *prev;

  nllvdbg("conn=%p blconn=%p\n", conn, blconn);

#ifdef CONFIG_DEBUG
  if (!conn)
    {
      return -EINVAL;
    }
#endif

  bls = conn->backlog;
  if (bls)
    {
       /* Find the container hold the connection */

       for (blc = (FAR struct uip_blcontainer_s *)sq_peek(&bls->bl_pending), prev = NULL;
            blc;
            prev = blc, blc = (FAR struct uip_blcontainer_s *)sq_next(&blc->bc_node))
         {
            if (blc->bc_conn == blconn)
              {
                if (prev)
                  {
                    /* Remove the a container from the middle of the list of
                     * pending connections
                      */

                    (void)sq_remafter(&prev->bc_node, &bls->bl_pending);
                  }
                else
                  {
                    /* Remove the a container from the head of the list of
                     * pending connections
                     */

                    (void)sq_remfirst(&bls->bl_pending);
                  }

                /* Put container in the free list */

                blc->bc_conn = NULL;
                sq_addlast(&blc->bc_node, &bls->bl_free);
                return OK;
              }
          }

        nlldbg("Failed to find pending connection\n");
        return -EINVAL;
    }
  return OK;
}
Ejemplo n.º 13
0
uint16_t uip_datahandler(FAR struct uip_conn *conn, FAR uint8_t *buffer,
                         uint16_t buflen)
{
    FAR struct uip_readahead_s *readahead1;
    FAR struct uip_readahead_s *readahead2 = NULL;
    uint16_t remaining;
    uint16_t recvlen = 0;

    /* First, we need to determine if we have space to buffer the data.  This
     * needs to be verified before we actually begin buffering the data. We
     * will use any remaining space in the last allocated readahead buffer
     * plus as much one additional buffer.  It is expected that the size of
     * readahead buffers are tuned so that one full packet will always fit
     * into one readahead buffer (for example if the buffer size is 420, then
     * a readahead buffer of 366 will hold a full packet of TCP data).
     */

    readahead1 = (FAR struct uip_readahead_s*)conn->readahead.tail;
    if ((readahead1 &&
            (CONFIG_NET_TCP_READAHEAD_BUFSIZE - readahead1->rh_nbytes) > buflen) ||
            (readahead2 = uip_tcpreadahead_alloc()) != NULL)
    {
        /* We have buffer space.  Now try to append add as much data as possible
         * to the last readahead buffer attached to this connection.
         */

        remaining = buflen;
        if (readahead1)
        {
            recvlen = uip_readahead(readahead1, buffer, remaining);
            if (recvlen > 0)
            {
                buffer    += recvlen;
                remaining -= recvlen;
            }
        }

        /* Do we need to buffer into the newly allocated buffer as well? */

        if (readahead2)
        {
            readahead2->rh_nbytes = 0;
            recvlen += uip_readahead(readahead2, buffer, remaining);

            /* Save the readahead buffer in the connection structure where
             * it can be found with recv() is called.
             */

            sq_addlast(&readahead2->rh_node, &conn->readahead);
        }
    }

    nllvdbg("Buffered %d bytes (of %d)\n", recvlen, buflen);
    return recvlen;
}
Ejemplo n.º 14
0
void sched_ufree(FAR void *address)
{
#ifdef CONFIG_BUILD_KERNEL
    /* REVISIT:  It is not safe to defer user allocation in the kernel mode
     * build.  Why?  Because the correct user context is in place now but
     * will not be in place when the deferred de-allocation is performed.  In
     * order to make this work, we would need to do something like:  (1) move
     * g_delayed_kufree into the group structure, then traverse the groups to
     * collect garbage on a group-by-group basis.
     */

    ASSERT(!up_interrupt_context());
    kumm_free(address);

#else
    /* Check if this is an attempt to deallocate memory from an exception
     * handler.  If this function is called from the IDLE task, then we
     * must have exclusive access to the memory manager to do this.
     */

    if (up_interrupt_context() || kumm_trysemaphore() != 0)
    {
        irqstate_t flags;

        /* Yes.. Make sure that this is not a attempt to free kernel memory
         * using the user deallocator.
         */

        flags = irqsave();
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
     defined(CONFIG_MM_KERNEL_HEAP)
        DEBUGASSERT(!kmm_heapmember(address));
#endif

        /* Delay the deallocation until a more appropriate time. */

        sq_addlast((FAR sq_entry_t *)address,
                   (FAR sq_queue_t *)&g_delayed_kufree);

        /* Signal the worker thread that is has some clean up to do */

#ifdef CONFIG_SCHED_WORKQUEUE
        work_signal(LPWORK);
#endif
        irqrestore(flags);
    }
    else
    {
        /* No.. just deallocate the memory now. */

        kumm_free(address);
        kumm_givesemaphore();
    }
#endif
}
Ejemplo n.º 15
0
void sq_addafter(sq_entry_t *prev, sq_entry_t *node,
		 sq_queue_t *queue)
{
	if (!queue->head || prev == queue->tail) {
		sq_addlast(node, queue);

	} else {
		node->flink = prev->flink;
		prev->flink = node;
	}
}
Ejemplo n.º 16
0
void usbstrg_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
{
  FAR struct usbstrg_dev_s *priv;
  FAR struct usbstrg_req_s *privreq;
  irqstate_t flags;

  /* Sanity check */

#ifdef CONFIG_DEBUG
  if (!ep || !ep->priv || !req || !req->priv)
    {
      usbtrace(TRACE_CLSERROR(USBSTRG_TRACEERR_WRCOMPLETEINVALIDARGS), 0);
      return;
     }
#endif

  /* Extract references to private data */

  priv    = (FAR struct usbstrg_dev_s*)ep->priv;
  privreq = (FAR struct usbstrg_req_s *)req->priv;

  /* Return the write request to the free list */

  flags = irqsave();
  sq_addlast((sq_entry_t*)privreq, &priv->wrreqlist);
  irqrestore(flags);

  /* Process the received data unless this is some unusual condition */

  switch (req->result)
    {
    case OK: /* Normal completion */
      usbtrace(TRACE_CLASSWRCOMPLETE, req->xfrd);
      break;

    case -ESHUTDOWN: /* Disconnection */
      usbtrace(TRACE_CLSERROR(USBSTRG_TRACEERR_WRSHUTDOWN), 0);
      break;

    default: /* Some other error occurred */
      usbtrace(TRACE_CLSERROR(USBSTRG_TRACEERR_WRUNEXPECTED),
               (uint16_t)-req->result);
      break;
    };

  /* Inform the worker thread that a write request has been returned */

  priv->theventset |= USBSTRG_EVENT_WRCOMPLETE;
  pthread_cond_signal(&priv->cond);
}
Ejemplo n.º 17
0
void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb)
{
  DEBUGASSERT(wrb && wrb->wb_iob);

  /* To avoid deadlocks, we must following this ordering:  Release the I/O
   * buffer chain first, then the write buffer structure.
   */

  iob_free_chain(wrb->wb_iob);

  /* Then free the write buffer structure */

  sq_addlast(&wrb->wb_node, &g_wrbuffer.freebuffers);
  sem_post(&g_wrbuffer.sem);
}
void net_freeroute(FAR struct net_route_s *route)
{
  uip_lock_t save;

  DEBUGASSERT(route);

  /* Get exclusive address to the networking data structures */

  save = uip_lock();

  /* Then add the new entry to the table */

  sq_addlast((FAR sq_entry_t *)route, (FAR sq_queue_t *)&g_freeroutes);
  uip_unlock(save);
}
Ejemplo n.º 19
0
static int sig_queueaction(FAR struct tcb_s *stcb, siginfo_t *info)
{
  FAR sigactq_t *sigact;
  FAR sigq_t    *sigq;
  irqstate_t     flags;
  int            ret = OK;

  sched_lock();
  DEBUGASSERT(stcb != NULL && stcb->group != NULL);

  /* Find the group sigaction associated with this signal */

  sigact = sig_findaction(stcb->group, info->si_signo);

  /* Check if a valid signal handler is available and if the signal is
   * unblocked.  NOTE:  There is no default action.
   */

  if ((sigact) && (sigact->act.sa_u._sa_sigaction))
    {
      /* Allocate a new element for the signal queue.  NOTE:
       * sig_allocatependingsigaction will force a system crash if it is
       * unable to allocate memory for the signal data */

      sigq = sig_allocatependingsigaction();
      if (!sigq)
        {
          ret = -ENOMEM;
        }
      else
        {
          /* Populate the new signal queue element */

          sigq->action.sighandler = sigact->act.sa_u._sa_sigaction;
          sigq->mask = sigact->act.sa_mask;
          memcpy(&sigq->info, info, sizeof(siginfo_t));

          /* Put it at the end of the pending signals list */

          flags = enter_critical_section();
          sq_addlast((FAR sq_entry_t *)sigq, &(stcb->sigpendactionq));
          leave_critical_section(flags);
        }
    }

  sched_unlock();
  return ret;
}
Ejemplo n.º 20
0
int pm_register(FAR struct pm_callback_s *callbacks)
{
  int ret;

  DEBUGASSERT(callbacks);

  /* Add the new entry to the end of the list of registered callbacks */

  ret = pm_lock();
  if (ret == OK)
    {
      sq_addlast(&callbacks->entry, &g_pmglobals.registry);
      pm_unlock();
    }
  return ret;
}
Ejemplo n.º 21
0
void sig_allocateactionblock(void)
{
  sigactq_t *sigact;
  int i;

  /* Allocate a block of signal actions */

  g_sigactionalloc =
     (sigactq_t*)kmalloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS);

  sigact = g_sigactionalloc;
  for (i = 0; i < NUM_SIGNAL_ACTIONS; i++)
    {
      sq_addlast((FAR sq_entry_t*)sigact++, &g_sigfreeaction);
    }
}
void net_initroute(void)
{
  int i;

  /* Initialize the routing table and the free list */

  sq_init(&g_routes);
  sq_init(&g_freeroutes);

  /* All all of the pre-allocated routing table entries to a free list */

  for (i = 0; i < CONFIG_NET_MAXROUTES; i++)
    {
      sq_addlast((FAR sq_entry_t *)&g_preallocroutes[i],
                 (FAR sq_queue_t *)&g_freeroutes);
    }    
}
Ejemplo n.º 23
0
static struct posix_timer_s *timer_allocate(void)
{
  FAR struct posix_timer_s *ret;
  irqstate_t flags;
  uint8_t pt_flags;

  /* Try to get a preallocated timer from the free list */

#if CONFIG_PREALLOC_TIMERS > 0
  flags = irqsave();
  ret   = (FAR struct posix_timer_s *)sq_remfirst((FAR sq_queue_t *)&g_freetimers);
  irqrestore(flags);

  /* Did we get one? */

  if (ret)
    {
      pt_flags = PT_FLAGS_PREALLOCATED;
    }
  else
#endif
    {
      /* Allocate a new timer from the heap */

      ret      = (FAR struct posix_timer_s *)kmm_malloc(sizeof(struct posix_timer_s));
      pt_flags = 0;
    }

  /* If we have a timer, then put it into the allocated timer list */

  if (ret)
    {
      /* Initialize the timer structure */

      memset(ret, 0, sizeof(struct posix_timer_s));
      ret->pt_flags = pt_flags;

      /* And add it to the end of the list of allocated timers */

      flags = irqsave();
      sq_addlast((FAR sq_entry_t *)ret, (FAR sq_queue_t *)&g_alloctimers);
      irqrestore(flags);
    }

  return ret;
}
Ejemplo n.º 24
0
void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
{
  uip_lock_t flags;

  grplldbg("Free: %p flags: %02x\n", group, group->flags);

  /* Cancel the wdog */

  flags = uip_lock();
  wd_cancel(group->wdog);
  
  /* Remove the group structure from the group list in the device structure */

  sq_rem((FAR sq_entry_t*)group, &dev->grplist);
  
  /* Destroy the wait semapore */

  (void)sem_destroy(&group->sem);

  /* Destroy the wdog */

  wd_delete(group->wdog);
  
  /* Then release the group structure resources.  Check first if this is one
   * of the pre-allocated group structures that we will retain in a free list.
   */

#if CONFIG_PREALLOC_IGMPGROUPS > 0
  if (IS_PREALLOCATED(group->flags))
    {
      grplldbg("Put back on free list\n");
      sq_addlast((FAR sq_entry_t*)group, &g_freelist);
      uip_unlock(flags);
    }
  else
#endif
    {
      /* No.. deallocate the group structure.  Use sched_free() just in case
       * this function is executing within an interrupt handler.
       */

      uip_unlock(flags);
      grplldbg("Call sched_free()\n");
      sched_free(group);
    }
}
Ejemplo n.º 25
0
static int sig_queueaction(FAR _TCB *stcb, siginfo_t *info)
{
  FAR sigactq_t *sigact;
  FAR sigq_t    *sigq;
  irqstate_t     saved_state;
  int            ret = OK;

  sched_lock();

  /* Find the sigaction associated with this signal */

  sigact = sig_findaction(stcb, info->si_signo);

  /* Check if a valid signal handler is available and if the signal is
   * unblocked.  NOTE:  There is no default action.
   */

  if ((sigact) && (sigact->act.sa_u._sa_sigaction))
    {
      /* Allocate a new element for the signal queue.  NOTE: sig_allocatependingsigaction
       * will force a system crash if it is unable to allocate memory for the
       * signal data */

      sigq = sig_allocatependingsigaction();
      if (!sigq) ret = ERROR;
      else
        {
          /* Populate the new signal queue element */

           sigq->action.sighandler = sigact->act.sa_u._sa_sigaction;
           sigq->mask = sigact->act.sa_mask;
           memcpy(&sigq->info, info, sizeof(siginfo_t));

           /* Put it at the end of the pending signals list */

           saved_state = irqsave();
           sq_addlast((FAR sq_entry_t*)sigq, &(stcb->sigpendactionq));
           irqrestore(saved_state);
        }
    }

  sched_unlock();
  return ret;
}
Ejemplo n.º 26
0
static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb,
                                            FAR siginfo_t *info)
{
  FAR struct task_group_s *group;
  FAR sigpendq_t *sigpend;
  irqstate_t flags;

  DEBUGASSERT(stcb != NULL && stcb->group != NULL);
  group = stcb->group;

  /* Check if the signal is already pending for the group */

  sigpend = sig_findpendingsignal(group, info->si_signo);
  if (sigpend)
    {
      /* The signal is already pending... retain only one copy */

      memcpy(&sigpend->info, info, sizeof(siginfo_t));
    }

  /* No... There is nothing pending in the group for this signo */

  else
    {
      /* Allocate a new pending signal entry */

      sigpend = sig_allocatependingsignal();
      if (sigpend)
        {
          /* Put the signal information into the allocated structure */

          memcpy(&sigpend->info, info, sizeof(siginfo_t));

          /* Add the structure to the group pending signal list */

          flags = enter_critical_section();
          sq_addlast((FAR sq_entry_t *)sigpend, &group->tg_sigpendingq);
          leave_critical_section(flags);
        }
    }

  return sigpend;
}
Ejemplo n.º 27
0
static FAR sigpendq_t *sig_addpendingsignal(FAR struct tcb_s *stcb,
                                            FAR siginfo_t *info)
{
  FAR struct task_group_s *group = stcb->group;
  FAR sigpendq_t *sigpend;
  irqstate_t saved_state;

  DEBUGASSERT(group);

  /* Check if the signal is already pending */

  sigpend = sig_findpendingsignal(group, info->si_signo);
  if (sigpend)
    {
      /* The signal is already pending... retain only one copy */

      memcpy(&sigpend->info, info, sizeof(siginfo_t));
    }

  /* No... There is nothing pending for this signo */

  else
    {
      /* Allocate a new pending signal entry */

      sigpend = sig_allocatependingsignal();
      if (sigpend)
        {
          /* Put the signal information into the allocated structure */

          memcpy(&sigpend->info, info, sizeof(siginfo_t));

          /* Add the structure to the pending signal list */

          saved_state = irqsave();
          sq_addlast((FAR sq_entry_t*)sigpend, &group->sigpendingq);
          irqrestore(saved_state);
        }
    }

  return sigpend;
}
Ejemplo n.º 28
0
static sigq_t *sig_allocateblock(sq_queue_t *siglist, uint16_t nsigs,
                                 uint8_t sigtype)
{
  sigq_t *sigqalloc;
  sigq_t *sigq;
  int     i;

  /* Allocate a block of pending signal actions */

  sigqalloc = (sigq_t*)kmalloc((sizeof(sigq_t)) * nsigs);

  sigq = sigqalloc;
  for (i = 0; i < nsigs; i++)
    {
      sigq->type = sigtype;
      sq_addlast((FAR sq_entry_t*)sigq++, siglist);
    }

  return sigqalloc;
}
Ejemplo n.º 29
0
static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *siglist,
                                                  uint16_t nsigs, uint8_t sigtype)
{
  sigpendq_t *sigpendalloc;
  sigpendq_t *sigpend;
  int i;

  /* Allocate a block of pending signal structures  */

  sigpendalloc =
     (sigpendq_t*)kmalloc((sizeof(sigpendq_t)) * nsigs);

  sigpend = sigpendalloc;
  for (i = 0; i < nsigs; i++)
    {
      sigpend->type = sigtype;
      sq_addlast((FAR sq_entry_t*)sigpend++, siglist);
    }

  return sigpendalloc;
}
Ejemplo n.º 30
0
void sched_ufree(FAR void *address)
{
    irqstate_t flags;

    /* Check if this is an attempt to deallocate memory from an exception
     * handler.  If this function is called from the IDLE task, then we
     * must have exclusive access to the memory manager to do this.
     */

    if (up_interrupt_context() || kumm_trysemaphore() != 0)
    {
        /* Yes.. Make sure that this is not a attempt to free kernel memory
         * using the user deallocator.
         */

        flags = irqsave();
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
     defined(CONFIG_MM_KERNEL_HEAP)
        DEBUGASSERT(!kmm_heapmember(address));
#endif

        /* Delay the deallocation until a more appropriate time. */

        sq_addlast((FAR sq_entry_t*)address, (sq_queue_t*)&g_delayed_kufree);

        /* Signal the worker thread that is has some clean up to do */

#ifdef CONFIG_SCHED_WORKQUEUE
        work_signal(LPWORK);
#endif
        irqrestore(flags);
    }
    else
    {
        /* No.. just deallocate the memory now. */

        kumm_free(address);
        kumm_givesemaphore();
    }
}