• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂49f3a42edf097fbaca76aef9bfcd98d871b442cb (tree)
時間2022-07-19 20:46:28
作者Rasmus Villemoes <rasmus.villemoes@prev...>
CommiterHeiko Schocher

Log Message

i2c: avoid dynamic stack use in dm_i2c_write

The size of the dynamic stack allocation here is bounded by the if()
statement. However, just allocating the maximum size up-front and
doing malloc() if necessary avoids code duplication (the
i2c_setup_offset() until the invocation of ->xfer), and generates much
better (smaller) code:

bloat-o-meter drivers/i2c/i2c-uclass.o.{0,1}
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-144 (-144)
Function old new delta
dm_i2c_write 552 408 -144
Total: Before=3828, After=3684, chg -3.76%

It also makes static analysis of maximum stack usage (using the .su
files that are automatically generated during build) easier if there
are no lines saying "dynamic".

[This is not entirely equivalent to the existing code; this now uses
the stack for len <= 64 rather than len <= 63, but that seems like a
more natural limit.]

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Reviewed-by: Heiko Schocher <hs@denx.de>

Change Summary

差異

--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -168,6 +168,9 @@ int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
168168 struct udevice *bus = dev_get_parent(dev);
169169 struct dm_i2c_ops *ops = i2c_get_ops(bus);
170170 struct i2c_msg msg[1];
171+ uint8_t _buf[I2C_MAX_OFFSET_LEN + 64];
172+ uint8_t *buf = _buf;
173+ int ret;
171174
172175 if (!ops->xfer)
173176 return -ENOSYS;
@@ -192,29 +195,20 @@ int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
192195 * need to allow space for the offset (up to 4 bytes) and the message
193196 * itself.
194197 */
195- if (len < 64) {
196- uint8_t buf[I2C_MAX_OFFSET_LEN + len];
197-
198- i2c_setup_offset(chip, offset, buf, msg);
199- msg->len += len;
200- memcpy(buf + chip->offset_len, buffer, len);
201-
202- return ops->xfer(bus, msg, 1);
203- } else {
204- uint8_t *buf;
205- int ret;
206-
198+ if (len > sizeof(_buf) - I2C_MAX_OFFSET_LEN) {
207199 buf = malloc(I2C_MAX_OFFSET_LEN + len);
208200 if (!buf)
209201 return -ENOMEM;
210- i2c_setup_offset(chip, offset, buf, msg);
211- msg->len += len;
212- memcpy(buf + chip->offset_len, buffer, len);
202+ }
213203
214- ret = ops->xfer(bus, msg, 1);
204+ i2c_setup_offset(chip, offset, buf, msg);
205+ msg->len += len;
206+ memcpy(buf + chip->offset_len, buffer, len);
207+
208+ ret = ops->xfer(bus, msg, 1);
209+ if (buf != _buf)
215210 free(buf);
216- return ret;
217- }
211+ return ret;
218212 }
219213
220214 int dm_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)