Index: init/init.c
===================================================================
--- init/init.c	(revision 11a4fbf3d932714911471f5631d3814591b6851e)
+++ init/init.c	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -38,5 +38,5 @@
 void utest(void *arg)
 {
-//	printf("Uspace thread created.\n");
+//	printf("Uspace thread started.\n");
 	for (;;)
 		;
@@ -190,5 +190,4 @@
 {
 	int tid;
-	char *stack;
 	version_print();
 
@@ -199,11 +198,6 @@
 	test_connection_ipc();
 	
-	stack = (char *) malloc(getpagesize());
-	if (!stack) {
-		printf("Malloc failed.\n");
-	} else {
-		if ((tid = thread_create(utest, NULL, stack, "utest") != -1)) {
-			printf("Created thread tid=%d\n", tid);
-		}
+	if ((tid = thread_create(utest, NULL, "utest") != -1)) {
+		printf("Created thread tid=%d\n", tid);
 	}
 	
Index: libc/Makefile
===================================================================
--- libc/Makefile	(revision 11a4fbf3d932714911471f5631d3814591b6851e)
+++ libc/Makefile	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -52,5 +52,6 @@
 
 ARCH_SOURCES += \
-	arch/$(ARCH)/src/entry.s
+	arch/$(ARCH)/src/entry.s \
+	arch/$(ARCH)/src/thread_entry.s
 
 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
Index: libc/arch/amd64/src/thread_entry.s
===================================================================
--- libc/arch/amd64/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
+++ libc/arch/amd64/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+.text
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	#
+	# RAX contains address of uarg
+	#
+	movq %rax, %rdi
+	call thread_main
+	
+.end __thread_entry
Index: libc/arch/ia32/src/thread_entry.s
===================================================================
--- libc/arch/ia32/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
+++ libc/arch/ia32/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -0,0 +1,48 @@
+#
+# 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.
+#
+
+.text
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	#
+	# EAX contains address of uarg.
+	#
+	pushl %eax
+	call thread_main
+	addl $4, %esp
+	
+	#
+	# Not reached.
+	#
+	
+.end __thread_entry
Index: libc/arch/ia64/src/entry.s
===================================================================
--- libc/arch/ia64/src/entry.s	(revision 11a4fbf3d932714911471f5631d3814591b6851e)
+++ libc/arch/ia64/src/entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -37,4 +37,5 @@
 #
 __entry:
+	alloc loc0 = ar.pfs, 0, 1, 2, 0
 	mov r1 = _gp 
 	{ br.call.sptk.many b0 = main }
Index: libc/arch/ia64/src/thread_entry.s
===================================================================
--- libc/arch/ia64/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
+++ libc/arch/ia64/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+.text
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	alloc loc0 = ar.pfs, 0, 1, 1, 0
+
+	mov r1 = _gp
+	
+	#
+	# r8 contains address of uarg structure.
+	#
+	
+	mov out0 = r8
+	{ br.call.sptk.many b0 = thread_main }
+	
+	#
+	# Not reached.
+	#
+	
+.end __thread_entry
Index: libc/arch/mips32/src/thread_entry.s
===================================================================
--- libc/arch/mips32/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
+++ libc/arch/mips32/src/thread_entry.s	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+.set nomacro
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	#
+	# v0 contains address of uarg.
+	#
+	add $4, $2, 0
+	jal thread_main
+	nop
+	
+	#
+	# Not reached.
+	#
Index: libc/generic/thread.c
===================================================================
--- libc/generic/thread.c	(revision 11a4fbf3d932714911471f5631d3814591b6851e)
+++ libc/generic/thread.c	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -29,11 +29,37 @@
 #include <thread.h>
 #include <libc.h>
+#include <stdlib.h>
 #include <arch/faddr.h>
+#include <kernel/proc/uarg.h>
 
-typedef void (* voidfunc_t)(void);
+void thread_main(uspace_arg_t *uarg)
+{
+	uarg->uspace_thread_function(uarg->uspace_thread_arg);
+	free(uarg->uspace_stack);
+	free(uarg);
+	thread_exit(0);
+}
 
-int thread_create(void (* function)(void *), void *arg, void *stack, char *name)
+int thread_create(void (* function)(void *), void *arg, char *name)
 {
-	return __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) FADDR((voidfunc_t) function), (sysarg_t) arg, (sysarg_t) stack, (sysarg_t) name);
+	char *stack;
+	uspace_arg_t *uarg;
+
+	stack = (char *) malloc(getpagesize());
+	if (!stack)
+		return -1;
+		
+	uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
+	if (!uarg) {
+		free(stack);
+		return -1;
+	}
+	uarg->uspace_entry = (void *) FADDR(__thread_entry);
+	uarg->uspace_stack = (void *) stack;
+	uarg->uspace_thread_function = (void *) FADDR(function);
+	uarg->uspace_thread_arg = arg;
+	uarg->uspace_uarg = uarg;
+	
+	return __SYSCALL2(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name);
 }
 
@@ -42,3 +68,2 @@
 	__SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
 }
-
Index: libc/include/thread.h
===================================================================
--- libc/include/thread.h	(revision 11a4fbf3d932714911471f5631d3814591b6851e)
+++ libc/include/thread.h	(revision e5a1f82f130880819d13b0748a2b517dd8a63df5)
@@ -30,6 +30,11 @@
 #define __LIBC__THREAD_H__
 
-int thread_create(void (* function)(void *arg), void *arg, void *stack, char *name);
-void thread_exit(int status);
+#include <kernel/proc/uarg.h>
+
+extern void __thread_entry(void);
+extern void thread_main(uspace_arg_t *uarg);
+
+extern int thread_create(void (* function)(void *arg), void *arg, char *name);
+extern void thread_exit(int status);
 
 #endif
