• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / JavaSpiNNaker / 6233274834

19 Sep 2023 08:46AM UTC coverage: 36.409% (-0.6%) from 36.982%
6233274834

Pull #658

github

dkfellows
Merge branch 'master' into java-17
Pull Request #658: Update Java version to 17

1656 of 1656 new or added lines in 260 files covered. (100.0%)

8373 of 22997 relevant lines covered (36.41%)

0.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/SpiNNaker-comms/src/main/java/uk/ac/manchester/spinnaker/transceiver/BMPWriteMemoryProcess.java
1
/*
2
 * Copyright (c) 2018 The University of Manchester
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package uk.ac.manchester.spinnaker.transceiver;
17

18
import static java.lang.Math.min;
19
import static java.nio.ByteBuffer.allocate;
20
import static java.nio.ByteOrder.LITTLE_ENDIAN;
21
import static uk.ac.manchester.spinnaker.messages.Constants.UDP_MESSAGE_MAX_SIZE;
22
import static uk.ac.manchester.spinnaker.utils.ByteBufferUtils.read;
23

24
import java.io.IOException;
25
import java.io.InputStream;
26
import java.nio.ByteBuffer;
27
import java.util.Iterator;
28

29
import uk.ac.manchester.spinnaker.connections.BMPConnection;
30
import uk.ac.manchester.spinnaker.connections.ConnectionSelector;
31
import uk.ac.manchester.spinnaker.machine.MemoryLocation;
32
import uk.ac.manchester.spinnaker.machine.board.BMPBoard;
33
import uk.ac.manchester.spinnaker.messages.Constants;
34
import uk.ac.manchester.spinnaker.messages.bmp.WriteBMPMemory;
35
import uk.ac.manchester.spinnaker.utils.UsedInJavadocOnly;
36
import uk.ac.manchester.spinnaker.utils.ValueHolder;
37

38
/**
39
 * Write to memory on a BMP.
40
 */
41
class BMPWriteMemoryProcess extends BMPCommandProcess {
42
        /**
43
         * @param connectionSelector
44
         *            How to select how to communicate.
45
         * @param retryTracker
46
         *            Object used to track how many retries were used in an
47
         *            operation. May be {@code null} if no suck tracking is
48
         *            required.
49
         */
50
        BMPWriteMemoryProcess(ConnectionSelector<BMPConnection> connectionSelector,
51
                        RetryTracker retryTracker) {
52
                super(connectionSelector, retryTracker);
×
53
        }
×
54

55
        /**
56
         * Writes memory onto a BMP from a buffer.
57
         *
58
         * @param board
59
         *            Which board's BMP to write to.
60
         * @param baseAddress
61
         *            Where to start copying to.
62
         * @param data
63
         *            The buffer of data to be copied. The copied region extends
64
         *            from the <i>position</i> (inclusive) to the <i>limit</i>
65
         *            (exclusive). This method is not obligated to preserve either
66
         *            the position or the limit, though the current implementation
67
         *            does so. The contents of the buffer will not be modified.
68
         * @throws IOException
69
         *             If anything goes wrong with networking.
70
         * @throws ProcessException
71
         *             If SpiNNaker rejects a message.
72
         * @throws InterruptedException
73
         *             If the communications were interrupted.
74
         */
75
        void writeMemory(BMPBoard board, MemoryLocation baseAddress,
76
                        ByteBuffer data)
77
                        throws IOException, ProcessException, InterruptedException {
78
                execute(new BMPWriteIterator(board, baseAddress, data.remaining()) {
×
79
                        private int offset = data.position();
×
80

81
                        @Override
82
                        ByteBuffer prepareSendBuffer(int chunkSize) {
83
                                var buffer = data.slice(offset, chunkSize).order(LITTLE_ENDIAN);
×
84
                                offset += chunkSize;
×
85
                                return buffer;
×
86
                        }
87
                });
88
        }
×
89

90
        /**
91
         * Writes memory onto a BMP from an input stream.
92
         *
93
         * @param board
94
         *            Which board's BMP to write to.
95
         * @param baseAddress
96
         *            Where to start copying to.
97
         * @param data
98
         *            Where to get data from
99
         * @param bytesToWrite
100
         *            How many bytes should be copied from the stream?
101
         * @throws IOException
102
         *             If anything goes wrong with networking or the input stream.
103
         * @throws ProcessException
104
         *             If SpiNNaker rejects a message.
105
         * @throws InterruptedException
106
         *             If the communications were interrupted.
107
         */
108
        void writeMemory(BMPBoard board, MemoryLocation baseAddress,
109
                        InputStream data, int bytesToWrite)
110
                        throws IOException, ProcessException, InterruptedException {
111
                var exn = new ValueHolder<IOException>();
×
112
                var workingBuffer = allocate(UDP_MESSAGE_MAX_SIZE);
×
113

114
                execute(new BMPWriteIterator(board, baseAddress, bytesToWrite) {
×
115
                        @Override
116
                        ByteBuffer prepareSendBuffer(int chunkSize) {
117
                                try {
118
                                        return read(data, workingBuffer, chunkSize);
×
119
                                } catch (IOException e) {
×
120
                                        exn.setValue(e); // Smuggle the exception out!
×
121
                                        return null;
×
122
                                }
123
                        }
124
                });
125
                if (exn.getValue() != null) {
×
126
                        throw exn.getValue();
×
127
                }
128
        }
×
129
}
130

