summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan McGee <dpmcgee@gmail.com>2012-01-29 15:30:44 -0600
committerDan McGee <dpmcgee@gmail.com>2012-01-29 15:32:09 -0600
commita75a555e1ec4f349f41a1fa2fa355a2ec821d88b (patch)
treef3b5ca06d73bf7bb92586ef2d75be9e8bb70e2c4
parentb2ec1416fffdb45c57d9f0dece1685bbcaffd425 (diff)
downloadonkyocontrol-a75a555e1ec4f349f41a1fa2fa355a2ec821d88b.tar.gz
onkyocontrol-a75a555e1ec4f349f41a1fa2fa355a2ec821d88b.zip
Reduce number of memory allocations
Combine certain allocation requests into a single request by inlining the character buffer and not asking for exact sizes. In other places, use the stack rather than a malloc/free cycle within a single function, since we know these allocations are never bigger than 128 bytes anyway. Signed-off-by: Dan McGee <dpmcgee@gmail.com>
-rw-r--r--command.c12
-rw-r--r--onkyo.h2
-rw-r--r--receiver.c30
3 files changed, 22 insertions, 22 deletions
diff --git a/command.c b/command.c
index 30ed45d..737c9c7 100644
--- a/command.c
+++ b/command.c
@@ -74,20 +74,19 @@ static void strtoupper(char *str)
static int cmd_attempt(struct receiver *rcvr,
const struct command *cmd, const char *arg)
{
- char *fullcmd;
struct cmdqueue *q;
if(!cmd || !arg)
return -1;
-
- fullcmd = malloc(strlen(cmd->prefix) + strlen(arg) + 1);
- sprintf(fullcmd, "%s%s", cmd->prefix, arg);
+ if(strlen(cmd->prefix) + strlen(arg) >= BUF_SIZE)
+ return -1;
q = malloc(sizeof(struct cmdqueue));
if(!q)
return -1;
- q->hash = hash_sdbm(fullcmd);
- q->cmd = fullcmd;
+
+ sprintf(q->cmd, "%s%s", cmd->prefix, arg);
+ q->hash = hash_sdbm(q->cmd);
q->next = NULL;
if(rcvr->queue == NULL) {
@@ -98,7 +97,6 @@ static int cmd_attempt(struct receiver *rcvr,
if(ptr->hash == q->hash) {
/* command already in our queue, skip second copy */
free(q);
- free(fullcmd);
return 0;
}
if(!ptr->next)
diff --git a/onkyo.h b/onkyo.h
index 1769dbf..f88a901 100644
--- a/onkyo.h
+++ b/onkyo.h
@@ -49,7 +49,7 @@ enum pipehalfs { READ = 0, WRITE = 1 };
/** Represents a command waiting to be sent to the receiver */
struct cmdqueue {
unsigned long hash;
- char *cmd;
+ char cmd[BUF_SIZE];
struct cmdqueue *next;
};
diff --git a/receiver.c b/receiver.c
index a810196..e33188b 100644
--- a/receiver.c
+++ b/receiver.c
@@ -48,7 +48,7 @@ struct power_status {
* @param rcvr the receiver to pull a command out of the queue for
* @return the command to send (must be freed), NULL if none available
*/
-static char *next_rcvr_command(struct receiver *rcvr)
+static struct cmdqueue *next_rcvr_command(struct receiver *rcvr)
{
/* Determine whether we should send the command. This depends on two
* factors:
@@ -61,12 +61,9 @@ static char *next_rcvr_command(struct receiver *rcvr)
rcvr->queue = rcvr->queue->next;
if(rcvr->power || is_power_command(ptr->cmd)) {
- char *cmd = ptr->cmd;
- free(ptr);
- return cmd;
+ return ptr;
} else {
printf("skipping command as receiver power appears to be off\n");
- free(ptr->cmd);
free(ptr);
}
}
@@ -82,18 +79,24 @@ static char *next_rcvr_command(struct receiver *rcvr)
*/
int rcvr_send_command(struct receiver *rcvr)
{
- char *cmd;
+ struct cmdqueue *ptr;
if(!rcvr->queue)
return -1;
- cmd = next_rcvr_command(rcvr);
- if(cmd) {
+ ptr = next_rcvr_command(rcvr);
+ if(ptr) {
ssize_t retval;
- size_t cmdsize = strlen(START_SEND) + strlen(cmd)
- + strlen(END_SEND);
- char *fullcmd = malloc(cmdsize + 1);
- sprintf(fullcmd, START_SEND "%s" END_SEND, cmd);
+ size_t cmdsize;
+ char fullcmd[BUF_SIZE * 2];
+
+ cmdsize = strlen(START_SEND) + strlen(ptr->cmd) + strlen(END_SEND);
+ if(cmdsize >= BUF_SIZE * 2) {
+ fprintf(stderr, "send_command, command too large: %zd\n", cmdsize);
+ return -1;
+ }
+
+ sprintf(fullcmd, START_SEND "%s" END_SEND, ptr->cmd);
/* write the command */
retval = xwrite(rcvr->fd, fullcmd, cmdsize);
@@ -101,8 +104,7 @@ int rcvr_send_command(struct receiver *rcvr)
gettimeofday(&(rcvr->last_cmd), NULL);
/* print command to console; newline is already in command */
printf("command: %s", fullcmd);
- free(fullcmd);
- free(cmd);
+ free(ptr);
if(retval < 0 || ((size_t)retval) != cmdsize) {
fprintf(stderr, "send_command, write returned %zd\n", retval);