got all of the code to actually compile again

I don't think it actually works though.
diff --git a/aos/atom_code/ipc_lib/aos_sync.c b/aos/atom_code/ipc_lib/aos_sync.c
index 29f3081..92b11c4 100644
--- a/aos/atom_code/ipc_lib/aos_sync.c
+++ b/aos/atom_code/ipc_lib/aos_sync.c
@@ -1,4 +1,4 @@
-#include "aos_sync.h"
+#include "aos/atom_code/ipc_lib/aos_sync.h"
 
 #include <stdio.h>
 #include <linux/futex.h>
diff --git a/aos/atom_code/ipc_lib/aos_sync.h b/aos/atom_code/ipc_lib/aos_sync.h
index 80364e9..0cecd68 100644
--- a/aos/atom_code/ipc_lib/aos_sync.h
+++ b/aos/atom_code/ipc_lib/aos_sync.h
@@ -1,5 +1,5 @@
-#ifndef AOS_IPC_LIB_SYNC_H_
-#define AOS_IPC_LIB_SYNC_H_
+#ifndef AOS_ATOM_CODE_IPC_LIB_SYNC_H_
+#define AOS_ATOM_CODE_IPC_LIB_SYNC_H_
 
 #include <stdlib.h>
 #include <signal.h>
@@ -90,4 +90,4 @@
 }
 #endif  // __cplusplus
 
-#endif
+#endif  // AOS_ATOM_CODE_IPC_LIB_SYNC_H_
diff --git a/aos/atom_code/ipc_lib/binheap.c b/aos/atom_code/ipc_lib/binheap.c
deleted file mode 100644
index 8eb024d..0000000
--- a/aos/atom_code/ipc_lib/binheap.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "binheap.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifndef TESTING_ASSERT
-#define TESTING_ASSERT(...)
-#endif
-#define Error(x) TESTING_ASSERT(0, x)
-
-#define MinData (0)
-
-void Initialize( int Elements, PriorityQueue H )
-{
-	H->Capacity = Elements - 1;
-	H->Size = 0;
-	H->Elements[ 0 ] = MinData;
-}
-
-int Insert( ElementType X, PriorityQueue H )
-{
-	int i;
-
-	if( IsFull( H ) )
-	{
-		return -1;
-	}
-
-	for( i = ++H->Size; H->Elements[ i / 2 ] > X; i /= 2 )
-		H->Elements[ i ] = H->Elements[ i / 2 ];
-	H->Elements[ i ] = X;
-	return 0;
-}
-
-void Remove( ElementType X, PriorityQueue H )
-{
-	int i, Child, removed = 0;
-	ElementType LastElement;
-
-	for ( i = 1; i <= H->Size; ++i )
-	{
-		if( H->Elements[ i ] == X )
-		{
-			removed = i;
-			break;
-		}
-	}
-	if( removed == 0 )
-	{
-		fprintf(stderr, "could not find element %d to remove. not removing any\n", X);
-		return;
-	}
-
-	LastElement = H->Elements[ H->Size-- ];
-
-	for( i = removed; i * 2 <= H->Size; i = Child )
-	{
-		/* Find smaller child */
-		Child = i * 2;
-		if( Child != H->Size && H->Elements[ Child + 1 ]
-				< H->Elements[ Child ] )
-			Child++;
-
-		/* Percolate one level */
-		if( LastElement > H->Elements[ Child ] )
-			H->Elements[ i ] = H->Elements[ Child ];
-		else
-			break;
-	}
-	H->Elements[ i ] = LastElement;
-}
-
-ElementType DeleteMin( PriorityQueue H )
-{
-	int i, Child;
-	ElementType MinElement, LastElement;
-
-	if( IsEmpty( H ) )
-	{
-		Error( "Priority queue is empty" );
-		return H->Elements[ 0 ];
-	}
-	MinElement = H->Elements[ 1 ];
-	LastElement = H->Elements[ H->Size-- ];
-
-	for( i = 1; i * 2 <= H->Size; i = Child )
-	{
-		/* Find smaller child */
-		Child = i * 2;
-		if( Child != H->Size && H->Elements[ Child + 1 ]
-				< H->Elements[ Child ] )
-			Child++;
-
-		/* Percolate one level */
-		if( LastElement > H->Elements[ Child ] )
-			H->Elements[ i ] = H->Elements[ Child ];
-		else
-			break;
-	}
-	H->Elements[ i ] = LastElement;
-	return MinElement;
-}
-
-ElementType GetMin( PriorityQueue H )
-{
-	if( !IsEmpty( H ) )
-		return H->Elements[ 1 ];
-	Error( "Priority Queue is Empty" );
-	return H->Elements[ 0 ];
-}
-
-int IsEmpty( PriorityQueue H )
-{
-	return H->Size == 0;
-}
-
-int IsFull( PriorityQueue H )
-{
-	return H->Size == H->Capacity;
-}
-
-int GetSize( PriorityQueue H )
-{
-	return H->Size;
-}
-
diff --git a/aos/atom_code/ipc_lib/binheap.h b/aos/atom_code/ipc_lib/binheap.h
deleted file mode 100644
index 8c26f9f..0000000
--- a/aos/atom_code/ipc_lib/binheap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _BinHeap_H
-#define _BinHeap_H
-
-#include <stdint.h>
-
-typedef uint8_t ElementType;
-struct HeapStruct;
-typedef struct HeapStruct *PriorityQueue;
-
-struct HeapStruct
-{
-	int Capacity;
-	int Size;
-	ElementType *Elements;
-};
-
-// Elements is the number allocated at H->Elements
-void Initialize( int Elements, PriorityQueue H );
-// 0 if successful, -1 if full
-int Insert( ElementType X, PriorityQueue H );
-void Remove( ElementType X, PriorityQueue H );
-ElementType DeleteMin( PriorityQueue H );
-ElementType GetMin( PriorityQueue H );
-int IsEmpty( PriorityQueue H );
-int IsFull( PriorityQueue H );
-int GetSize( PriorityQueue H );
-
-#endif
-
diff --git a/aos/atom_code/ipc_lib/binheap_test.cpp b/aos/atom_code/ipc_lib/binheap_test.cpp
deleted file mode 100644
index 62eecd4..0000000
--- a/aos/atom_code/ipc_lib/binheap_test.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-extern "C" {
-#include "binheap.h"
-}
-
-#include <gtest/gtest.h>
-
-class BinHeapTest : public testing::Test{
-	protected:
-		static const int TEST_ELEMENTS = 57;
-		PriorityQueue queue;
-		virtual void SetUp(){
-			queue = new HeapStruct();
-			queue->Elements = new uint8_t[TEST_ELEMENTS];
-			Initialize(TEST_ELEMENTS, queue);
-		}
-		virtual void TearDown(){
-			delete[] queue->Elements;
-			delete queue;
-		}
-};
-
-std::ostream& operator<< (std::ostream& o, uint8_t c){
-    return o<<(int)c;
-}
-
-testing::AssertionResult Contains(PriorityQueue queue, const uint8_t expected[], size_t length){
-	for(size_t i = 0; i < length; ++i){
-		//printf("expected[%d]=%d\n", i, expected[i]);
-		if(DeleteMin(queue) != expected[i]){
-			return testing::AssertionFailure() << "queue[" << i << "] != " << expected[i];
-		}
-	}
-	if(!IsEmpty(queue))
-		return testing::AssertionFailure() << "queue is longer than " << length;
-	return ::testing::AssertionSuccess();
-}
-
-TEST_F(BinHeapTest, SingleElement){
-	Insert(87, queue);
-	EXPECT_EQ(87, DeleteMin(queue));
-	EXPECT_TRUE(IsEmpty(queue));
-}
-TEST_F(BinHeapTest, MultipleElements){
-	Insert(54, queue);
-	Insert(1, queue);
-	Insert(0, queue);
-	Insert(255, queue);
-	Insert(123, queue);
-	uint8_t expected[] = {0, 1, 54, 123, 255};
-	EXPECT_TRUE(Contains(queue, expected, sizeof(expected)));
-}
-TEST_F(BinHeapTest, Removals){
-	Insert(54, queue);
-	Insert(1, queue);
-	Insert(0, queue);
-	Insert(255, queue);
-	Insert(123, queue);
-	Remove(255, queue);
-	Remove(0, queue);
-	Insert(222, queue);
-	Insert(67, queue);
-	uint8_t expected[] = {1, 54, 67, 123, 222};
-	EXPECT_TRUE(Contains(queue, expected, sizeof(expected)));
-}
-
diff --git a/aos/atom_code/ipc_lib/cmpxchg.h b/aos/atom_code/ipc_lib/cmpxchg.h
index acb4a3c..715c57d 100644
--- a/aos/atom_code/ipc_lib/cmpxchg.h
+++ b/aos/atom_code/ipc_lib/cmpxchg.h
@@ -9,10 +9,10 @@
 
 #define cmpxchg(ptr, o, n) __sync_val_compare_and_swap(ptr, o, n)
 /*#define xchg(ptr, n) ({typeof(*ptr) r; \
-		do{ \
-			r = *ptr; \
-		}while(!__sync_bool_compare_and_swap(ptr, r, n)); \
-		r; \
+    do{ \
+      r = *ptr; \
+    }while(!__sync_bool_compare_and_swap(ptr, r, n)); \
+    r; \
 })*/
 
 #  define LOCK "lock;"