131
/**
132
 * Helper for writing a stream of chunks. Allows us to construct the chunks one
133
 * at a time on demand. The complexity is because chunk construction is
134
 * permitted to fail!
135
 * <p>
136
 * This is a one-shot iterable.
137
 *
138
 * @author Donal Fellows
139
 */
140
abstract class BMPWriteIterator implements Iterable<WriteBMPMemory> {
141
        private final BMPBoard board;
142

143
        private int sizeRemaining;
144

145
        private MemoryLocation address;
146

147
        private ByteBuffer sendBuffer;
148

149
        /**
150
         * @param board
151
         *            Where the write messages are going.
152
         * @param address
153
         *            Where the writes start at.
154
         * @param size
155
         *            What size of memory will be written.
156
         */
157
        BMPWriteIterator(BMPBoard board, MemoryLocation address, int size) {
×
158
                this.board = board;
×
159
                this.address = address;
×
160
                this.sizeRemaining = size;
×
161
        }
×
162

163
        /**
164
         * Get the next chunk.
165
         *
166
         * @param plannedSize
167
         *            What size the chunk should be. Up to
168
         *            {@link Constants#UDP_MESSAGE_MAX_SIZE}.
169
         * @return The chunk, or {@code null} if no chunk available.
170
         */
171
        @UsedInJavadocOnly(Constants.class)
172
        abstract ByteBuffer prepareSendBuffer(int plannedSize);
173

174
        @Override
175
        public Iterator<WriteBMPMemory> iterator() {
176
                return new Iterator<>() {
×
177
                        @Override
178
                        public boolean hasNext() {
179
                                if (sizeRemaining < 1) {
×
180
                                        return false;
×
181
                                }
182
                                sendBuffer = prepareSendBuffer(
×
183
                                                min(sizeRemaining, UDP_MESSAGE_MAX_SIZE));
×
184
                                return sendBuffer != null;
×
185
                        }
186

187
                        @Override
188
                        public WriteBMPMemory next() {
189
                                int chunkSize = sendBuffer.remaining();
×
190
                                try {
191
                                        return new WriteBMPMemory(board, address, sendBuffer);
×
192
                                } finally {
193
                                        address = address.add(chunkSize);
×
194
                                        sizeRemaining -= chunkSize;
×
195
                                }
196
                        }
197
                };
198
        }
199
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc