[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: How could HP help Debian



On Mon, Sep 15, 2003 at 10:42:30AM -0400, Grzegorz B. Prokopski wrote:
> My objective is to get SableVM working on HPPA.
> I've just seen
> http://lists.debian.org/debian-hppa/2002/debian-hppa-200208/msg00132.html
> which unfortunately ends w/o any conclusions (again).

Kernel assist is the conclusion. You can't do multi-insn atomic
operations in userspace because signals will get you in trouble.
 
> So as I originally said - I'd be glad to "take a look" at the code of
> your cmp&xchg instruction emulation because I belive it may be better
> that what I was thinking about.
> 
> You made me curious and I want to find the best solution for SableVM
> on HPPA. So maybe you could just attach the most relevant files with
> your (maybe incomplete, partial) implementation and sent me off the
> list?

"Idea-patch" attached. We already have a single light-weight syscall to
retreive the tcb of the current thread (e.g. the value of the thread
register as seen by libc's thread manager).

What needs to be done with the current patch:
- Implement the rest of the atomic ops in glibc's atomic.h for future
  uses.
- Move the code back onto the gateway page (need to be executable)
- Create light-weight syscall table patterned after the normal syscall
  table.
- Add loader code at 0xA0 that reads r26, loads the jump address from a
  light-weight syscall table and jumps there (look at how syscall does
  it)
- Testing.

Already done:
- Example scalability through address hasihing -> lock for SMP systems.
- Example CAS implemented.

If you can take this example code and flesh it out I would be _really_
happy! :)

> I also have another question, more general, may be to the whole list:
> do you currently have *any* JVM working on HPPA? I've seen thread about
> kaffe working, but look at ftp://ftp.debian.org/debian/pool/main/k/kaffe
> shows that it's not the case. [*]

Unknown :)

c.
? config-2.4.21-pa5
? config-thibaut
? dep.log
? modules.log
? vmlinux.log
? arch/parisc/kernel/syscall.S.diff
Index: arch/parisc/kernel/syscall.S
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/syscall.S,v
retrieving revision 1.79
diff -u -p -r1.79 syscall.S
--- arch/parisc/kernel/syscall.S	15 Jul 2003 04:35:18 -0000	1.79
+++ arch/parisc/kernel/syscall.S	27 Aug 2003 01:13:01 -0000
@@ -7,6 +7,8 @@
  * sorry about the wall, puffin..
  */
 
+#include <linux/autoconf.h>   /* for CONFIG_SMP */
+
 #include <asm/offset.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
@@ -48,7 +50,9 @@ linux_gateway_page:
 	break   0,0
 	.endr
 
+
 set_thread_pointer:
+	/* WARNING - Must start at address 0xE0 to match GNU/Libc's assembly macro! */
 	gate	.+8, %r0		/* increase privilege */
 	depi	3, 31, 2, %r31		/* Ensure we return into user mode. */
 	be	0(%sr7,%r31)		/* return to user space */
@@ -613,4 +617,81 @@ sys_call_table:
 	.align 4096
 	.export end_linux_gateway_page
 end_linux_gateway_page:
+
+/* Start of next page, we store the kernel-assisted fast-syscalls of 
+ * atomic operations on this page. The entry point for these fast-syscalls
+ * is in the start of the gateway page.
+ */
+
+/* All atomic operations use this set of 16 locks. This ensures that
+ * threads on multiple cpus executing different atomic fast-syscalls
+ * on the same address hash to the same lock and are serialized.
+ */
+
+lock_start:
+	.rept 16
+	.align 16
+	.word 1
+	.endr
+
+atomic_compare_and_swap:
+	/* Implementing CAS as atomic kernel operation
+	 * %r26 - Address to examine (addr)
+	 * %r25 - Old value to check (old)
+	 * %r24 - New value to set   (new)
+	 * %r28 - Return (prev) through this register
+	 */
+	
+	gate		.+8, %r0				/* Increase privilege */
+	depi		3, 31, 2, %r31		/* Make sure we return to userspace */
+
+#ifdef CONFIG_SMP
+	/* Load start of lock table */
+	ldil		L%lock_start, %r1
+	ldo		R%lock_start(%r1), %r21
+
+	/* Extract four bits from %r26 that hash to a lock (Bits 4-7)*/
+	extru		%r26, 4, 4, %r20
+
+	/* Find lock to use (start+offset) */
+	add		%r20, %r21, %r20
+#endif
+
+	/* Disable interrupts */
+	rsm		PSW_SM_I, %r0
+
+#ifdef CONFIG_SMP
+	/* Try to acquire lock, if you fail then spin */
+.Lcas_spin:
+	ldcw		0(%r20), %r21
+	cmpib,=	0, %r21, cas_spin	
+
+	/* With lock acquired do the CAS */
+#endif
+
+	/*
+		prev = *addr;
+		if ( prev == old )
+			*addr = new;
+		return prev;
+	*/
+
+	/* Load value from CAS address */
+	ldw		0(%r26), %r28
+	cmpib,<>	%r28, %r25, no_change
+	stw,ma	%r24, (%r26)
+
+.Lno_change:
+
+#ifdef CONFIG_SMP
+	/* Release the lock (stack pointer is a valid non-zero value?) */
+	stw,ma	%sp, 0(%r20)
+#endif
+
+	/* Enable interrupts */
+	ssm	PSW_SM_I, %r0
+
+	/* Return to userspace */
+	bo	0(%sr7,%r31)
+	nop
 

Reply to: