Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 30 additions & 17 deletions sched/sched/sched_smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <nuttx/config.h>

#include <assert.h>
#include <nuttx/arch.h>
#include <nuttx/nuttx.h>
#include <nuttx/queue.h>
Expand Down Expand Up @@ -61,6 +62,7 @@ struct smp_call_data_s

static sq_queue_t g_smp_call_queue[CONFIG_SMP_NCPUS];
static struct smp_call_data_s g_smp_call_data;
static spinlock_t g_smp_call_lock;

/****************************************************************************
* Private Functions
Expand All @@ -86,9 +88,9 @@ static void nxsched_smp_call_add(int cpu,
{
irqstate_t flags;

flags = enter_critical_section();
flags = spin_lock_irqsave(&g_smp_call_lock);
sq_addlast(&call_data->node[cpu], &g_smp_call_queue[cpu]);
leave_critical_section(flags);
spin_unlock_irqrestore(&g_smp_call_lock, flags);
}

/****************************************************************************
Expand Down Expand Up @@ -119,7 +121,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
FAR sq_entry_t *next;
int cpu = this_cpu();

irqstate_t flags = enter_critical_section();
irqstate_t flags = spin_lock_irqsave(&g_smp_call_lock);

call_queue = &g_smp_call_queue[cpu];

Expand All @@ -132,32 +134,32 @@ int nxsched_smp_call_handler(int irq, FAR void *context,

sq_rem(&call_data->node[cpu], call_queue);

leave_critical_section(flags);
spin_unlock_irqrestore(&g_smp_call_lock, flags);

ret = call_data->func(call_data->arg);

flags = enter_critical_section();
if (call_data->cookie != NULL)
flags = spin_lock_irqsave(&g_smp_call_lock);
if (spin_is_locked(&call_data->lock))
{
if (ret < 0)
if (--call_data->refcount == 0)
{
call_data->cookie->error = ret;
spin_unlock(&call_data->lock);
}

nxsem_post(&call_data->cookie->sem);
}

if (spin_is_locked(&call_data->lock))
if (call_data->cookie != NULL)
{
if (--call_data->refcount == 0)
if (ret < 0)
{
spin_unlock(&call_data->lock);
call_data->cookie->error = ret;
}

nxsem_post(&call_data->cookie->sem);
}
}

up_cpu_paused_restore();
leave_critical_section(flags);
spin_unlock_irqrestore(&g_smp_call_lock, flags);
return OK;
}

Expand Down Expand Up @@ -219,13 +221,20 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func,
};

FAR struct smp_call_data_s *call_data;
int remote_cpus = 0;
int remote_cpus;
int ret = OK;
int i;

/* Cannot wait in interrupt context. */

DEBUGASSERT(!(wait && up_interrupt_context()));

/* Prevent reschedule on another processor */

sched_lock();
if (!up_interrupt_context())
{
sched_lock();
}

if (CPU_ISSET(this_cpu(), &cpuset))
{
Expand Down Expand Up @@ -293,6 +302,10 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func,
}

out:
sched_unlock();
if (!up_interrupt_context())
{
sched_unlock();
}

return ret;
}