Index: init/init.c
===================================================================
--- init/init.c	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ init/init.c	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -275,5 +275,5 @@
 	version_print();
 
-/*	test_printf(); */
+//	test_printf();
 //	test_ping();
 //	test_async_ipc();
@@ -289,12 +289,12 @@
 		printf("Futex failed.\n");
 
-	if ((tid = thread_create(utest, NULL, "utest") != -1)) {
+	if (futex_down(&ftx) < 0)
+		printf("Futex failed.\n");
+
+	if ((tid = thread_create(utest, NULL, "utest")) != -1) {
 		printf("Created thread tid=%d\n", tid);
 	}
 
-	if (futex_down(&ftx) < 0)
-		printf("Futex failed.\n");
-
-	if ((tid = thread_create(utest, NULL, "utest") != -1)) {
+	if ((tid = thread_create(utest, NULL, "utest")) != -1) {
 		printf("Created thread tid=%d\n", tid);
 	}
@@ -302,5 +302,5 @@
 	int i;
 	
-	for (i = 0; i < 10000000; i++)
+	for (i = 0; i < 50000000; i++)
 		;
 		
@@ -309,7 +309,7 @@
 
 	ptid = psthread_create(ptest, NULL);
-	printf("Main thread-1\n");
-	ps_preempt();
-	printf("Main thread-2\n");
+	printf("main thread-1\n");
+	ps_preempt();
+	printf("main thread-2\n");
 	ps_preempt();
 	printf("main thread-3\n");
Index: libc/arch/amd64/Makefile.inc
===================================================================
--- libc/arch/amd64/Makefile.inc	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/arch/amd64/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
Index: libc/arch/ia32/Makefile.inc
===================================================================
--- libc/arch/ia32/Makefile.inc	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/arch/ia32/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
Index: libc/arch/ia64/Makefile.inc
===================================================================
--- libc/arch/ia64/Makefile.inc	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/arch/ia64/Makefile.inc	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -36,3 +36,4 @@
 AFLAGS += 
 
-ARCH_SOURCES += arch/$(ARCH)/src/syscall.S
+ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
+		arch/$(ARCH)/src/psthread.S
Index: libc/arch/ia64/include/psthread.h
===================================================================
--- libc/arch/ia64/include/psthread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/include/psthread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LIBC__ia64PSTHREAD_H__
+#define __LIBC__ia64PSTHREAD_H__
+
+#include <types.h>
+#include <align.h>
+#include <libarch/stack.h>
+
+/*
+ * context_save() and context_restore() are both leaf procedures.
+ * No need to allocate scratch area.
+ */
+#define SP_DELTA	(0+ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+#define PFM_MASK        (~0x3fffffffff)
+
+#ifdef context_set
+#undef context_set
+#endif
+
+#define context_set(c, _pc, stack, size, tls) 								\
+	do {												\
+		(c)->pc = (uint64_t) _pc;								\
+		(c)->bsp = (uint64_t) stack;								\
+		(c)->ar_pfs &= PFM_MASK; 								\
+		(c)->sp = ((uint64_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - SP_DELTA;		\
+		(c)->tp = (uint64_t) tls;								\
+	} while (0);
+	
+
+/*
+ * Only save registers that must be preserved across
+ * function calls.
+ */
+typedef struct context {
+
+	/*
+	 * Application registers
+	 */
+	uint64_t ar_pfs;
+	uint64_t ar_unat_caller;
+	uint64_t ar_unat_callee;
+	uint64_t ar_rsc;
+	uint64_t bsp;		/* ar_bsp */
+	uint64_t ar_rnat;
+	uint64_t ar_lc;
+
+	/*
+	 * General registers
+	 */
+	uint64_t r1;
+	uint64_t r4;
+	uint64_t r5;
+	uint64_t r6;
+	uint64_t r7;
+	uint64_t sp;		/* r12 */
+	uint64_t tp;		/* r13 */
+	
+	/*
+	 * Branch registers
+	 */
+	uint64_t pc;		/* b0 */
+	uint64_t b1;
+	uint64_t b2;
+	uint64_t b3;
+	uint64_t b4;
+	uint64_t b5;
+
+	/*
+	 * Predicate registers
+	 */
+	uint64_t pr;
+} context_t;
+
+#endif
Index: libc/arch/ia64/include/stack.h
===================================================================
--- libc/arch/ia64/include/stack.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/include/stack.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ia64_STACK_H__
+#define __ia64_STACK_H__
+
+#define STACK_ITEM_SIZE			8
+#define STACK_ALIGNMENT			16
+#define STACK_SCRATCH_AREA_SIZE		16
+#define REGISTER_STACK_ALIGNMENT 	8
+
+#endif
Index: libc/arch/ia64/include/thread.h
===================================================================
--- libc/arch/ia64/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/include/thread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LIBC__ia64THREAD_H__
+#define __LIBC__ia64THREAD_H__
+
+static inline void __tls_set(void *tls)
+{
+	__asm__ volatile ("mov r13 = %0\n" : : "r" (tls) : "r13");
+}
+
+static inline void *__tls_get(void)
+{
+	void *retval;
+
+	__asm__ volatile ("mov %0 = r13\n" : "=r" (retval));
+
+	return retval;
+}
+
+#endif
Index: libc/arch/ia64/src/psthread.S
===================================================================
--- libc/arch/ia64/src/psthread.S	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/arch/ia64/src/psthread.S	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -0,0 +1,196 @@
+#
+# Copyright (C) 2005 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text
+
+.global context_save
+.global context_restore
+
+context_save:
+	alloc loc0 = ar.pfs, 1, 8, 0, 0
+	mov loc1 = ar.unat	;;
+	/* loc2 */
+	mov loc3 = ar.rsc
+
+	.auto
+
+	/*
+	 * Flush dirty registers to backing store.
+	 * After this ar.bsp and ar.bspstore are equal.
+	 */
+	flushrs
+	mov loc4 = ar.bsp	
+	
+	/*
+	 * Put RSE to enforced lazy mode.
+	 * So that ar.rnat can be read.
+	 */
+	and loc5 = ~3, loc3
+	mov ar.rsc = loc5
+	mov loc5 = ar.rnat
+
+	.explicit
+
+	mov loc6 = ar.lc
+	
+	/*
+	 * Save application registers
+	 */
+	st8 [in0] = loc0, 8	;;	/* save ar.pfs */
+	st8 [in0] = loc1, 8	;;	/* save ar.unat (caller) */
+	mov loc2 = in0		;;
+	add in0 = 8, in0	;;	/* skip ar.unat (callee) */
+	st8 [in0] = loc3, 8	;;	/* save ar.rsc */
+	st8 [in0] = loc4, 8	;;	/* save ar.bsp */
+	st8 [in0] = loc5, 8	;;	/* save ar.rnat */
+	st8 [in0] = loc6, 8	;;	/* save ar.lc */
+	
+	/*
+	 * Save general registers including NaT bits
+	 */
+	st8.spill [in0] = r1, 8		;;
+	st8.spill [in0] = r4, 8		;;
+	st8.spill [in0] = r5, 8		;;
+	st8.spill [in0] = r6, 8		;;
+	st8.spill [in0] = r7, 8		;;
+	st8.spill [in0] = r12, 8	;;	/* save sp */
+	st8.spill [in0] = r13, 8	;;	/* save tp */
+
+	mov loc3 = ar.unat		;;
+	st8 [loc2] = loc3		/* save ar.unat (callee) */
+
+	/*
+	 * Save branch registers
+	 */
+	mov loc2 = b0		;;
+	st8 [in0] = loc2, 8		/* save pc */
+	mov loc3 = b1		;;
+	st8 [in0] = loc3, 8
+	mov loc4 = b2		;;
+	st8 [in0] = loc4, 8
+	mov loc5 = b3		;;
+	st8 [in0] = loc5, 8
+	mov loc6 = b4		;;
+	st8 [in0] = loc6, 8
+	mov loc7 = b5		;;
+	st8 [in0] = loc7, 8
+
+	/*
+	 * Save predicate registers
+	 */
+	mov loc2 = pr		;;
+	st8 [in0] = loc2, 8	;;
+	
+	mov ar.unat = loc1
+	
+	add r8 = r0, r0, 1 		/* context_save returns 1 */
+	br.ret.sptk.many b0
+
+context_restore:
+	alloc loc0 = ar.pfs, 1, 9, 0, 0	;;
+
+	ld8 loc0 = [in0], 8	;;	/* load ar.pfs */
+	ld8 loc1 = [in0], 8	;;	/* load ar.unat (caller) */
+	ld8 loc2 = [in0], 8	;;	/* load ar.unat (callee) */
+	ld8 loc3 = [in0], 8	;;	/* load ar.rsc */
+	ld8 loc4 = [in0], 8	;;	/* load ar.bsp */
+	ld8 loc5 = [in0], 8	;;	/* load ar.rnat */
+	ld8 loc6 = [in0], 8	;;	/* load ar.lc */
+	
+	.auto	
+
+	/*
+	 * Invalidate the ALAT
+	 */
+	invala
+
+	/*
+	 * Put RSE to enforced lazy mode.
+	 * So that ar.bspstore and ar.rnat can be written.
+	 */
+	movl loc8 = ~3
+	and loc8 = loc3, loc8
+	mov ar.rsc = loc8
+
+	/*
+	 * Flush dirty registers to backing store.
+	 * We do this because we want the following move
+	 * to ar.bspstore to assign the same value to ar.bsp.
+	 */
+	flushrs
+
+	/*
+	 * Restore application registers
+	 */
+	mov ar.bspstore = loc4	/* rse.bspload = ar.bsp = ar.bspstore = loc4 */
+	mov ar.rnat = loc5
+	mov ar.pfs = loc0
+	mov ar.rsc = loc3
+
+	.explicit
+
+	mov ar.unat = loc2	;;
+	mov ar.lc = loc6
+	
+	/*
+	 * Restore general registers including NaT bits
+	 */
+	ld8.fill r1 = [in0], 8	;;
+	ld8.fill r4 = [in0], 8	;;
+	ld8.fill r5 = [in0], 8	;;
+	ld8.fill r6 = [in0], 8	;;
+	ld8.fill r7 = [in0], 8	;;
+	ld8.fill r12 = [in0], 8	;;	/* restore sp */
+	ld8.fill r13 = [in0], 8	;;
+
+	/* 
+	 * Restore branch registers
+	 */
+	ld8 loc2 = [in0], 8	;;	/* restore pc */
+	mov b0 = loc2
+	ld8 loc3 = [in0], 8	;;
+	mov b1 = loc3
+	ld8 loc4 = [in0], 8	;;
+	mov b2 = loc4
+	ld8 loc5 = [in0], 8	;;
+	mov b3 = loc5
+	ld8 loc6 = [in0], 8	;;
+	mov b4 = loc6
+	ld8 loc7 = [in0], 8	;;
+	mov b5 = loc7
+
+	/*
+	 * Restore predicate registers
+	 */
+	ld8 loc2 = [in0], 8	;;
+	mov pr = loc2, ~0
+	
+	mov ar.unat = loc1
+	
+	mov r8 = r0			/* context_restore returns 0 */
+	br.ret.sptk.many b0
Index: libc/generic/psthread.c
===================================================================
--- libc/generic/psthread.c	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/generic/psthread.c	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -33,11 +33,14 @@
 #include <thread.h>
 #include <stdio.h>
+#include <kernel/arch/faddr.h>
 
 static LIST_INITIALIZE(ready_list);
+
+static void ps_exit(void) __attribute__ ((noinline));
 
 /** Function to preempt to other thread without adding
  * currently running thread to runqueue
  */
-static void ps_exit(void)
+void ps_exit(void)
 {
 	psthread_data_t *pt;
@@ -88,6 +91,6 @@
 int ps_join(pstid_t psthrid)
 {
-	psthread_data_t *pt, *mypt;
-	int retval;
+	volatile psthread_data_t *pt, *mypt;
+	volatile int retval;
 
 	/* Handle psthrid = Kernel address -> it is wait for call */
@@ -97,6 +100,6 @@
 	if (!pt->finished) {
 		mypt = __tls_get();
-		if (context_save(&mypt->ctx)) {
-			pt->waiter = mypt;
+		if (context_save(&((psthread_data_t *) mypt)->ctx)) {
+			pt->waiter = (psthread_data_t *) mypt;
 			ps_exit();
 		}
@@ -105,5 +108,5 @@
 
 	free(pt->stack);
-	__free_tls(pt);
+	__free_tls((psthread_data_t *) pt);
 
 	return retval;
@@ -131,5 +134,5 @@
 
 	context_save(&pt->ctx);
-	context_set(&pt->ctx, psthread_main, pt->stack, getpagesize(), pt);
+	context_set(&pt->ctx, FADDR(psthread_main), pt->stack, getpagesize(), pt);
 
 	list_append(&pt->list, &ready_list);
Index: libc/include/align.h
===================================================================
--- libc/include/align.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
+++ libc/include/align.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ALIGN_H__
+#define __ALIGN_H__
+
+/** Align to the nearest lower address.
+ *
+ * @param s Address or size to be aligned.
+ * @param a Size of alignment, must be power of 2.
+ */
+#define ALIGN_DOWN(s, a)	((s) & ~((a) - 1))
+
+
+/** Align to the nearest higher address.
+ *
+ * @param s Address or size to be aligned.
+ * @param a Size of alignment, must be power of 2.
+ */
+#define ALIGN_UP(s, a)		(((s) + ((a) - 1)) & ~((a) - 1))
+
+#endif
Index: libc/include/psthread.h
===================================================================
--- libc/include/psthread.h	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/include/psthread.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -34,7 +34,7 @@
 
 #ifndef context_set
-#define context_set(c, _pc, stack, size, ptls) 	\
-	(c)->pc = (sysarg_t) (_pc);		\
-	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+#define context_set(c, _pc, stack, size, ptls) 			\
+	(c)->pc = (sysarg_t) (_pc);				\
+	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; 	\
         (c)->tls = (sysarg_t) (ptls);
 #endif /* context_set */
@@ -43,5 +43,5 @@
 
 struct psthread_data {
-	struct psthread_data *self; /* IA32,AMD64 needs to get self address */
+	struct psthread_data *self; /* ia32, amd64 needs to get self address */
 
 	link_t list;
Index: libc/include/stdarg.h
===================================================================
--- libc/include/stdarg.h	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/include/stdarg.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -45,2 +45,3 @@
 
 #endif
+
Index: libc/include/stdlib.h
===================================================================
--- libc/include/stdlib.h	(revision a71d9af9f07b33417eac0e091ee4318de370ac93)
+++ libc/include/stdlib.h	(revision 86d05faebd6bfaa54033b77b89c83c9e349ac8bd)
@@ -30,4 +30,5 @@
 #define __LIBC__STDLIB_H__
 
+#include <unistd.h>
 #include <malloc.h>
 
