summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vlib/vlib/threads.c12
-rw-r--r--vlib/vlib/unix/main.c5
-rw-r--r--vppinfra/Makefile.am3
-rw-r--r--vppinfra/vppinfra/mem_mheap.c7
-rw-r--r--vppinfra/vppinfra/os.h1
-rw-r--r--vppinfra/vppinfra/smp.h276
-rw-r--r--vppinfra/vppinfra/unix-misc.c10
7 files changed, 20 insertions, 294 deletions
diff --git a/vlib/vlib/threads.c b/vlib/vlib/threads.c
index 72f340ea205..302e201397b 100644
--- a/vlib/vlib/threads.c
+++ b/vlib/vlib/threads.c
@@ -77,6 +77,18 @@ os_get_cpu_number (void)
return n;
}
+uword
+os_get_ncpus (void)
+{
+ u32 len;
+
+ len = vec_len (vlib_thread_stacks);
+ if (len == 0)
+ return 1;
+ else
+ return len;
+}
+
void
vlib_set_thread_name (char *name)
{
diff --git a/vlib/vlib/unix/main.c b/vlib/vlib/unix/main.c
index 3c17031b884..efa4f20f03f 100644
--- a/vlib/vlib/unix/main.c
+++ b/vlib/vlib/unix/main.c
@@ -439,8 +439,6 @@ int
vlib_unix_main (int argc, char *argv[])
{
vlib_main_t *vm = &vlib_global_main; /* one and only time for this! */
-
- clib_smp_main_t *sm = &clib_smp_main;
vlib_thread_main_t *tm = &vlib_thread_main;
unformat_input_t input;
u8 *thread_stacks;
@@ -472,9 +470,6 @@ vlib_unix_main (int argc, char *argv[])
((uword) tm->n_thread_stacks * VLIB_THREAD_STACK_SIZE,
(VLIB_MAX_CPUS << VLIB_LOG2_THREAD_STACK_SIZE));
- sm->vm_base = thread_stacks;
- sm->log2_n_per_cpu_vm_bytes = VLIB_LOG2_THREAD_STACK_SIZE;
-
vec_validate (vlib_thread_stacks, tm->n_thread_stacks - 1);
for (i = 0; i < vec_len (vlib_thread_stacks); i++)
{
diff --git a/vppinfra/Makefile.am b/vppinfra/Makefile.am
index a9de5ad03b3..f9855e34f79 100644
--- a/vppinfra/Makefile.am
+++ b/vppinfra/Makefile.am
@@ -200,7 +200,6 @@ nobase_include_HEADERS = \
vppinfra/serialize.h \
vppinfra/slist.h \
vppinfra/smp.h \
- vppinfra/smp_fifo.h \
vppinfra/socket.h \
vppinfra/sparse_vec.h \
vppinfra/string.h \
@@ -247,8 +246,6 @@ CLIB_CORE = \
vppinfra/random_isaac.c \
vppinfra/serialize.c \
vppinfra/slist.c \
- vppinfra/smp.c \
- vppinfra/smp_fifo.c \
vppinfra/std-formats.c \
vppinfra/string.c \
vppinfra/time.c \
diff --git a/vppinfra/vppinfra/mem_mheap.c b/vppinfra/vppinfra/mem_mheap.c
index 5718c8ce618..00437b011c9 100644
--- a/vppinfra/vppinfra/mem_mheap.c
+++ b/vppinfra/vppinfra/mem_mheap.c
@@ -43,13 +43,6 @@
#include <vppinfra/memcheck.h>
#include <vppinfra/valgrind.h>
-clib_smp_main_t clib_smp_main = {
- .n_cpus = 0,
- .log2_n_per_cpu_stack_bytes = 20,
- .log2_n_per_cpu_vm_bytes = 28,
- .n_tls_4k_pages = 1,
-};
-
void * clib_per_cpu_mheaps[CLIB_MAX_MHEAPS];
void clib_mem_exit (void)
diff --git a/vppinfra/vppinfra/os.h b/vppinfra/vppinfra/os.h
index b63b35cc654..124864f5578 100644
--- a/vppinfra/vppinfra/os.h
+++ b/vppinfra/vppinfra/os.h
@@ -57,6 +57,7 @@ void os_out_of_memory (void);
f64 os_cpu_clock_frequency (void);
uword os_get_cpu_number (void);
+uword os_get_ncpus (void);
#include <vppinfra/smp.h>
diff --git a/vppinfra/vppinfra/smp.h b/vppinfra/vppinfra/smp.h
index 9f92a9fc816..7f0b93ccb91 100644
--- a/vppinfra/vppinfra/smp.h
+++ b/vppinfra/vppinfra/smp.h
@@ -41,70 +41,6 @@
#include <vppinfra/cache.h>
#include <vppinfra/os.h> /* for os_panic */
-/* Per-CPU state. */
-typedef struct {
- /* Per-cpu local heap. */
- void * heap;
-
- u32 thread_id;
-} clib_smp_per_cpu_main_t;
-
-typedef struct {
- /* Number of CPUs used to model current computer. */
- u32 n_cpus;
-
- /* Number of cpus that are done and have exited. */
- u32 n_cpus_exited;
-
- /* Log2 stack and vm (heap) size. */
- u8 log2_n_per_cpu_stack_bytes, log2_n_per_cpu_vm_bytes;
-
- /* Thread local store (TLS) is stored at stack top.
- Number of 4k pages to allocate for TLS. */
- u16 n_tls_4k_pages;
-
- /* Per cpus stacks/heaps start at these addresses. */
- void * vm_base;
-
- /* Thread-safe global heap. Objects here can be allocated/freed by any cpu. */
- void * global_heap;
-
- clib_smp_per_cpu_main_t * per_cpu_mains;
-} clib_smp_main_t;
-
-extern clib_smp_main_t clib_smp_main;
-
-always_inline void *
-clib_smp_vm_base_for_cpu (clib_smp_main_t * m, uword cpu)
-{
- return m->vm_base + (cpu << m->log2_n_per_cpu_vm_bytes);
-}
-
-always_inline void *
-clib_smp_stack_top_for_cpu (clib_smp_main_t * m, uword cpu)
-{
- /* Stack is at top of per cpu VM area. */
- return clib_smp_vm_base_for_cpu (m, cpu + 1) - ((uword) 1 << m->log2_n_per_cpu_stack_bytes);
-}
-
-always_inline uword
-os_get_cpu_number_inline (void)
-{
- clib_smp_main_t * m = &clib_smp_main;
- void * sp;
- uword n;
-
- /* Get any old stack address. */
- sp = &sp;
-
- n = ((uword)sp - (uword)m->vm_base) >> m->log2_n_per_cpu_vm_bytes;
-
- if (CLIB_DEBUG && m->n_cpus > 0 && n >= m->n_cpus)
- os_panic ();
-
- return n < m->n_cpus ? n : 0;
-}
-
#define clib_smp_compare_and_swap(addr,new,old) __sync_val_compare_and_swap(addr,old,new)
#define clib_smp_swap(addr,new) __sync_lock_test_and_set(addr,new)
#define clib_smp_atomic_add(addr,increment) __sync_fetch_and_add(addr,increment)
@@ -129,217 +65,5 @@ os_sched_yield (void)
{ clib_smp_pause (); }
#endif
-typedef enum {
- CLIB_SMP_LOCK_TYPE_READER,
- CLIB_SMP_LOCK_TYPE_WRITER,
- CLIB_SMP_LOCK_TYPE_SPIN,
-} clib_smp_lock_type_t;
-
-typedef enum {
- CLIB_SMP_LOCK_WAIT_EMPTY,
- CLIB_SMP_LOCK_WAIT_DONE,
- CLIB_SMP_LOCK_WAIT_READER,
- CLIB_SMP_LOCK_WAIT_WRITER,
-} clib_smp_lock_wait_type_t;
-
-#if uword_bits == 64
-typedef u16 clib_smp_quarter_word_t;
-typedef u32 clib_smp_half_word_t;
-#else
-typedef u8 clib_smp_quarter_word_t;
-typedef u16 clib_smp_half_word_t;
-#endif
-
-typedef union {
- struct {
- /* FIFO of CPUs (threads) waiting for lock. */
- struct {
- clib_smp_quarter_word_t head_index, n_elts;
- } waiting_fifo;
-
- /* Requesting CPU for atomic compare_and_swap instructions.
- This makes CPUs requesting same header change unique. */
- clib_smp_quarter_word_t request_cpu;
-
- /* Count of readers who have been given read lock.
- Not applicable for spin locks. */
- clib_smp_quarter_word_t n_readers_with_lock : BITS (clib_smp_quarter_word_t) - 1;
-
- /* Set when writer has been given write lock. Only one of
- these can happen at a time. */
- clib_smp_quarter_word_t writer_has_lock : 1;
- };
-
- uword as_uword;
-} clib_smp_lock_header_t;
-
-always_inline uword
-clib_smp_lock_header_is_equal (clib_smp_lock_header_t h0, clib_smp_lock_header_t h1)
-{ return h0.as_uword == h1.as_uword; }
-
-typedef struct {
- volatile clib_smp_lock_wait_type_t wait_type;
- u8 pad[CLIB_CACHE_LINE_BYTES - 1 * sizeof (clib_smp_lock_wait_type_t)];
-} clib_smp_lock_waiting_fifo_elt_t;
-
-/* Cache aligned. */
-typedef struct {
- clib_smp_lock_header_t header;
-
- /* Size of waiting FIFO; equal to max number of threads less one. */
- u32 n_waiting_fifo_elts;
-
- u8 pad[CLIB_CACHE_LINE_BYTES - sizeof (clib_smp_lock_header_t) - sizeof (u32)];
-
- clib_smp_lock_waiting_fifo_elt_t waiting_fifo[0];
-} clib_smp_lock_t;
-
-always_inline clib_smp_lock_header_t
-clib_smp_lock_set_header (clib_smp_lock_t * l, clib_smp_lock_header_t new_hdr, clib_smp_lock_header_t old)
-{
- clib_smp_lock_header_t cmp;
- cmp.as_uword = clib_smp_compare_and_swap (&l->header.as_uword, new_hdr.as_uword, old.as_uword);
- return cmp;
-}
-
-void clib_smp_lock_init (clib_smp_lock_t ** l);
-void clib_smp_lock_free (clib_smp_lock_t ** l);
-void clib_smp_lock_slow_path (clib_smp_lock_t * l, uword my_cpu, clib_smp_lock_header_t h, clib_smp_lock_type_t type);
-void clib_smp_unlock_slow_path (clib_smp_lock_t * l, uword my_cpu, clib_smp_lock_header_t h, clib_smp_lock_type_t type);
-
-always_inline void
-clib_smp_lock_inline (clib_smp_lock_t * l, clib_smp_lock_type_t type)
-{
- clib_smp_lock_header_t h0, h1, h2;
- uword is_reader = type == CLIB_SMP_LOCK_TYPE_READER;
- uword my_cpu;
-
- /* Null lock means n_cpus <= 1: nothing to lock. */
- if (! l)
- return;
-
- my_cpu = os_get_cpu_number_inline ();
- h0 = l->header;
- while (! h0.writer_has_lock)
- {
- /* Want to write but there are still readers with lock? */
- if (type == CLIB_SMP_LOCK_TYPE_WRITER && h0.n_readers_with_lock != 0)
- break;
-
- if (type == CLIB_SMP_LOCK_TYPE_SPIN)
- ASSERT_AND_PANIC (h0.waiting_fifo.n_elts == 0);
-
- /* Read/write can't proceed when waiting fifo is non-empty. */
- else if (h0.waiting_fifo.n_elts != 0)
- break;
-
- h1 = h0;
- h1.request_cpu = my_cpu;
- h1.writer_has_lock = ! is_reader;
- h1.n_readers_with_lock += is_reader;
-
- /* Try to set head and tail to zero and thereby get the lock. */
- h2 = clib_smp_lock_set_header (l, h1, h0);
-
- /* Compare and swap succeeded? If so, we got the lock. */
- if (clib_smp_lock_header_is_equal (h2, h0))
- return;
-
- /* Header for slow path. */
- h0 = h2;
- }
-
- clib_smp_lock_slow_path (l, my_cpu, h0, type);
-}
-
-always_inline void
-clib_smp_unlock_inline (clib_smp_lock_t * l, clib_smp_lock_type_t type)
-{
- clib_smp_lock_header_t h0, h1;
- uword is_reader = type == CLIB_SMP_LOCK_TYPE_READER;
- uword my_cpu;
-
- /* Null means no locking is necessary. */
- if (! l)
- return;
-
- my_cpu = os_get_cpu_number_inline ();
- h0 = l->header;
-
- /* Should be locked. */
- if (is_reader)
- {
- ASSERT_AND_PANIC (h0.n_readers_with_lock != 0);
- ASSERT_AND_PANIC (h0.writer_has_lock == 0);
- }
- else
- {
- ASSERT_AND_PANIC (h0.n_readers_with_lock == 0);
- ASSERT_AND_PANIC (h0.writer_has_lock);
- }
-
- /* Locked but empty waiting fifo? */
- while (h0.waiting_fifo.n_elts == 0)
- {
- /* Try to mark it unlocked. */
- h1 = h0;
- if (is_reader)
- h1.n_readers_with_lock -= 1;
- else
- h1.writer_has_lock = 0;
- h1.request_cpu = my_cpu;
- h1 = clib_smp_lock_set_header (l, h1, h0);
- if (clib_smp_lock_header_is_equal (h1, h0))
- return;
- h0 = h1;
- }
-
- /* Other cpus are waiting. */
- clib_smp_unlock_slow_path (l, my_cpu, h0, type);
-}
-
-always_inline void
-clib_smp_lock (clib_smp_lock_t * l)
-{ clib_smp_lock_inline (l, CLIB_SMP_LOCK_TYPE_SPIN); }
-
-always_inline void
-clib_smp_lock_for_writer (clib_smp_lock_t * l)
-{ clib_smp_lock_inline (l, CLIB_SMP_LOCK_TYPE_WRITER); }
-
-always_inline void
-clib_smp_lock_for_reader (clib_smp_lock_t * l)
-{ clib_smp_lock_inline (l, CLIB_SMP_LOCK_TYPE_READER); }
-
-always_inline void
-clib_smp_unlock (clib_smp_lock_t * l)
-{ clib_smp_unlock_inline (l, CLIB_SMP_LOCK_TYPE_SPIN); }
-
-always_inline void
-clib_smp_unlock_for_writer (clib_smp_lock_t * l)
-{ clib_smp_unlock_inline (l, CLIB_SMP_LOCK_TYPE_WRITER); }
-
-always_inline void
-clib_smp_unlock_for_reader (clib_smp_lock_t * l)
-{ clib_smp_unlock_inline (l, CLIB_SMP_LOCK_TYPE_READER); }
-
-#define clib_exec_on_global_heap(body) \
-do { \
- void * __clib_exec_on_global_heap_saved_heap; \
- \
- /* Switch to global (thread-safe) heap. */ \
- __clib_exec_on_global_heap_saved_heap = clib_mem_set_heap (clib_smp_main.global_heap); \
- \
- /* Execute body. */ \
- body; \
- \
- /* Switch back to previous heap. */ \
- clib_mem_set_heap (__clib_exec_on_global_heap_saved_heap); \
-} while (0)
-
-uword os_smp_bootstrap (uword n_cpus,
- void * bootstrap_function,
- uword bootstrap_function_arg);
-
-void clib_smp_init (void);
#endif /* included_clib_smp_h */
diff --git a/vppinfra/vppinfra/unix-misc.c b/vppinfra/vppinfra/unix-misc.c
index 7b6683a6aef..4a654066c5b 100644
--- a/vppinfra/vppinfra/unix-misc.c
+++ b/vppinfra/vppinfra/unix-misc.c
@@ -174,14 +174,14 @@ void os_puts (u8 * string, uword string_length, uword is_error)
void os_puts (u8 * string, uword string_length, uword is_error)
{
- clib_smp_main_t * m = &clib_smp_main;
int cpu = os_get_cpu_number ();
+ int ncpus = os_get_ncpus();
char buf[64];
int fd = is_error ? 2 : 1;
struct iovec iovs[2];
int n_iovs = 0;
- if (m->n_cpus > 1)
+ if (ncpus > 1)
{
snprintf (buf, sizeof(buf), "%d: ", cpu);
@@ -204,4 +204,8 @@ void os_out_of_memory (void)
uword os_get_cpu_number (void) __attribute__ ((weak));
uword os_get_cpu_number (void)
-{ return os_get_cpu_number_inline(); }
+{ return 0; }
+
+uword os_get_ncpus (void) __attribute__ ((weak));
+uword os_get_ncpus (void)
+{ return 1; }