summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2006-09-30 02:38:06 +0000
committerHans-Peter Nilsson <hp@axis.com>2006-09-30 02:38:06 +0000
commiteccd787e25d7213738b9c5be9416398abd0caaae (patch)
tree5d5a42c60abf964856bfe13e95913a030c165826
parent539a52558fc24b1a2c4dd3d6dc389ca111858401 (diff)
downloadbinutils-eccd787e25d7213738b9c5be9416398abd0caaae.tar.gz
binutils-eccd787e25d7213738b9c5be9416398abd0caaae.tar.bz2
binutils-eccd787e25d7213738b9c5be9416398abd0caaae.zip
* cris/traps.c (TARGET_PIPE_BUF): New macro.
(cris_pipe_empty): Correct initialization of "remaining". Only adjust the "write" return value if more than TARGET_PIPE_BUF bytes are written.
-rw-r--r--sim/ChangeLog7
-rw-r--r--sim/cris/traps.c37
2 files changed, 31 insertions, 13 deletions
diff --git a/sim/ChangeLog b/sim/ChangeLog
index d68f2300ea1..bd3129ac46c 100644
--- a/sim/ChangeLog
+++ b/sim/ChangeLog
@@ -1,3 +1,10 @@
+2006-09-30 Hans-Peter Nilsson <hp@axis.com>
+
+ * cris/traps.c (TARGET_PIPE_BUF): New macro.
+ (cris_pipe_empty): Correct initialization of "remaining". Only
+ adjust the "write" return value if more than TARGET_PIPE_BUF bytes
+ are written.
+
2006-09-29 Hans-Peter Nilsson <hp@axis.com>
* cris/configure.ac: Check for limits.h and sys/param.h.
diff --git a/sim/cris/traps.c b/sim/cris/traps.c
index 487fadd83a1..371688f70a2 100644
--- a/sim/cris/traps.c
+++ b/sim/cris/traps.c
@@ -240,6 +240,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define TARGET___WALL 0x40000000
#define TARGET___WCLONE 0x80000000
+/* From linux/limits.h. */
+#define TARGET_PIPE_BUF 4096
+
static const char stat_map[] =
"st_dev,2:space,10:space,4:st_mode,4:st_nlink,4:st_uid,4"
":st_gid,4:st_rdev,2:space,10:st_size,8:st_blksize,4:st_blocks,4"
@@ -2971,13 +2974,14 @@ cris_pipe_nonempty (host_callback *cb ATTRIBUTE_UNUSED,
static void
cris_pipe_empty (host_callback *cb,
- int reader ATTRIBUTE_UNUSED,
+ int reader,
int writer)
{
int i;
SIM_CPU *cpu = current_cpu_for_cb_callback;
bfd_byte r10_buf[4];
- int remaining = cb->pipe_buffer[writer].size;
+ int remaining
+ = cb->pipe_buffer[writer].size - cb->pipe_buffer[reader].size;
/* We need to find the thread that waits for this pipe. */
for (i = 0; i < SIM_TARGET_MAX_THREADS; i++)
@@ -2985,6 +2989,7 @@ cris_pipe_empty (host_callback *cb,
&& cpu->thread_data[i].pipe_write_fd == writer)
{
int retval;
+
/* Temporarily switch to this cpu context, so we can change the
PC by ordinary calls. */
@@ -2995,19 +3000,25 @@ cris_pipe_empty (host_callback *cb,
cpu->thread_data[i].cpu_context,
cpu->thread_cpu_data_size);
- /* The return value is supposed to contain the number of written
- bytes, which is the number of bytes requested and returned at
- the write call. We subtract the remaining bytes from that,
- but making sure we still get a positive number.
- The return value may also be a negative number; an error
- value. We cover this case by comparing against remaining,
- which is always >= 0. */
+ /* The return value is supposed to contain the number of
+ written bytes, which is the number of bytes requested and
+ returned at the write call. You might think the right
+ thing is to adjust the return-value to be only the
+ *consumed* number of bytes, but it isn't. We're only
+ called if the pipe buffer is fully consumed or it is being
+ closed, possibly with remaining bytes. For the latter
+ case, the writer is still supposed to see success for
+ PIPE_BUF bytes (a constant which we happen to know and is
+ unlikely to change). The return value may also be a
+ negative number; an error value. This case is covered
+ because "remaining" is always >= 0. */
(*CPU_REG_FETCH (cpu)) (cpu, H_GR_R10, r10_buf, 4);
retval = (int) bfd_getl_signed_32 (r10_buf);
- if (retval >= remaining)
- bfd_putl32 (retval - remaining, r10_buf);
- (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
-
+ if (retval - remaining > TARGET_PIPE_BUF)
+ {
+ bfd_putl32 (retval - remaining, r10_buf);
+ (*CPU_REG_STORE (cpu)) (cpu, H_GR_R10, r10_buf, 4);
+ }
sim_pc_set (cpu, sim_pc_get (cpu) + 2);
memcpy (cpu->thread_data[i].cpu_context,
&cpu->cpu_data_placeholder,