Index: kernel/generic/include/adt/cht.h
===================================================================
--- kernel/generic/include/adt/cht.h	(revision 669f3d321e8829b7e31263be9622012f870d9539)
+++ kernel/generic/include/adt/cht.h	(revision c28413a9016657d3ac6987b6caf3bccd6680c48d)
@@ -132,6 +132,7 @@
 #define cht_read_unlock()   rcu_read_unlock()
 
+extern bool cht_create_simple(cht_t *h, cht_ops_t *op);
 extern bool cht_create(cht_t *h, size_t init_size, size_t min_size, 
-	size_t max_load, cht_ops_t *op);
+	size_t max_load, bool can_block, cht_ops_t *op);
 extern void cht_destroy(cht_t *h);
 
Index: kernel/generic/src/adt/cht.c
===================================================================
--- kernel/generic/src/adt/cht.c	(revision 669f3d321e8829b7e31263be9622012f870d9539)
+++ kernel/generic/src/adt/cht.c	(revision c28413a9016657d3ac6987b6caf3bccd6680c48d)
@@ -408,5 +408,6 @@
 
 static size_t size_to_order(size_t bucket_cnt, size_t min_order);
-static cht_buckets_t *alloc_buckets(size_t order, bool set_invalid);
+static cht_buckets_t *alloc_buckets(size_t order, bool set_invalid, 
+	bool can_block);
 static inline cht_link_t *find_lazy(cht_t *h, void *key);
 static cht_link_t *search_bucket(cht_t *h, marked_ptr_t head, void *key, 
@@ -478,4 +479,20 @@
 static void cas_order_barrier(void);
 
+static void dummy_remove_callback(cht_link_t *item)
+{
+	/* empty */
+}
+
+/** Creates a concurrent hash table.
+ * 
+ * @param h         Valid pointer to a cht_t instance.
+ * @param op        Item specific operations. All operations are compulsory.
+ * @return True if successfully created the table. False otherwise.
+ */
+bool cht_create_simple(cht_t *h, cht_ops_t *op)
+{
+	return cht_create(h, 0, 0, 0, false, op); 
+}
+
 /** Creates a concurrent hash table.
  * 
@@ -490,9 +507,13 @@
  * @param max_load  Maximum average number of items per bucket that allowed
  *                  before the table grows.
+ * @param can_block If true creating the table blocks until enough memory
+ *                  is available (possibly indefinitely). Otherwise, 
+ *                  table creation does not block and returns immediately
+ *                  even if not enough memory is available. 
  * @param op        Item specific operations. All operations are compulsory.
  * @return True if successfully created the table. False otherwise.
  */
 bool cht_create(cht_t *h, size_t init_size, size_t min_size, size_t max_load, 
-	cht_ops_t *op)
+	bool can_block, cht_ops_t *op)
 {
 	ASSERT(h);
@@ -509,5 +530,5 @@
 	size_t order = size_to_order(init_size, min_order);
 	
-	h->b = alloc_buckets(order, false);
+	h->b = alloc_buckets(order, false, can_block);
 	
 	if (!h->b)
@@ -520,4 +541,9 @@
 	atomic_set(&h->item_cnt, 0);
 	atomic_set(&h->resize_reqs, 0);
+	
+	if (NULL == op->remove_callback) {
+		h->op->remove_callback = dummy_remove_callback;
+	}
+	
 	/* 
 	 * Cached item hashes are stored in item->rcu_link.func. Once the item
@@ -539,12 +565,15 @@
  * @param set_invalid Bucket heads are marked invalid if true; otherwise
  *                    they are marked N_NORMAL.
+ * @param can_block   If true memory allocation blocks until enough memory
+ *                    is available (possibly indefinitely). Otherwise, 
+ *                    memory allocation does not block. 
  * @return Newly allocated and initialized buckets or NULL if not enough memory.
  */
-static cht_buckets_t *alloc_buckets(size_t order, bool set_invalid)
+static cht_buckets_t *alloc_buckets(size_t order, bool set_invalid, bool can_block)
 {
 	size_t bucket_cnt = (1 << order);
 	size_t bytes = 
 		sizeof(cht_buckets_t) + (bucket_cnt - 1) * sizeof(marked_ptr_t);
-	cht_buckets_t *b = malloc(bytes, FRAME_ATOMIC);
+	cht_buckets_t *b = malloc(bytes, can_block ? 0 : FRAME_ATOMIC);
 	
 	if (!b)
@@ -2145,5 +2174,5 @@
 		return;
 	
-	h->new_b = alloc_buckets(h->b->order + 1, true);
+	h->new_b = alloc_buckets(h->b->order + 1, true, false);
 
 	/* Failed to alloc a new table - try next time the resizer is run. */
@@ -2231,5 +2260,5 @@
 		return;
 	
-	h->new_b = alloc_buckets(h->b->order - 1, true);
+	h->new_b = alloc_buckets(h->b->order - 1, true, false);
 
 	/* Failed to alloc a new table - try next time the resizer is run. */
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision 669f3d321e8829b7e31263be9622012f870d9539)
+++ kernel/generic/src/synch/futex.c	(revision c28413a9016657d3ac6987b6caf3bccd6680c48d)
@@ -133,7 +133,5 @@
 	task->futexes = malloc(sizeof(struct futex_cache), 0);
 	
-	/* todo: make it block until mem is available */
-	bool ret = cht_create(&task->futexes->ht, 0, 0, 0, &task_futex_ht_ops);
-	ASSERT(ret);
+	cht_create(&task->futexes->ht, 0, 0, 0, true, &task_futex_ht_ops);
 }
 
Index: kernel/test/cht/cht1.c
===================================================================
--- kernel/test/cht/cht1.c	(revision 669f3d321e8829b7e31263be9622012f870d9539)
+++ kernel/test/cht/cht1.c	(revision c28413a9016657d3ac6987b6caf3bccd6680c48d)
@@ -237,5 +237,5 @@
 {
 	cht_t h;
-	if (!cht_create(&h, 5, 0, 0, &val_ops))
+	if (!cht_create_simple(&h, &val_ops))
 		return "Could not create the table.";
 	
@@ -453,5 +453,5 @@
 	cht_t h;
 	
-	if (!cht_create(&h, 0, 0, 0, &stress_ops)) {
+	if (!cht_create_simple(&h, &stress_ops)) {
 		TPRINTF("Failed to create the table\n");
 		return false;
