diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2006-09-30 02:38:06 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@axis.com> | 2006-09-30 02:38:06 +0000 |
commit | eccd787e25d7213738b9c5be9416398abd0caaae (patch) | |
tree | 5d5a42c60abf964856bfe13e95913a030c165826 | |
parent | 539a52558fc24b1a2c4dd3d6dc389ca111858401 (diff) | |
download | binutils-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/ChangeLog | 7 | ||||
-rw-r--r-- | sim/cris/traps.c | 37 |
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, |