Index: libcfa/src/concurrency/io/call.cfa.in
===================================================================
--- libcfa/src/concurrency/io/call.cfa.in	(revision 7b91c0e992ed493cc46d297ec3fe313c381a8dbc)
+++ libcfa/src/concurrency/io/call.cfa.in	(revision 4f762d3f5eee513f2e464273142ed0e3e34f8c08)
@@ -54,15 +54,15 @@
 			| IOSQE_IO_DRAIN
 		#endif
+		#if defined(CFA_HAVE_IOSQE_IO_LINK)
+			| IOSQE_IO_LINK
+		#endif
+		#if defined(CFA_HAVE_IOSQE_IO_HARDLINK)
+			| IOSQE_IO_HARDLINK
+		#endif
 		#if defined(CFA_HAVE_IOSQE_ASYNC)
 			| IOSQE_ASYNC
 		#endif
-	;
-
-	static const __u32 LINK_FLAGS = 0
-		#if defined(CFA_HAVE_IOSQE_IO_LINK)
-			| IOSQE_IO_LINK
-		#endif
-		#if defined(CFA_HAVE_IOSQE_IO_HARDLINK)
-			| IOSQE_IO_HARDLINK
+		#if defined(CFA_HAVE_IOSQE_BUFFER_SELECTED)
+			| IOSQE_BUFFER_SELECTED
 		#endif
 	;
@@ -74,16 +74,6 @@
 	;
 
-	extern [* volatile struct io_uring_sqe, __u32] __submit_alloc( struct __io_data & ring, __u64 data );
-	extern void __submit( struct io_context * ctx, __u32 idx ) __attribute__((nonnull (1)));
-
-	static inline io_context * __get_io_context( void ) {
-		cluster * cltr = active_cluster();
-
-		/* paranoid */ verifyf( cltr, "No active cluster for io operation\\n");
-		assertf( cltr->io.cnt > 0, "Cluster %p has no default io contexts and no context was specified\\n", cltr );
-
-		/* paranoid */ verifyf( cltr->io.ctxs, "default io contexts for cluster %p are missing\\n", cltr);
-		return &cltr->io.ctxs[ thread_rand() % cltr->io.cnt ];
-	}
+	extern struct $io_context * cfa_io_allocate(struct io_uring_sqe * out_sqes[], __u32 out_idxs[], __u32 want)  __attribute__((nonnull (1,2)));
+	extern void cfa_io_submit( struct $io_context * in_ctx, __u32 in_idxs[], __u32 have ) __attribute__((nonnull (1,2)));
 #endif
 
@@ -195,5 +185,5 @@
 		return ', '.join(args_a)
 
-AsyncTemplate = """inline void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context) {{
+AsyncTemplate = """inline void async_{name}(io_future_t & future, {params}, int submit_flags) {{
 	#if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_{op})
 		ssize_t res = {name}({args});
@@ -205,24 +195,11 @@
 		}}
 	#else
-		// we don't support LINK yet
-		if( 0 != (submit_flags & LINK_FLAGS) ) {{
-			errno = ENOTSUP; return -1;
-		}}
-
-		if( !context ) {{
-			context = __get_io_context();
-		}}
-		if(cancellation) {{
-			cancellation->target = (__u64)(uintptr_t)&future;
-		}}
-
 		__u8 sflags = REGULAR_FLAGS & submit_flags;
-		struct __io_data & ring = *context->thrd.ring;
-
 		__u32 idx;
 		struct io_uring_sqe * sqe;
-		[(volatile struct io_uring_sqe *) sqe, idx] = __submit_alloc( ring, (__u64)(uintptr_t)&future );
+		struct $io_context * ctx = cfa_io_allocate( &sqe, &idx, 1 );
 
 		sqe->opcode = IORING_OP_{op};
+		sqe->user_data = (__u64)(uintptr_t)&future;
 		sqe->flags = sflags;
 		sqe->ioprio = 0;
@@ -239,16 +216,12 @@
 
 		verify( sqe->user_data == (__u64)(uintptr_t)&future );