@@ -24,7 +24,7 @@
 
 /*static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
 {
-	*ptr = val;
+  *ptr = val;
 }
 
 #define _set_64bit set_64bit*/
@@ -32,37 +32,37 @@
 /*
  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  * Note 2: xchg has side effect, so that attribute volatile is necessary,
- *	  but generally the primitive is invalid, *ptr is output argument. --ANK
+ *    but generally the primitive is invalid, *ptr is output argument. --ANK
  */
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
-	switch (size) {
-		case 1:
-			__asm__ __volatile__("xchgb %b0,%1"
-					:"=q" (x)
-					:"m" (*__xg(ptr)), "0" (x)
-					:"memory");
-			break;
-		case 2:
-			__asm__ __volatile__("xchgw %w0,%1"
-					:"=r" (x)
-					:"m" (*__xg(ptr)), "0" (x)
-					:"memory");
-			break;
-		case 4:
-			__asm__ __volatile__("xchgl %k0,%1"
-					:"=r" (x)
-					:"m" (*__xg(ptr)), "0" (x)
-					:"memory");
-			break;
-		case 8:
-			__asm__ __volatile__("xchg %0,%1"
-					:"=r" (x)
-					:"m" (*__xg(ptr)), "0" (x)
-					:"memory");
-			break;
-	}
-	return x;
+  switch (size) {
+    case 1:
+      __asm__ __volatile__("xchgb %b0,%1"
+          :"=q" (x)
+          :"m" (*__xg(ptr)), "0" (x)
+          :"memory");
+      break;
+    case 2:
+      __asm__ __volatile__("xchgw %w0,%1"
+          :"=r" (x)
+          :"m" (*__xg(ptr)), "0" (x)
+          :"memory");
+      break;
+    case 4:
+      __asm__ __volatile__("xchgl %k0,%1"
+          :"=r" (x)
+          :"m" (*__xg(ptr)), "0" (x)
+          :"memory");
+      break;
+    case 8:
+      __asm__ __volatile__("xchg %0,%1"
+          :"=r" (x)
+          :"m" (*__xg(ptr)), "0" (x)
+          :"memory");
+      break;
+  }
+  return x;
 }
 
 /*
@@ -76,78 +76,78 @@
 #define __HAVE_ARCH_CMPXCHG 1
 
 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-		unsigned long new, int size)
+    unsigned long new, int size)
 {
-	int32_t prev;
-	switch (size) {
-		case 1:
-			__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
-				    : "=a"(prev)
-				    : "q"(new), "m"(*__xg(ptr)), "0"(old)
-				    : "memory");
-			return prev;
-		case 2:
-			__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
-				    : "=a"(prev)
-				    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-				    : "memory");
-			return prev;
-		case 4:
-			__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
-				    : "=a"(prev)
-				    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-				    : "memory");
-			return prev;
-		case 8:
-			__asm__ __volatile__("lock; cmpxchg %1,%2"
-				    : "=a"(prev)
-				    : "q"(new), "m"(*__xg(ptr)), "0"(old)
-				    : "memory");
-			return prev;
-	}
-	return old;
+  int32_t prev;
+  switch (size) {
+    case 1:
+      __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+            : "=a"(prev)
+            : "q"(new), "m"(*__xg(ptr)), "0"(old)
+            : "memory");
+      return prev;
+    case 2:
+      __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+            : "=a"(prev)
+            : "r"(new), "m"(*__xg(ptr)), "0"(old)
+            : "memory");
+      return prev;
+    case 4:
+      __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
+            : "=a"(prev)
+            : "r"(new), "m"(*__xg(ptr)), "0"(old)
+            : "memory");
+      return prev;
+    case 8:
+      __asm__ __volatile__("lock; cmpxchg %1,%2"
+            : "=a"(prev)
+            : "q"(new), "m"(*__xg(ptr)), "0"(old)
+            : "memory");
+      return prev;
+  }
+  return old;
 }
 
 /*
 static inline unsigned long __cmpxchg_local(volatile void *ptr,
-			unsigned long old, unsigned long new, int size)
+      unsigned long old, unsigned long new, int size)
 {
-	unsigned long prev;
-	switch (size) {
-	case 1:
-		__asm__ __volatile__("cmpxchgb %b1,%2"
-				     : "=a"(prev)
-				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
-				     : "memory");
-		return prev;
-	case 2:
-		__asm__ __volatile__("cmpxchgw %w1,%2"
-				     : "=a"(prev)
-				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-				     : "memory");
-		return prev;
-	case 4:
-		__asm__ __volatile__("cmpxchgl %k1,%2"
-				     : "=a"(prev)
-				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-				     : "memory");
-		return prev;
-	case 8:
-		__asm__ __volatile__("cmpxchgq %1,%2"
-				     : "=a"(prev)
-				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
-				     : "memory");
-		return prev;
-	}
-	return old;
+  unsigned long prev;
+  switch (size) {
+  case 1:
+    __asm__ __volatile__("cmpxchgb %b1,%2"
+             : "=a"(prev)
+             : "q"(new), "m"(*__xg(ptr)), "0"(old)
+             : "memory");
+    return prev;
+  case 2:
+    __asm__ __volatile__("cmpxchgw %w1,%2"
+             : "=a"(prev)
+             : "r"(new), "m"(*__xg(ptr)), "0"(old)
+             : "memory");
+    return prev;
+  case 4:
+    __asm__ __volatile__("cmpxchgl %k1,%2"
+             : "=a"(prev)
+             : "r"(new), "m"(*__xg(ptr)), "0"(old)
+             : "memory");
+    return prev;
+  case 8:
+    __asm__ __volatile__("cmpxchgq %1,%2"
+             : "=a"(prev)
+             : "r"(new), "m"(*__xg(ptr)), "0"(old)
+             : "memory");
+    return prev;
+  }
+  return old;
 }*/
 
 #define cmpxchg(ptr,o,n)\
