Subject: Re: build aborts in regress/lib/libpthread/sem
To: None <mlist@beholder.homeunix.net>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-dreamcast
Date: 02/16/2003 10:26:05
In article <200302151940.23567.mlist@beholder.homeunix.net>
mlist@beholder.homeunix.net wrote:

> Have you noticed any networking slowdown with this patch?  Not that I've 
> experienced any slowdown myself, but I didn't test very scientifically from 
> old patch to new.

I couldn't test it because I don't have the LAN adapter,
but I'd say:

- Christian's original patch enables/disables interrupts
  on each byte so it would cause certain overhead.
- My patch disables interrupts during whole region/multi ops,
  so it would make response of other interrupts worse.

Another option is to unroll loops and disable/enable
interrupts on each iteration, but I'm not sure it really
makes any performance difference.
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp

Index: g2bus_bus_mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/g2/g2bus_bus_mem.c,v
retrieving revision 1.6
diff -u -r1.6 g2bus_bus_mem.c
--- g2bus_bus_mem.c	2002/12/27 11:34:05	1.6
+++ g2bus_bus_mem.c	2003/02/16 01:20:28
@@ -144,33 +144,22 @@
 
 /*
  * G2 bus cycles must not be interrupted by IRQs or G2 DMA.
- * The following paired macros will take the necessary precautions.
  */
 
-#define G2_LOCK								\
-	do {								\
-		_cpu_exception_suspend();				\
-		/* suspend any G2 DMA here... */			\
-		while((*(volatile unsigned int *)0xa05f688c) & 32);	\
-	} while(/*CONSTCOND*/0)
-
-#define G2_UNLOCK							\
-	do {								\
-		/* resume any G2 DMA here... */				\
-		_cpu_exception_resume(0);				\
-	} while(/*CONSTCOND*/0)
+#define WAIT_G2DMA while ((*(volatile unsigned int *)0xa05f688c) & 0x20)
 
-
 u_int8_t
 g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int8_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int8_t *)(sh + off);
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -178,13 +167,15 @@
 u_int16_t
 g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int16_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int16_t *)(sh + off);
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -192,13 +183,15 @@
 u_int32_t
 g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int32_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int32_t *)(sh + off);
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -207,64 +200,118 @@
 g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int8_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int8_t *)(sh + off) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int16_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int16_t *)(sh + off) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int32_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int32_t *)(sh + off) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_bus_mem_read_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile const u_int8_t *baddr = (u_int8_t *)(sh + off);
 
-	G2_LOCK;
+	for (; len >= 16; len -= 16) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		*addr++ = *baddr++;
+		_cpu_intr_resume(s);
+	}
 
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
+
 	while (len--)
 		*addr++ = *baddr++;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_bus_mem_write_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
     const u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile u_int8_t *baddr = (u_int8_t *)(sh + off);
+
+	for (; len >= 16; len -= 16) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		*baddr++ = *addr++;
+		_cpu_intr_resume(s);
+	}
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	while (len--)
 		*baddr++ = *addr++;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
@@ -291,13 +338,15 @@
 u_int8_t
 g2bus_sparse_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int8_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int8_t *)(sh + (off * 4));
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -305,13 +354,15 @@
 u_int16_t
 g2bus_sparse_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int16_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int16_t *)(sh + (off * 4));
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -319,13 +370,15 @@
 u_int32_t
 g2bus_sparse_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
 {
+	int s;
 	u_int32_t rv;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	rv = *(__volatile u_int32_t *)(sh + (off * 4));
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 
 	return (rv);
 }
@@ -334,94 +387,196 @@
 g2bus_sparse_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int8_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int8_t *)(sh + (off * 4)) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int16_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int16_t *)(sh + (off * 4)) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
     u_int32_t val)
 {
+	int s;
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	*(__volatile u_int32_t *)(sh + (off * 4)) = val;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_read_region_1(void *v, bus_space_handle_t sh,
     bus_size_t off, u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile const u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
 
-	G2_LOCK;
+	for (; len >= 8; len -= 8) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		*addr++ = *baddr;
+		baddr += 4;
+		_cpu_intr_resume(s);
+	}
+		
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	while (len--) {
 		*addr++ = *baddr;
 		baddr += 4;
 	}
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_write_region_1(void *v, bus_space_handle_t sh,
     bus_size_t off, const u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
 
-	G2_LOCK;
+	for (; len >= 8; len -= 8) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		*baddr = *addr++;
+		baddr += 4;
+		_cpu_intr_resume(s);
+	}
+
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	while (len--) {
 		*baddr = *addr++;
 		baddr += 4;
 	}
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_read_multi_1(void *v, bus_space_handle_t sh,
     bus_size_t off, u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile const u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
+
+	for (; len >= 16; len -= 16) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		*addr++ = *baddr;
+		_cpu_intr_resume(s);
+	}
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	while (len--)
 		*addr++ = *baddr;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }
 
 void
 g2bus_sparse_bus_mem_write_multi_1(void *v, bus_space_handle_t sh,
     bus_size_t off, const u_int8_t *addr, bus_size_t len)
 {
+	int s;
 	__volatile u_int8_t *baddr = (u_int8_t *)(sh + (off * 4));
+
+	for (; len >= 16; len -= 16) {
+		s = _cpu_intr_suspend();
+		WAIT_G2DMA;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		*baddr = *addr++;
+		_cpu_intr_resume(s);
+	}
 
-	G2_LOCK;
+	s = _cpu_intr_suspend();
+	WAIT_G2DMA;
 
 	while (len--)
 		*baddr = *addr++;
 
-	G2_UNLOCK;
+	_cpu_intr_resume(s);
 }