-		__submit( context, idx );
+		cfa_io_submit( ctx, &idx, 1 );
 	#endif
 }}"""
 
-SyncTemplate = """{ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {{
-	if( timeout >= 0 ) {{
-		errno = ENOTSUP;
-		return -1;
-	}}
+SyncTemplate = """{ret} cfa_{name}({params}, int submit_flags) {{
 	io_future_t future;
 
-	async_{name}( future, {args}, submit_flags, cancellation, context );
+	async_{name}( future, {args}, submit_flags );
 
 	wait( future );
@@ -415,8 +388,8 @@
 	if c.define:
 		print("""#if defined({define})
-	{ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);
+	{ret} cfa_{name}({params}, int submit_flags);
 #endif""".format(define=c.define,ret=c.ret, name=c.name, params=c.params))
 	else:
-		print("{ret} cfa_{name}({params}, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context);"
+		print("{ret} cfa_{name}({params}, int submit_flags);"
 		.format(ret=c.ret, name=c.name, params=c.params))
 
@@ -426,8 +399,8 @@
 	if c.define:
 		print("""#if defined({define})
-	void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context);
+	void async_{name}(io_future_t & future, {params}, int submit_flags);
 #endif""".format(define=c.define,name=c.name, params=c.params))
 	else:
-		print("void async_{name}(io_future_t & future, {params}, int submit_flags, io_cancellation * cancellation, io_context * context);"
+		print("void async_{name}(io_future_t & future, {params}, int submit_flags);"
 		.format(name=c.name, params=c.params))
 print("\n")
@@ -474,37 +447,4 @@
 
 print("""
-//-----------------------------------------------------------------------------
-bool cancel(io_cancellation & this) {
-	#if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_ASYNC_CANCEL)
-		return false;
-	#else
-		io_future_t future;
-
-		io_context * context = __get_io_context();
-
-		__u8 sflags = 0;
-		struct __io_data & ring = *context->thrd.ring;
-
-		__u32 idx;
-		volatile struct io_uring_sqe * sqe;
-		[sqe, idx] = __submit_alloc( ring, (__u64)(uintptr_t)&future );
-
-		sqe->__pad2[0] = sqe->__pad2[1] = sqe->__pad2[2] = 0;
-		sqe->opcode = IORING_OP_ASYNC_CANCEL;
-		sqe->flags = sflags;
-		sqe->addr = this.target;
-
-		verify( sqe->user_data == (__u64)(uintptr_t)&future );
-		__submit( context, idx );
-
-		wait(future);
-
-		if( future.result == 0 ) return true; // Entry found
-		if( future.result == -EALREADY) return true; // Entry found but in progress
-		if( future.result == -ENOENT ) return false; // Entry not found
-		return false;
-	#endif
-}
-
 //-----------------------------------------------------------------------------
 // Check if a function is has asynchronous
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision 7b91c0e992ed493cc46d297ec3fe313c381a8dbc)
+++ libcfa/src/concurrency/io/setup.cfa	(revision 4f762d3f5eee513f2e464273142ed0e3e34f8c08)
@@ -36,12 +36,9 @@
 	void ?{}(io_context_params & this) {}
 
-	void ?{}(io_context & this, struct cluster & cl) {}
-	void ?{}(io_context & this, struct cluster & cl, const io_context_params & params) {}
-
-	void ^?{}(io_context & this) {}
-	void ^?{}(io_context & this, bool cluster_context) {}
-
-	void register_fixed_files( io_context &, int *, unsigned ) {}
-	void register_fixed_files( cluster    &, int *, unsigned ) {}
+	void  ?{}($io_context & this, struct cluster & cl) {}
+	void ^?{}($io_context & this) {}
+
+	$io_arbiter * create(void) { return 0p; }
+	void destroy($io_arbiter *) {}
 
 #else
@@ -68,10 +65,4 @@
 	void ?{}(io_context_params & this) {
 		this.num_entries = 256;
-		this.num_ready = 256;
-		this.submit_aff = -1;
-		this.eager_submits = false;
-		this.poller_submits = false;
-		this.poll_submit = false;
-		this.poll_complete = false;
 	}
 
@@ -194,7 +185,7 @@
 
 			for(i; nfds) {
-				$io_ctx_thread * io_ctx = ($io_ctx_thread *)(uintptr_t)events[i].data.u64;
+				$io_context * io_ctx = ($io_context *)(uintptr_t)events[i].data.u64;
 				/* paranoid */ verify( io_ctx );
-				__cfadbg_print_safe(io_core, "Kernel I/O - epoll : Unparking io poller %d (%p)\n", io_ctx->ring->fd, io_ctx);
+				__cfadbg_print_safe(io_core, "Kernel I/O - epoll : Unparking io poller %d (%p)\n", io_ctx->fd, io_ctx);
 				#if !defined( __CFA_NO_STATISTICS__ )
 					__cfaabi_tls.this_stats = io_ctx->self.curr_cluster->stats;
@@ -202,5 +193,5 @@
 
 				eventfd_t v;
-				eventfd_read(io_ctx->ring->efd, &v);
+				eventfd_read(io_ctx->efd, &v);
 
 				post( io_ctx->sem );
@@ -219,109 +210,51 @@
 //=============================================================================================
 
-	void ?{}($io_ctx_thread & this, struct cluster & cl) { (this.self){ "IO Poller", cl }; }
-	void main( $io_ctx_thread & this );
-	static inline $thread * get_thread( $io_ctx_thread & this ) { return &this.self; }
-	void ^?{}( $io_ctx_thread & mutex this ) {}
-
-	static void __io_create ( __io_data & this, const io_context_params & params_in );
-	static void __io_destroy( __io_data & this );
-
-	void ?{}(io_context & this, struct cluster & cl, const io_context_params & params) {
-		(this.thrd){ cl };
-		this.thrd.ring = malloc();
-		__cfadbg_print_safe(io_core, "Kernel I/O : Creating ring for io_context %p\n", &this);
-		__io_create( *this.thrd.ring, params );
-
-		__cfadbg_print_safe(io_core, "Kernel I/O : Starting poller thread for io_context %p\n", &this);
-		this.thrd.done = false;
-		__thrd_start( this.thrd, main );
-
-		__cfadbg_print_safe(io_core, "Kernel I/O : io_context %p ready\n", &this);
+	static void __io_uring_setup ( $io_context & this, const io_context_params & params_in );
+	static void __io_uring_teardown( $io_context & this );
+	static void __epoll_register($io_context & ctx);
+	static void __epoll_unregister($io_context & ctx);
+	void __ioarbiter_register( $io_arbiter & mutex, $io_context & ctx );
+	void __ioarbiter_unregister( $io_arbiter & mutex, $io_context & ctx );
+
+	void ?{}($io_context & this, struct cluster & cl) {
+		(this.self){ "IO Poller", cl };
+		this.ext_sq.empty = true;
+		__io_uring_setup( this, cl.io.params );
+		__cfadbg_print_safe(io_core, "Kernel I/O : Created ring for io_context %u (%p)\n", this.fd, &this);
+
+		__epoll_register(this);
+
+		__ioarbiter_register(*cl.io.arbiter, this);
+
+		__thrd_start( this, main );
+		__cfadbg_print_safe(io_core, "Kernel I/O : Started poller thread for io_context %u\n", this.fd);
+	}
+
+	void ^?{}($io_context & mutex this) {
+		__cfadbg_print_safe(io_core, "Kernel I/O : tearing down io_context %u\n", this.fd);
+
+		^(this.self){};
+		__cfadbg_print_safe(io_core, "Kernel I/O : Stopped poller thread for io_context %u\n", this.fd);
+
+		__ioarbiter_unregister(*this.arbiter, this);
+
+		__epoll_unregister(this);
+
+		__io_uring_teardown( this );
+		__cfadbg_print_safe(io_core, "Kernel I/O : Destroyed ring for io_context %u\n", this.fd);
 	}
 
 	void ?{}(io_context & this, struct cluster & cl) {
-		io_context_params params;
-		(this){ cl, params };
-	}
-
-	void ^?{}(io_context & this, bool cluster_context) {
-		__cfadbg_print_safe(io_core, "Kernel I/O : tearing down io_context %p\n", &this);
-
-		// Notify the thread of the shutdown
-		__atomic_store_n(&this.thrd.done, true, __ATOMIC_SEQ_CST);
-
-		// If this is an io_context within a cluster, things get trickier
-		$thread & thrd = this.thrd.self;
-		if( cluster_context ) {
-			// We are about to do weird things with the threads
-			// we don't need interrupts to complicate everything
-			disable_interrupts();
-
-			// Get cluster info
-			cluster & cltr = *thrd.curr_cluster;
-			/* paranoid */ verify( cltr.idles.total == 0 || &cltr == mainCluster );
-			/* paranoid */ verify( !ready_mutate_islocked() );
-
-			// We need to adjust the clean-up based on where the thread is
-			if( thrd.state == Ready || thrd.preempted != __NO_PREEMPTION ) {
-				// This is the tricky case
-				// The thread was preempted or ready to run and now it is on the ready queue
-				// but the cluster is shutting down, so there aren't any processors to run the ready queue
-				// the solution is to steal the thread from the ready-queue and pretend it was blocked all along
-
-				ready_schedule_lock();
-					// The thread should on the list
-					/* paranoid */ verify( thrd.link.next != 0p );
-
-					// Remove the thread from the ready queue of this cluster
-					// The thread should be the last on the list
-					__attribute__((unused)) bool removed = remove_head( &cltr, &thrd );
-					/* paranoid */ verify( removed );
-					thrd.link.next = 0p;
-					thrd.link.prev = 0p;
-
-					// Fixup the thread state
-					thrd.state = Blocked;
-					thrd.ticket = TICKET_BLOCKED;
-					thrd.preempted = __NO_PREEMPTION;
-
-				ready_schedule_unlock();
-
-				// Pretend like the thread was blocked all along
-			}
-			// !!! This is not an else if !!!
-			// Ok, now the thread is blocked (whether we cheated to get here or not)
-			if( thrd.state == Blocked ) {
-				// This is the "easy case"
-				// The thread is parked and can easily be moved to active cluster
-				verify( thrd.curr_cluster != active_cluster() || thrd.curr_cluster == mainCluster );
-				thrd.curr_cluster = active_cluster();
-
-				// unpark the fast io_poller
-				unpark( &thrd );
-			}
-			else {
-				// The thread is in a weird state
-				// I don't know what to do here
-				abort("io_context poller thread is in unexpected state, cannot clean-up correctly\n");
-			}
-
-			// The weird thread kidnapping stuff is over, restore interrupts.
-			enable_interrupts( __cfaabi_dbg_ctx );
-		} else {
-			post( this.thrd.sem );
-		}
-
-		^(this.thrd){};
-		__cfadbg_print_safe(io_core, "Kernel I/O : Stopped poller thread for io_context %p\n", &this);
-
-		__io_destroy( *this.thrd.ring );
-		__cfadbg_print_safe(io_core, "Kernel I/O : Destroyed ring for io_context %p\n", &this);
-
-		free(this.thrd.ring);
+		// this.ctx = new(cl);
+		this.ctx = alloc();
+		(*this.ctx){ cl };
+
+		__cfadbg_print_safe(io_core, "Kernel I/O : io_context %u ready\n", this.ctx->fd);
 	}
 
 	void ^?{}(io_context & this) {
-		^(this){ false };
+		post( this.ctx->sem );
+
+		delete(this.ctx);
 	}
 
@@ -329,10 +262,10 @@
 	extern void __enable_interrupts_hard();
 
-	static void __io_create( __io_data & this, const io_context_params & params_in ) {
+	static void __io_uring_setup( $io_context & this, const io_context_params & params_in ) {
 		// Step 1 : call to setup
 		struct io_uring_params params;
 		memset(&params, 0, sizeof(params));
-		if( params_in.poll_submit   ) params.flags |= IORING_SETUP_SQPOLL;
-		if( params_in.poll_complete ) params.flags |= IORING_SETUP_IOPOLL;
+		// if( params_in.poll_submit   ) params.flags |= IORING_SETUP_SQPOLL;
+		// if( params_in.poll_complete ) params.flags |= IORING_SETUP_IOPOLL;
 
 		__u32 nentries = params_in.num_entries != 0 ? params_in.num_entries : 256;
@@ -340,7 +273,4 @@
 			abort("ERROR: I/O setup 'num_entries' must be a power of 2\n");
 		}
-		if( params_in.poller_submits && params_in.eager_submits ) {
-			abort("ERROR: I/O setup 'poller_submits' and 'eager_submits' cannot be used together\n");
-		}
 
 		int fd = syscall(__NR_io_uring_setup, nentries, &params );
@@ -350,7 +280,6 @@
 
 		// Step 2 : mmap result
-		memset( &this, 0, sizeof(struct __io_data) );
-		struct __submition_data  & sq = this.submit_q;
-		struct __completion_data & cq = this.completion_q;
+		struct __sub_ring_t & sq = this.sq;
+		struct __cmp_ring_t & cq = this.cq;
 
 		// calculate the right ring size
@@ -401,37 +330,23 @@
 		// Get the pointers from the kernel to fill the structure
 		// submit queue
-		sq.head    = (volatile __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.head);
-		sq.tail    = (volatile __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.tail);
-		sq.mask    = (   const __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.ring_mask);
-		sq.num     = (   const __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.ring_entries);
-		sq.flags   = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.flags);
-		sq.dropped = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.dropped);
-		sq.array   = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
-		sq.prev_head = *sq.head;
-
-		{
-			const __u32 num = *sq.num;
-			for( i; num ) {
-				__sqe_clean( &sq.sqes[i] );
-			}
-		}
-
-		(sq.submit_lock){};
-		(sq.release_lock){};
-
-		if( params_in.poller_submits || params_in.eager_submits ) {
-			/* paranoid */ verify( is_pow2( params_in.num_ready ) || (params_in.num_ready < 8) );
-			sq.ready_cnt = max( params_in.num_ready, 8 );
-			sq.ready = alloc( sq.ready_cnt, 64`align );
-			for(i; sq.ready_cnt) {
-				sq.ready[i] = -1ul32;
-			}
-			sq.prev_ready = 0;
-		}
-		else {
-			sq.ready_cnt = 0;
-			sq.ready = 0p;
-			sq.prev_ready = 0;
-		}
+		sq.kring.head  = (volatile __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.head);
+		sq.kring.tail  = (volatile __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.tail);
+		sq.kring.array = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
+		sq.mask        = (   const __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.ring_mask);
+		sq.num         = (   const __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.ring_entries);
+		sq.flags       = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.flags);
+		sq.dropped     = (         __u32 *)(((intptr_t)sq.ring_ptr) + params.sq_off.dropped);
+
+		sq.kring.ready = 0;
+		sq.kring.released = 0;
+
+		sq.free_ring.head = 0;
+		sq.free_ring.tail = *sq.num;
+		sq.free_ring.array = alloc( *sq.num, 128`align );
+		for(i; (__u32)*sq.num) {
+			sq.free_ring.array[i] = i;
+		}
+
+		sq.to_submit = 0;
 
 		// completion queue
@@ -468,19 +383,17 @@
 		/* paranoid */ verifyf( (*sq.mask) == ((*sq.num) - 1ul32), "IO_URING Expected mask to be %u (%u entries), was %u", (*sq.num) - 1ul32, *sq.num, *sq.mask );
 		/* paranoid */ verifyf( (*sq.num) >= nentries, "IO_URING Expected %u entries, got %u", nentries, *sq.num );
-		/* paranoid */ verifyf( (*sq.head) == 0, "IO_URING Expected head to be 0, got %u", *sq.head );
-		/* paranoid */ verifyf( (*sq.tail) == 0, "IO_URING Expected tail to be 0, got %u", *sq.tail );
+		/* paranoid */ verifyf( (*sq.kring.head) == 0, "IO_URING Expected head to be 0, got %u", *sq.kring.head );
+		/* paranoid */ verifyf( (*sq.kring.tail) == 0, "IO_URING Expected tail to be 0, got %u", *sq.kring.tail );
 
 		// Update the global ring info
-		this.ring_flags = params.flags;
+		this.ring_flags = 0;
 		this.fd         = fd;
 		this.efd        = efd;
-		this.eager_submits  = params_in.eager_submits;
-		this.poller_submits = params_in.poller_submits;
-	}
-
-	static void __io_destroy( __io_data & this ) {
+	}
+
+	static void __io_uring_teardown( $io_context & this ) {
 		// Shutdown the io rings
-		struct __submition_data  & sq = this.submit_q;
-		struct __completion_data & cq = this.completion_q;
+		struct __sub_ring_t & sq = this.sq;
+		struct __cmp_ring_t & cq = this.cq;
 
 		// unmap the submit queue entries
@@ -499,5 +412,5 @@
 		close(this.efd);
 
-		free( this.submit_q.ready ); // Maybe null, doesn't matter
+		free( this.sq.free_ring.array ); // Maybe null, doesn't matter
 	}
 
@@ -505,9 +418,9 @@
 // I/O Context Sleep
 //=============================================================================================
-	static inline void __ioctx_epoll_ctl($io_ctx_thread & ctx, int op, const char * error) {
+	static inline void __epoll_ctl($io_context & ctx, int op, const char * error) {
 		struct epoll_event ev;
 		ev.events = EPOLLIN | EPOLLONESHOT;
 		ev.data.u64 = (__u64)&ctx;
-		int ret = epoll_ctl(iopoll.epollfd, op, ctx.ring->efd, &ev);
+		int ret = epoll_ctl(iopoll.epollfd, op, ctx.efd, &ev);
 		if (ret < 0) {
 			abort( "KERNEL ERROR: EPOLL %s - (%d) %s\n", error, (int)errno, strerror(errno) );
@@ -515,19 +428,14 @@
 	}
 
-	void __ioctx_register($io_ctx_thread & ctx) {
-		__ioctx_epoll_ctl(ctx, EPOLL_CTL_ADD, "ADD");
-	}
-
-	void __ioctx_prepare_block($io_ctx_thread & ctx) {
-		__cfadbg_print_safe(io_core, "Kernel I/O - epoll : Re-arming io poller %d (%p)\n", ctx.ring->fd, &ctx);
-		__ioctx_epoll_ctl(ctx, EPOLL_CTL_MOD, "REARM");
-	}
-
-	void __ioctx_unregister($io_ctx_thread & ctx) {
+	static void __epoll_register($io_context & ctx) {
+		__epoll_ctl(ctx, EPOLL_CTL_ADD, "ADD");
+	}
+
+	static void __epoll_unregister($io_context & ctx) {
 		// Read the current epoch so we know when to stop
 		size_t curr = __atomic_load_n(&iopoll.epoch, __ATOMIC_SEQ_CST);
 
 		// Remove the fd from the iopoller
-		__ioctx_epoll_ctl(ctx, EPOLL_CTL_DEL, "REMOVE");
+		__epoll_ctl(ctx, EPOLL_CTL_DEL, "REMOVE");
 
 		// Notify the io poller thread of the shutdown
@@ -543,20 +451,33 @@
 	}
 
+	void __ioctx_prepare_block($io_context & ctx) {
+		__cfadbg_print_safe(io_core, "Kernel I/O - epoll : Re-arming io poller %d (%p)\n", ctx.fd, &ctx);
+		__epoll_ctl(ctx, EPOLL_CTL_MOD, "REARM");
+	}
+
+
 //=============================================================================================
 // I/O Context Misc Setup
 //=============================================================================================
-	void register_fixed_files( io_context & ctx, int * files, unsigned count ) {
-		int ret = syscall( __NR_io_uring_register, ctx.thrd.ring->fd, IORING_REGISTER_FILES, files, count );
-		if( ret < 0 ) {
-			abort( "KERNEL ERROR: IO_URING REGISTER - (%d) %s\n", (int)errno, strerror(errno) );
-		}
-
-		__cfadbg_print_safe( io_core, "Kernel I/O : Performed io_register for %p, returned %d\n", active_thread(), ret );
-	}
-
-	void register_fixed_files( cluster & cltr, int * files, unsigned count ) {
-		for(i; cltr.io.cnt) {
-			register_fixed_files( cltr.io.ctxs[i], files, count );
-		}
-	}
+	void ?{}( $io_arbiter & this ) {
+		this.pending.flag = false;
+	}
+
+	void ^?{}( $io_arbiter & mutex this ) {
+		/* paranoid */ verify( empty(this.assigned) );
+		/* paranoid */ verify( empty(this.available) );
+		/* paranoid */ verify( is_empty(this.pending.blocked) );
+	}
+
+	$io_arbiter * create(void) {
+		return new();
+	}
+	void destroy($io_arbiter * arbiter) {
+		delete(arbiter);
+	}
+
+//=============================================================================================
+// I/O Context Misc Setup
+//=============================================================================================
+
 #endif
Index: libcfa/src/concurrency/io/types.hfa
===================================================================
--- libcfa/src/concurrency/io/types.hfa	(revision 7b91c0e992ed493cc46d297ec3fe313c381a8dbc)
+++ libcfa/src/concurrency/io/types.hfa	(revision 4f762d3f5eee513f2e464273142ed0e3e34f8c08)
@@ -25,22 +25,35 @@
 
 #if defined(CFA_HAVE_LINUX_IO_URING_H)
-	#define LEADER_LOCK
-	struct __leaderlock_t {
-		struct $thread * volatile value;	// ($thread) next_leader | (bool:1) is_locked
-	};
+	#include "bits/sequence.hfa"
+	#include "monitor.hfa"
 
-	static inline void ?{}( __leaderlock_t & this ) { this.value = 0p; }
+	struct processor;
+	monitor $io_arbiter;
 
 	//-----------------------------------------------------------------------
 	// Ring Data structure
-      struct __submition_data {
-		// Head and tail of the ring (associated with array)
-		volatile __u32 * head;
-		volatile __u32 * tail;
-		volatile __u32 prev_head;
+      struct __sub_ring_t {
+		struct {
+			// Head and tail of the ring (associated with array)
+			volatile __u32 * head;	 // one passed last index consumed by the kernel
+			volatile __u32 * tail;   // one passed last index visible to the kernel
+			volatile __u32 ready;    // one passed last index added to array ()
+			volatile __u32 released; // one passed last index released back to the free list
 
-		// The actual kernel ring which uses head/tail
-		// indexes into the sqes arrays
-		__u32 * array;
+			// The actual kernel ring which uses head/tail
+			// indexes into the sqes arrays
+			__u32 * array;
+		} kring;
+
+		struct {
+			volatile __u32 head;
+			volatile __u32 tail;
+			// The ring which contains free allocations
+			// indexes into the sqes arrays
+			__u32 * array;
+		} free_ring;
+
+		// number of sqes to submit on next system call.
+		__u32 to_submit;
 
 		// number of entries and mask to go with it
@@ -48,24 +61,13 @@
 		const __u32 * mask;
 
-		// Submission flags (Not sure what for)
+		// Submission flags, currently only IORING_SETUP_SQPOLL
 		__u32 * flags;
 
-		// number of sqes not submitted (whatever that means)
+		// number of sqes not submitted
+		// From documentation : [dropped] is incremented for each invalid submission queue entry encountered in the ring buffer.
 		__u32 * dropped;
 
-		// Like head/tail but not seen by the kernel
-		volatile __u32 * ready;
-		__u32 ready_cnt;
-		__u32 prev_ready;
-
-		#if defined(LEADER_LOCK)
-			__leaderlock_t submit_lock;
-		#else
-			__spinlock_t submit_lock;
-		#endif
-		__spinlock_t  release_lock;
-
 		// A buffer of sqes (not the actual ring)
-		volatile struct io_uring_sqe * sqes;
+		struct io_uring_sqe * sqes;
 
 		// The location and size of the mmaped area
@@ -74,5 +76,5 @@
 	};
 
-	struct __completion_data {
+	struct __cmp_ring_t {
 		// Head and tail of the ring
 		volatile __u32 * head;
@@ -83,5 +85,5 @@
 		const __u32 * num;
 
-		// number of cqes not submitted (whatever that means)
+		// I don't know what this value is for
 		__u32 * overflow;
 
@@ -94,12 +96,44 @@
 	};
 
-	struct __io_data {
-		struct __submition_data submit_q;
-		struct __completion_data completion_q;
+	struct __attribute__((aligned(128))) $io_context {
+		inline Seqable;
+
+		volatile bool revoked;
+		processor * proc;
+
+		$io_arbiter * arbiter;
+
+		struct {
+			volatile bool empty;
+			condition blocked;
+		} ext_sq;
+
+		struct __sub_ring_t sq;
+		struct __cmp_ring_t cq;
 		__u32 ring_flags;
 		int fd;
 		int efd;
-		bool eager_submits:1;
-		bool poller_submits:1;
+
+		single_sem sem;
+		$thread self;
+	};
+
+	void main( $io_context & this );
+	static inline $thread  * get_thread ( $io_context & this ) __attribute__((const)) { return &this.self; }
+	static inline $monitor * get_monitor( $io_context & this ) __attribute__((const)) { return &this.self.self_mon; }
+	static inline $io_context *& Back( $io_context * n ) { return ($io_context *)Back( (Seqable *)n ); }
+	static inline $io_context *& Next( $io_context * n ) { return ($io_context *)Next( (Colable *)n ); }
+	void ^?{}( $io_context & mutex this );
+
+	monitor __attribute__((aligned(128))) $io_arbiter {
+		struct {
+			condition blocked;
+			$io_context * ctx;
+			volatile bool flag;
+		} pending;
+
+		Sequence($io_context) assigned;
+
+		Sequence($io_context) available;
 	};
 
@@ -133,9 +167,5 @@
 	#endif
 
-	struct $io_ctx_thread;
-	void __ioctx_register($io_ctx_thread & ctx);
-	void __ioctx_unregister($io_ctx_thread & ctx);
-	void __ioctx_prepare_block($io_ctx_thread & ctx);
-	void __sqe_clean( volatile struct io_uring_sqe * sqe );
+	void __ioctx_prepare_block($io_context & ctx);
 #endif
 