-	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-					(unsigned long)(n),sizeof(*(ptr))))
+  ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+          (unsigned long)(n),sizeof(*(ptr))))
 /*#define cmpxchg_local(ptr,o,n)\
-	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-					(unsigned long)(n),sizeof(*(ptr))))*/
+  ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+          (unsigned long)(n),sizeof(*(ptr))))*/
 #endif
 
 #endif
diff --git a/aos/atom_code/ipc_lib/condition.cc b/aos/atom_code/ipc_lib/condition.cc
index 1524773..f65c67d 100644
--- a/aos/atom_code/ipc_lib/condition.cc
+++ b/aos/atom_code/ipc_lib/condition.cc
@@ -6,49 +6,23 @@
 
 namespace aos {
 
+static_assert(shm_ok<condition_variable>::value,
+              "all C structs really should work in shared memory");
 static_assert(shm_ok<Condition>::value, "Condition should work"
               " in shared memory");
 
-Condition::Condition() : impl_(0) {}
+Condition::Condition(Mutex *m) : impl_(), m_(m) {}
 
-bool Condition::Wait() {
-  switch (condition_wait(&impl_)) {
-    case 1:
-      return false;
-    case 0:
-      return true;
-    default:
-      if (errno != EINTR) {
-        LOG(FATAL, "condition_wait(%p(=%"PRIu32")) failed because of %d: %s\n",
-            &impl_, impl_, errno, strerror(errno));
-      }
-      return false;
-  }
-}
-bool Condition::WaitNext() {
-  switch (condition_wait_force(&impl_)) {
-    case 1:
-      return false;
-    case 0:
-      return true;
-    default:
-      if (errno != EINTR) {
-        LOG(FATAL, "condition_wait_force(%p(=%"PRIu32")) failed"
-            " because of %d: %s\n", &impl_, impl_, errno, strerror(errno));
-      }
-      return false;
-  }
+void Condition::Wait() {
+  condition_wait(&impl_, &m_->impl_);
 }
 
-void Condition::Set() {
-  if (condition_set(&impl_) == -1) {
-    LOG(FATAL, "condition_set(%p(=%"PRIu32")) failed because of %d: %s\n",
-        &impl_, impl_, errno, strerror(errno));
-  }
+void Condition::Signal() {
+  condition_signal(&impl_);
 }
-void Condition::Unset() {
-  // can not fail
-  condition_unset(&impl_);
+
+void Condition::Broadcast() {
+  condition_broadcast(&impl_);
 }
 
 }  // namespace aos
diff --git a/aos/atom_code/ipc_lib/core_lib.c b/aos/atom_code/ipc_lib/core_lib.c
index 26581a1..bbd2f5b 100644
--- a/aos/atom_code/ipc_lib/core_lib.c
+++ b/aos/atom_code/ipc_lib/core_lib.c
@@ -1,48 +1,43 @@
+#include "aos/atom_code/ipc_lib/core_lib.h"
+
 #include <stdio.h>
 #include <stdlib.h>
-#include "shared_mem.h"
-#include "core_lib.h"
-#include <time.h>
 
-void init_shared_mem_core(aos_shm_core *shm_core) {
-	clock_gettime(CLOCK_REALTIME, &shm_core->identifier);
-	shm_core->msg_alloc_lock = 0;
-	shm_core->queues.queue_list = NULL;
-	shm_core->queues.alloc_lock = 0;
-}
+#include "aos/atom_code/ipc_lib/shared_mem.h"
+
 static inline uint8_t aos_8max(uint8_t l, uint8_t r) {
-	return (l > r) ? l : r;
+  return (l > r) ? l : r;
 }
 void *shm_malloc_aligned(size_t length, uint8_t alignment) {
-	// minimum alignments from <http://software.intel.com/en-us/articles/data-alignment-when-migrating-to-64-bit-intel-architecture/>
-	if (length <= 1) {
-		alignment = aos_8max(alignment, 1);
-	} else if (length <= 2) {
-		alignment = aos_8max(alignment, 2);
-	} else if (length <= 4) {
-		alignment = aos_8max(alignment, 4);
-	} else if (length <= 8) {
-		alignment = aos_8max(alignment, 8);
-	} else if (length <= 16) {
-		alignment = aos_8max(alignment, 16);
-	} else {
-		alignment = aos_8max(alignment, (length >= 64) ? 64 : 16);
-	}
+  // minimum alignments from <http://software.intel.com/en-us/articles/data-alignment-when-migrating-to-64-bit-intel-architecture/>
+  if (length <= 1) {
+    alignment = aos_8max(alignment, 1);
+  } else if (length <= 2) {
+    alignment = aos_8max(alignment, 2);
+  } else if (length <= 4) {
+    alignment = aos_8max(alignment, 4);
+  } else if (length <= 8) {
+    alignment = aos_8max(alignment, 8);
+  } else if (length <= 16) {
+    alignment = aos_8max(alignment, 16);
+  } else {
+    alignment = aos_8max(alignment, (length >= 64) ? 64 : 16);
+  }
 
-	void *msg = NULL;
-	aos_shm_core *shm_core = global_core->mem_struct;
-	mutex_grab(&shm_core->msg_alloc_lock);
-	shm_core->msg_alloc = (uint8_t *)shm_core->msg_alloc - length;
-	const uint8_t align_extra = (uintptr_t)shm_core->msg_alloc % alignment;
-	shm_core->msg_alloc = (uint8_t *)shm_core->msg_alloc - align_extra;
-	msg = shm_core->msg_alloc;
-	if (msg <= global_core->shared_mem) {
-		fprintf(stderr, "core_lib: RAN OUT OF SHARED MEMORY!!!----------------------------------------------------------\n");
-		printf("if you didn't see the stderr output just then, you should\n");
-		abort();
-	}
-	//printf("alloc %p\n", msg);
-	mutex_unlock(&shm_core->msg_alloc_lock);
-	return msg;
+  void *msg = NULL;
+  aos_shm_core *shm_core = global_core->mem_struct;
+  mutex_grab(&shm_core->msg_alloc_lock);
+  shm_core->msg_alloc = (uint8_t *)shm_core->msg_alloc - length;
+  const uint8_t align_extra = (uintptr_t)shm_core->msg_alloc % alignment;
+  shm_core->msg_alloc = (uint8_t *)shm_core->msg_alloc - align_extra;
+  msg = shm_core->msg_alloc;
+  if (msg <= global_core->shared_mem) {
+    fprintf(stderr, "core_lib: RAN OUT OF SHARED MEMORY!!!----------------------------------------------------------\n");
+    printf("if you didn't see the stderr output just then, you should have\n");
+    abort();
+  }
+  //printf("alloc %p\n", msg);
+  mutex_unlock(&shm_core->msg_alloc_lock);
+  return msg;
 }
 
diff --git a/aos/atom_code/ipc_lib/core_lib.h b/aos/atom_code/ipc_lib/core_lib.h
index 233660b..5674220 100644
--- a/aos/atom_code/ipc_lib/core_lib.h
+++ b/aos/atom_code/ipc_lib/core_lib.h
@@ -1,42 +1,14 @@
 #ifndef _AOS_CORE_LIB_H_
 #define _AOS_CORE_LIB_H_
 
-// defined in shared_mem.c
-#ifdef __cplusplus
-extern "C" {
-#endif  // __cplusplus
-extern struct aos_core *global_core;
-#ifdef __cplusplus
-}
-#endif  // __cplusplus
-
-#include "aos_sync.h"
-#include "queue.h"
 #include <stdint.h>
 
+#include "aos/atom_code/ipc_lib/aos_sync.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif  // __cplusplus
 
-typedef struct aos_queue_global_t {
-	mutex alloc_lock;
-	void *queue_list;  // an aos::Queue* declared in C code
-} aos_queue_global;
-
-typedef struct aos_shm_core_t {
-  // clock_gettime(CLOCK_REALTIME, &identifier) gets called to identify
-  // this shared memory area
-  struct timespec identifier;
-  // gets 0-initialized at the start (as part of shared memory) and
-  // the owner sets as soon as it finishes setting stuff up
-  mutex creation_condition;
-  mutex msg_alloc_lock;
-  void *msg_alloc;
-  aos_queue_global queues;
-} aos_shm_core;
-
-void init_shared_mem_core(aos_shm_core *shm_core);
-
 void *shm_malloc_aligned(size_t length, uint8_t alignment)
     __attribute__((alloc_size(1)));
 static void *shm_malloc(size_t length) __attribute__((alloc_size(1)));
diff --git a/aos/atom_code/ipc_lib/ipc_lib.gyp b/aos/atom_code/ipc_lib/ipc_lib.gyp
index 4614680..7d42b04 100644
--- a/aos/atom_code/ipc_lib/ipc_lib.gyp
+++ b/aos/atom_code/ipc_lib/ipc_lib.gyp
@@ -1,41 +1,64 @@
 {
   'targets': [
     {
-      'target_name': 'ipc_lib',
+      'target_name': 'aos_sync',
       'type': 'static_library',
       'sources': [
         'aos_sync.c',
-        'binheap.c',
-        'core_lib.c',
-        'queue.c',
-        'shared_mem.c',
-      ],
-      'dependencies': [
-        # TODO(brians): fix this once there's a nice logging interface to use
-        # '<(AOS)/build/aos.gyp:logging',
       ],
     },
     {
-      'target_name': 'binheap_test',
-      'type': 'executable',
+      'target_name': 'core_lib',
+      'type': 'static_library',
       'sources': [
-        'binheap_test.cpp',
+        'core_lib.c',
       ],
       'dependencies': [
-        '<(EXTERNALS):gtest',
-        'ipc_lib',
+        'aos_sync',
+        'shared_mem',
+      ],
+      'export_dependent_settings': [
+        'aos_sync',
+      ],
+    },
+    {
+      'target_name': 'shared_mem',
+      'type': 'static_library',
+      'sources': [
+        'shared_mem.c',
+      ],
+      'dependencies': [
+        'aos_sync',
+      ],
+      'export_dependent_settings': [
+        'aos_sync',
+      ],
+    },
+    {
+      'target_name': 'queue',
+      'type': 'static_library',
+      'sources': [
+        'queue.cc',
+      ],
+      'dependencies': [
+        '<(AOS)/common/common.gyp:condition',
+        '<(AOS)/common/common.gyp:mutex',
+        'core_lib',
+        # TODO(brians): fix this once there's a nice logging interface to use
+        # '<(AOS)/build/aos.gyp:logging',
       ],
     },
     {
       'target_name': 'ipc_queue_test',
       'type': 'executable',
       'sources': [
-        'queue_test.cpp',
+        'queue_test.cc',
       ],
       'dependencies': [
         '<(EXTERNALS):gtest',
-        'ipc_lib',
+        'queue',
         '<(AOS)/build/aos.gyp:logging',
+        'core_lib',
       ],
     },
   ],
diff --git a/aos/atom_code/ipc_lib/queue.cc b/aos/atom_code/ipc_lib/queue.cc
index 57e2a5e..81d036c 100644
--- a/aos/atom_code/ipc_lib/queue.cc
+++ b/aos/atom_code/ipc_lib/queue.cc
@@ -1,4 +1,4 @@
-#include "aos/common/queue.h"
+#include "aos/atom_code/ipc_lib/queue.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -9,12 +9,13 @@
 
 #include "aos/common/logging/logging.h"
 #include "aos/common/type_traits.h"
+#include "aos/atom_code/ipc_lib/core_lib.h"
 
 namespace aos {
-
 namespace {
 
-static_assert(shm_ok<Queue>::value, "Queue instances go into shared memory");
+static_assert(shm_ok<RawQueue>::value,
+              "RawQueue instances go into shared memory");
 
 const bool kReadDebug = false;
 const bool kWriteDebug = false;
@@ -22,12 +23,19 @@
 const bool kFetchDebug = false;
 
 // The number of extra messages the pool associated with each queue will be able
-// to hold (for readers who are slow about freeing them).
+// to hold (for readers who are slow about freeing them or who leak one when
+// they get killed).
 const int kExtraMessages = 20;
 
 }  // namespace
 
-struct Queue::MessageHeader {
+const int RawQueue::kPeek;
+const int RawQueue::kFromEnd;
+const int RawQueue::kNonBlock;
+const int RawQueue::kBlock;
+const int RawQueue::kOverride;
+
+struct RawQueue::MessageHeader {
   int ref_count;
   int index;  // in pool_
   static MessageHeader *Get(const void *msg) {
@@ -42,12 +50,12 @@
     memcpy(this, &temp, sizeof(*this));
   }
 };
-static_assert(shm_ok<Queue::MessageHeader>::value, "the whole point"
+static_assert(shm_ok<RawQueue::MessageHeader>::value, "the whole point"
               " is to stick it in shared memory");
 
 // TODO(brians) maybe do this with atomic integer instructions so it doesn't
 //   have to lock/unlock pool_lock_
-void Queue::DecrementMessageReferenceCount(const void *msg) {
+void RawQueue::DecrementMessageReferenceCount(const void *msg) {
   MutexLocker locker(&pool_lock_);
   MessageHeader *header = MessageHeader::Get(msg);
   --header->ref_count;
@@ -60,7 +68,8 @@
   }
 }
 
-Queue::Queue(const char *name, size_t length, int hash, int queue_length) {
+RawQueue::RawQueue(const char *name, size_t length, int hash, int queue_length)
+  : readable_(&data_lock_), writable_(&data_lock_) {
   const size_t name_size = strlen(name) + 1;
   char *temp = static_cast<char *>(shm_malloc(name_size));
   memcpy(temp, name, name_size);
@@ -97,7 +106,7 @@
     printf("made queue %s\n", name);
   }
 }
-Queue *Queue::Fetch(const char *name, size_t length, int hash,
+RawQueue *RawQueue::Fetch(const char *name, size_t length, int hash,
                     int queue_length) {
   if (kFetchDebug) {
     printf("fetching queue %s\n", name);
@@ -105,9 +114,9 @@
   if (mutex_lock(&global_core->mem_struct->queues.alloc_lock) != 0) {
     return NULL;
   }
-  Queue *current = static_cast<Queue *>(
+  RawQueue *current = static_cast<RawQueue *>(
       global_core->mem_struct->queues.queue_list);
-  Queue *last = NULL;
+  RawQueue *last = NULL;
   while (current != NULL) {
     // if we found a matching queue
     if (strcmp(current->name_, name) == 0 && current->length_ == length &&
@@ -123,8 +132,8 @@
     current = current->next_;
   }
 
-  void *temp = shm_malloc(sizeof(Queue));
-  current = new (temp) Queue(name, length, hash, queue_length);
+  void *temp = shm_malloc(sizeof(RawQueue));
+  current = new (temp) RawQueue(name, length, hash, queue_length);
   if (last == NULL) {  // if we don't have one to tack the new one on to
     global_core->mem_struct->queues.queue_list = current;
   } else {
@@ -134,10 +143,10 @@
   mutex_unlock(&global_core->mem_struct->queues.alloc_lock);
   return current;
 }
-Queue *Queue::Fetch(const char *name, size_t length, int hash,
+RawQueue *RawQueue::Fetch(const char *name, size_t length, int hash,
                     int queue_length,
-                    int recycle_hash, int recycle_length, Queue **recycle) {
-  Queue *r = Fetch(name, length, hash, queue_length);
+                    int recycle_hash, int recycle_length, RawQueue **recycle) {
+  RawQueue *r = Fetch(name, length, hash, queue_length);
   r->recycle_ = Fetch(name, length, recycle_hash, recycle_length);
   if (r == r->recycle_) {
     fprintf(stderr, "queue: r->recycle_(=%p) == r(=%p)\n", r->recycle_, r);
@@ -148,7 +157,7 @@
   return r;
 }
 
-void Queue::DoFreeMessage(const void *msg) {
+void RawQueue::DoFreeMessage(const void *msg) {
   MessageHeader *header = MessageHeader::Get(msg);
   if (pool_[header->index] != header) {  // if something's messed up
     fprintf(stderr, "queue: something is very very wrong with queue %p."
@@ -206,13 +215,13 @@
   }
 }
 
-bool Queue::WriteMessage(void *msg, int options) {
+bool RawQueue::WriteMessage(void *msg, int options) {
   if (kWriteDebug) {
     printf("queue: %p->WriteMessage(%p, %d)\n", this, msg, options);
   }
   if (msg == NULL || msg < reinterpret_cast<void *>(global_core->mem_struct) ||
       msg > static_cast<void *>((
-              reinterpret_cast<uintptr_t>(global_core->mem_struct) +
+              reinterpret_cast<char *>(global_core->mem_struct) +
               global_core->size))) {
     fprintf(stderr, "queue: attempt to write bad message %p to %p. aborting\n",
             msg, this);
@@ -239,7 +248,7 @@
         if (kWriteDebug) {
           printf("queue: going to wait for writable_ of %p\n", this);
         }
-        writable_.Wait(&data_lock_);
+        writable_.Wait();
       }
       new_end = (data_end_ + 1) % data_length_;
     }
@@ -257,12 +266,12 @@
   return true;
 }
 
-void Queue::ReadCommonEnd(bool read) {
+void RawQueue::ReadCommonEnd(bool read) {
   if (read) {
     writable_.Signal();
   }
 }
-bool Queue::ReadCommonStart(int options, int *index) {
+bool RawQueue::ReadCommonStart(int options, int *index) {
   while (data_start_ == data_end_ || ((index != NULL) && messages_ <= *index)) {
     if (options & kNonBlock) {
       if (kReadDebug) {
@@ -287,7 +296,7 @@
   }
   return true;
 }
-void *Queue::ReadPeek(int options, int start) {
+void *RawQueue::ReadPeek(int options, int start) {
   void *ret;
   if (options & kFromEnd) {
     int pos = data_end_ - 1;
@@ -311,7 +320,7 @@
   }
   return ret;
 }
-const void *Queue::ReadMessage(int options) {
+const void *RawQueue::ReadMessage(int options) {
   if (kReadDebug) {
     printf("queue: %p->ReadMessage(%d)\n", this, options);
   }
@@ -359,7 +368,7 @@
   }
   return msg;
 }
-const void *Queue::ReadMessageIndex(int options, int *index) {
+const void *RawQueue::ReadMessageIndex(int options, int *index) {
   if (kReadDebug) {
     printf("queue: %p->ReadMessageIndex(%d, %p(*=%d))\n",
            this, options, index, *index);
@@ -421,14 +430,14 @@
   return msg;
 }
 
-void *Queue::GetMessage() {
+void *RawQueue::GetMessage() {
   MutexLocker locker(&pool_lock_);
   MessageHeader *header;
   if (pool_length_ - messages_used_ > 0) {
     header = pool_[messages_used_];
   } else {
     if (pool_length_ >= mem_length_) {
-      LOG(FATAL, "overused pool %p from queue %p\n", pool, queue);
+      LOG(FATAL, "overused pool of queue %p\n", this);
     }
     header = pool_[pool_length_] =
         static_cast<MessageHeader *>(shm_malloc(msg_length_));
diff --git a/aos/atom_code/ipc_lib/queue.h b/aos/atom_code/ipc_lib/queue.h
index f7c116b..0ab4227 100644
--- a/aos/atom_code/ipc_lib/queue.h
+++ b/aos/atom_code/ipc_lib/queue.h
@@ -1,5 +1,5 @@
-#ifndef AOS_COMMON_QUEUE_H_
-#define AOS_COMMON_QUEUE_H_
+#ifndef AOS_ATOM_CODE_IPC_LIB_QUEUE_H_
+#define AOS_ATOM_CODE_IPC_LIB_QUEUE_H_
 
 #include "aos/atom_code/ipc_lib/shared_mem.h"
 #include "aos/common/mutex.h"
@@ -26,14 +26,14 @@
 // of name and type signature will result in a different queue, which means
 // that if you only recompile some code that uses differently sized messages,
 // it will simply use a different queue than the old code.
-class Queue {
+class RawQueue {
  public:
   // Retrieves (and creates if necessary) a queue. Each combination of name and
   // signature refers to a completely independent queue.
   // length is how large each message will be
   // hash can differentiate multiple otherwise identical queues
   // queue_length is how many messages the queue will be able to hold
-  static Queue *Fetch(const char *name, size_t length, int hash,
+  static RawQueue *Fetch(const char *name, size_t length, int hash,
                       int queue_length);
   // Same as above, except sets up the returned queue so that it will put
   // messages on *recycle when they are freed (after they have been released by
@@ -47,10 +47,10 @@
   // NOTE: calling this function with the same (name,length,hash,queue_length)
   // but multiple recycle_queue_lengths will result in each freed message being
   // put onto an undefined one of the recycle queues.
-  static Queue *Fetch(const char *name, size_t length, int hash,
+  static RawQueue *Fetch(const char *name, size_t length, int hash,
                       int queue_length,
                       int recycle_hash, int recycle_queue_length,
-                      Queue **recycle);
+                      RawQueue **recycle);
 
   // Constants for passing to options arguments.
   // The non-conflicting ones can be combined with bitwise-or.
@@ -79,6 +79,7 @@
   // Writes a message into the queue.
   // This function takes ownership of msg.
   // NOTE: msg must point to a valid message from this queue
+  // Returns truen on success.
   bool WriteMessage(void *msg, int options);
 
   // Reads a message out of the queue.
@@ -105,6 +106,7 @@
   // FreeMessage.
   void *GetMessage();
 
+  // It is ok to call this with msg == NULL.
   void FreeMessage(const void *msg) { DecrementMessageReferenceCount(msg); }
 
  private:
@@ -116,9 +118,9 @@
   int hash_;
   int queue_length_;
   // The next one in the linked list of queues.
-  Queue *next_;
+  RawQueue *next_;
 
-  Queue *recycle_;
+  RawQueue *recycle_;
 
   Mutex data_lock_;  // protects operations on data_ etc
   Condition readable_;
@@ -152,9 +154,9 @@
   void *ReadPeek(int options, int start);
 
   // Gets called by Fetch when necessary (with placement new).
-  Queue(const char *name, size_t length, int hash, int queue_length);
+  RawQueue(const char *name, size_t length, int hash, int queue_length);
 };
 
 }  // namespace aos
 
-#endif  // AOS_COMMONG_QUEUE_H_
+#endif  // AOS_ATOM_CODE_IPC_LIB_QUEUE_H_
diff --git a/aos/atom_code/ipc_lib/queue_test.cc b/aos/atom_code/ipc_lib/queue_test.cc
index b437c86..276e81a 100644
--- a/aos/atom_code/ipc_lib/queue_test.cc
+++ b/aos/atom_code/ipc_lib/queue_test.cc
@@ -11,6 +11,7 @@
 #include "gtest/gtest.h"
 
 #include "aos/atom_code/ipc_lib/sharedmem_test_setup.h"
+#include "aos/atom_code/ipc_lib/core_lib.h"
 #include "aos/common/type_traits.h"
 
 using ::testing::AssertionResult;
@@ -245,7 +246,7 @@
     int16_t data; // don't really want to test empty messages
   };
   struct MessageArgs {
-    Queue *const queue;
+    RawQueue *const queue;
     int flags;
     int16_t data; // -1 means NULL expected
   };
@@ -266,13 +267,14 @@
         args->queue->ReadMessage(args->flags));
     if (msg == NULL) {
       if (args->data != -1) {
-        snprintf(failure, kFailureSize, "expected data of %"PRId16" but got NULL message",
+        snprintf(failure, kFailureSize,
+                 "expected data of %" PRId16 " but got NULL message",
                  args->data);
       }
     } else {
       if (args->data != msg->data) {
         snprintf(failure, kFailureSize,
-                 "expected data of %"PRId16" but got %"PRId16" instead",
+                 "expected data of %" PRId16 " but got %" PRId16 " instead",
                  args->data, msg->data);
       }
       args->queue->FreeMessage(msg);
@@ -283,75 +285,75 @@
 std::map<QueueTest::ChildID, QueueTest::ForkedProcess *> QueueTest::children_;
 
 TEST_F(QueueTest, Reading) {
-  Queue *const queue = Queue::Fetch("Queue", sizeof(TestMessage), 1, 1);
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 1);
   MessageArgs args{queue, 0, -1};
 
-  args.flags = Queue::kNonBlock;
+  args.flags = RawQueue::kNonBlock;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  args.flags = Queue::kNonBlock | Queue::kPeek;
+  args.flags = RawQueue::kNonBlock | RawQueue::kPeek;
   EXPECT_RETURNS(ReadTestMessage, &args);
   args.flags = 0;
   EXPECT_HANGS(ReadTestMessage, &args);
-  args.flags = Queue::kPeek;
+  args.flags = RawQueue::kPeek;
   EXPECT_HANGS(ReadTestMessage, &args);
   args.data = 254;
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_RETURNS(WriteTestMessage, &args);
-  args.flags = Queue::kPeek;
+  args.flags = RawQueue::kPeek;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  args.flags = Queue::kPeek;
+  args.flags = RawQueue::kPeek;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  args.flags = Queue::kPeek | Queue::kNonBlock;
+  args.flags = RawQueue::kPeek | RawQueue::kNonBlock;
   EXPECT_RETURNS(ReadTestMessage, &args);
   args.flags = 0;
   EXPECT_RETURNS(ReadTestMessage, &args);
   args.flags = 0;
   args.data = -1;
   EXPECT_HANGS(ReadTestMessage, &args);
-  args.flags = Queue::kNonBlock;
+  args.flags = RawQueue::kNonBlock;
   EXPECT_RETURNS(ReadTestMessage, &args);
   args.flags = 0;
   args.data = 971;
   EXPECT_RETURNS_FAILS(ReadTestMessage, &args);
 }
 TEST_F(QueueTest, Writing) {
-  Queue *const queue = Queue::Fetch("Queue", sizeof(TestMessage), 1, 1);
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 1);
   MessageArgs args{queue, 0, 973};
 
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_RETURNS(WriteTestMessage, &args);
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_HANGS(WriteTestMessage, &args);
-  args.flags = Queue::kNonBlock;
+  args.flags = RawQueue::kNonBlock;
   EXPECT_RETURNS_FAILS(WriteTestMessage, &args);
-  args.flags = Queue::kNonBlock;
+  args.flags = RawQueue::kNonBlock;
   EXPECT_RETURNS_FAILS(WriteTestMessage, &args);
-  args.flags = Queue::kPeek;
+  args.flags = RawQueue::kPeek;
   EXPECT_RETURNS(ReadTestMessage, &args);
   args.data = 971;
-  args.flags = Queue::kOverride;
+  args.flags = RawQueue::kOverride;
   EXPECT_RETURNS(WriteTestMessage, &args);
-  args.flags = Queue::kOverride;
+  args.flags = RawQueue::kOverride;
   EXPECT_RETURNS(WriteTestMessage, &args);
   args.flags = 0;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  args.flags = Queue::kNonBlock;
+  args.flags = RawQueue::kNonBlock;
   EXPECT_RETURNS(WriteTestMessage, &args);
   args.flags = 0;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  args.flags = Queue::kOverride;
+  args.flags = RawQueue::kOverride;
   EXPECT_RETURNS(WriteTestMessage, &args);
   args.flags = 0;
   EXPECT_RETURNS(ReadTestMessage, &args);
 }
 
 TEST_F(QueueTest, MultiRead) {
-  Queue *const queue = Queue::Fetch("Queue", sizeof(TestMessage), 1, 1);
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 1);
   MessageArgs args{queue, 0, 1323};
 
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_RETURNS(WriteTestMessage, &args);
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   ASSERT_TRUE(HangsFork(ReadTestMessage, &args, true, 1));
   ASSERT_TRUE(HangsFork(ReadTestMessage, &args, true, 2));
   EXPECT_TRUE(HangsCheck(1) != HangsCheck(2));
@@ -361,22 +363,22 @@
 TEST_F(QueueTest, Recycle) {
   // TODO(brians) basic test of recycle queue
   // include all of the ways a message can get into the recycle queue
-  Queue *recycle_queue = reinterpret_cast<Queue *>(23);
-  Queue *const queue = Queue::Fetch("Queue", sizeof(TestMessage), 1, 2, 2, 2,
+  RawQueue *recycle_queue = reinterpret_cast<RawQueue *>(23);
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2, 2, 2,
                                     &recycle_queue);
-  ASSERT_NE(reinterpret_cast<Queue *>(23), recycle_queue);
+  ASSERT_NE(reinterpret_cast<RawQueue *>(23), recycle_queue);
   MessageArgs args{queue, 0, 973}, recycle{recycle_queue, 0, 973};
 
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_RETURNS(WriteTestMessage, &args);
   EXPECT_HANGS(ReadTestMessage, &recycle);
   args.data = 254;
   EXPECT_RETURNS(WriteTestMessage, &args);
   EXPECT_HANGS(ReadTestMessage, &recycle);
   args.data = 971;
-  args.flags = Queue::kOverride;
+  args.flags = RawQueue::kOverride;
   EXPECT_RETURNS(WriteTestMessage, &args);
-  recycle.flags = Queue::kBlock;
+  recycle.flags = RawQueue::kBlock;
   EXPECT_RETURNS(ReadTestMessage, &recycle);
 
   EXPECT_HANGS(ReadTestMessage, &recycle);
@@ -391,11 +393,11 @@
   EXPECT_HANGS(ReadTestMessage, &recycle);
 
   args.data = 254;
-  args.flags = Queue::kPeek;
+  args.flags = RawQueue::kPeek;
   EXPECT_RETURNS(ReadTestMessage, &args);
-  recycle.flags = Queue::kBlock;
+  recycle.flags = RawQueue::kBlock;
   EXPECT_HANGS(ReadTestMessage, &recycle);
-  args.flags = Queue::kBlock;
+  args.flags = RawQueue::kBlock;
   EXPECT_RETURNS(ReadTestMessage, &args);
   recycle.data = 254;
   EXPECT_RETURNS(ReadTestMessage, &recycle);
diff --git a/aos/atom_code/ipc_lib/shared_mem.c b/aos/atom_code/ipc_lib/shared_mem.c
index cea9a67..e2c2c9e 100644
--- a/aos/atom_code/ipc_lib/shared_mem.c
+++ b/aos/atom_code/ipc_lib/shared_mem.c
@@ -1,4 +1,4 @@
-#include "shared_mem.h"
+#include "aos/atom_code/ipc_lib/shared_mem.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -8,22 +8,31 @@
 #include <sys/types.h>
 #include <errno.h>
 
+#include "aos/atom_code/ipc_lib/core_lib.h"
+
 // the path for the shared memory segment. see shm_open(3) for restrictions
 #define AOS_SHM_NAME "/aos_shared_mem"
 // Size of the shared mem segment.
 // set to the maximum number that worked
 #define SIZEOFSHMSEG (4096 * 27813)
 
+void init_shared_mem_core(aos_shm_core *shm_core) {
+  clock_gettime(CLOCK_REALTIME, &shm_core->identifier);
+  shm_core->msg_alloc_lock = 0;
+  shm_core->queues.queue_list = NULL;
+  shm_core->queues.alloc_lock = 0;
+}
+
 ptrdiff_t aos_core_get_mem_usage(void) {
   return global_core->size -
       ((ptrdiff_t)global_core->mem_struct->msg_alloc -
        (ptrdiff_t)global_core->mem_struct);
 }
 
-struct aos_core global_core_data;
 struct aos_core *global_core = NULL;
 
 int aos_core_create_shared_mem(enum aos_core_create to_create) {
+  static struct aos_core global_core_data;
   global_core = &global_core_data;
   int shm;
 before:
diff --git a/aos/atom_code/ipc_lib/shared_mem.h b/aos/atom_code/ipc_lib/shared_mem.h
index d8f2d18..c0d21ac 100644
--- a/aos/atom_code/ipc_lib/shared_mem.h
+++ b/aos/atom_code/ipc_lib/shared_mem.h
@@ -1,19 +1,40 @@
 #ifndef _SHARED_MEM_H_
 #define _SHARED_MEM_H_
 
-#include "core_lib.h"
 #include <stddef.h>
 #include <unistd.h>
+#include <time.h>
+
+#include "aos/atom_code/ipc_lib/aos_sync.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+extern struct aos_core *global_core;
+
 // Where the shared memory segment starts in each process's address space.
 // Has to be the same in all of them so that stuff in shared memory
 // can have regular pointers to other stuff in shared memory.
 #define SHM_START 0x20000000
 
+typedef struct aos_queue_global_t {
+  mutex alloc_lock;
+  void *queue_list;  // an aos::Queue* declared in C code
+} aos_queue_global;
+
+typedef struct aos_shm_core_t {
+  // clock_gettime(CLOCK_REALTIME, &identifier) gets called to identify
+  // this shared memory area
+  struct timespec identifier;
+  // gets 0-initialized at the start (as part of shared memory) and
+  // the owner sets as soon as it finishes setting stuff up
+  mutex creation_condition;
+  mutex msg_alloc_lock;
+  void *msg_alloc;
+  aos_queue_global queues;
+} aos_shm_core;
+
 enum aos_core_create {
   create,
   reference
@@ -26,6 +47,8 @@
   aos_shm_core *mem_struct;
 };
 
+void init_shared_mem_core(aos_shm_core *shm_core);
+
 ptrdiff_t aos_core_get_mem_usage(void);
 
 // Takes the specified memory address and uses it as the shared memory.