~verterok/+junk/postgresql-amqp

« back to all changes in this revision

Viewing changes to librabbitmq/amqp_mem.c

  • Committer: Rodney Dawes
  • Date: 2010-08-19 14:35:20 UTC
  • Revision ID: rodney.dawes@canonical.com-20100819143520-25qfv1scbjt3p3xj
Tags: upstream-0.1+r180
ImportĀ upstreamĀ versionĀ 0.1+r180

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include <stdio.h>
 
3
#include <string.h>
 
4
#include <stdint.h>
 
5
#include <sys/types.h>
 
6
#include <errno.h>
 
7
#include <assert.h>
 
8
 
 
9
#include "amqp.h"
 
10
#include "amqp_config.h"
 
11
 
 
12
char const *amqp_version(void) {
 
13
  return VERSION; /* defined in config.h */
 
14
}
 
15
 
 
16
void init_amqp_pool(amqp_pool_t *pool, size_t pagesize) {
 
17
  pool->pagesize = pagesize ? pagesize : 4096;
 
18
 
 
19
  pool->pages.num_blocks = 0;
 
20
  pool->pages.blocklist = NULL;
 
21
 
 
22
  pool->large_blocks.num_blocks = 0;
 
23
  pool->large_blocks.blocklist = NULL;
 
24
 
 
25
  pool->next_page = 0;
 
26
  pool->alloc_block = NULL;
 
27
  pool->alloc_used = 0;
 
28
}
 
29
 
 
30
static void empty_blocklist(amqp_pool_blocklist_t *x) {
 
31
  int i;
 
32
 
 
33
  for (i = 0; i < x->num_blocks; i++) {
 
34
    free(x->blocklist[i]);
 
35
  }
 
36
  if (x->blocklist != NULL) {
 
37
    free(x->blocklist);
 
38
  }
 
39
  x->num_blocks = 0;
 
40
  x->blocklist = NULL;
 
41
}
 
42
 
 
43
void recycle_amqp_pool(amqp_pool_t *pool) {
 
44
  empty_blocklist(&pool->large_blocks);
 
45
  pool->next_page = 0;
 
46
  pool->alloc_block = NULL;
 
47
  pool->alloc_used = 0;
 
48
}
 
49
 
 
50
void empty_amqp_pool(amqp_pool_t *pool) {
 
51
  recycle_amqp_pool(pool);
 
52
  empty_blocklist(&pool->pages);
 
53
}
 
54
 
 
55
static int record_pool_block(amqp_pool_blocklist_t *x, void *block) {
 
56
  size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1);
 
57
 
 
58
  if (x->blocklist == NULL) {
 
59
    x->blocklist = malloc(blocklistlength);
 
60
    if (x->blocklist == NULL) {
 
61
      return -ENOMEM;
 
62
    }
 
63
  } else {
 
64
    void *newbl = realloc(x->blocklist, blocklistlength);
 
65
    if (newbl == NULL) {
 
66
      return -ENOMEM;
 
67
    }
 
68
    x->blocklist = newbl;
 
69
  }
 
70
 
 
71
  x->blocklist[x->num_blocks] = block;
 
72
  x->num_blocks++;
 
73
  return 0;
 
74
}
 
75
 
 
76
void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) {
 
77
  if (amount == 0) {
 
78
    return NULL;
 
79
  }
 
80
 
 
81
  amount = (amount + 7) & (~7); /* round up to nearest 8-byte boundary */
 
82
 
 
83
  if (amount > pool->pagesize) {
 
84
    void *result = calloc(1, amount);
 
85
    if (result == NULL) {
 
86
      return NULL;
 
87
    }
 
88
    if (record_pool_block(&pool->large_blocks, result) != 0) {
 
89
      return NULL;
 
90
    }
 
91
    return result;
 
92
  }
 
93
 
 
94
  if (pool->alloc_block != NULL) {
 
95
    assert(pool->alloc_used <= pool->pagesize);
 
96
 
 
97
    if (pool->alloc_used + amount <= pool->pagesize) {
 
98
      void *result = pool->alloc_block + pool->alloc_used;
 
99
      pool->alloc_used += amount;
 
100
      return result;
 
101
    }
 
102
  }
 
103
 
 
104
  if (pool->next_page >= pool->pages.num_blocks) {
 
105
    pool->alloc_block = calloc(1, pool->pagesize);
 
106
    if (pool->alloc_block == NULL) {
 
107
      return NULL;
 
108
    }
 
109
    if (record_pool_block(&pool->pages, pool->alloc_block) != 0) {
 
110
      return NULL;
 
111
    }
 
112
    pool->next_page = pool->pages.num_blocks;
 
113
  } else {
 
114
    pool->alloc_block = pool->pages.blocklist[pool->next_page];
 
115
    pool->next_page++;
 
116
  }
 
117
 
 
118
  pool->alloc_used = amount;
 
119
 
 
120
  return pool->alloc_block;
 
121
}
 
122
 
 
123
void amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, amqp_bytes_t *output) {
 
124
  output->len = amount;
 
125
  output->bytes = amqp_pool_alloc(pool, amount);
 
126
}
 
127
 
 
128
amqp_bytes_t amqp_cstring_bytes(char const *cstr) {
 
129
  amqp_bytes_t result;
 
130
  result.len = strlen(cstr);
 
131
  result.bytes = (void *) cstr;
 
132
  return result;
 
133
}
 
134
 
 
135
amqp_bytes_t amqp_bytes_malloc_dup(amqp_bytes_t src) {
 
136
  amqp_bytes_t result;
 
137
  result.len = src.len;
 
138
  result.bytes = malloc(src.len);
 
139
  if (result.bytes != NULL) {
 
140
    memcpy(result.bytes, src.bytes, src.len);
 
141
  }
 
142
  return result;
 
143
}