tmempool.c 3.5 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
Shengliang Guan 已提交
16
#include "os.h"
S
Shengliang Guan 已提交
17
#include "ulog.h"
H
hzcheng 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#include "tmempool.h"
#include "tutil.h"

typedef struct {
  int             numOfFree;  /* number of free slots */
  int             first;      /* the first free slot  */
  int             numOfBlock; /* the number of blocks */
  int             blockSize;  /* block size in bytes  */
  int *           freeList;   /* the index list       */
  char *          pool;       /* the actual mem block */
  pthread_mutex_t mutex;
} pool_t;

mpool_h taosMemPoolInit(int numOfBlock, int blockSize) {
  int     i;
  pool_t *pool_p;

  if (numOfBlock <= 1 || blockSize <= 1) {
S
slguan 已提交
36
    uError("invalid parameter in memPoolInit\n");
H
hzcheng 已提交
37 38 39 40 41
    return NULL;
  }

  pool_p = (pool_t *)malloc(sizeof(pool_t));
  if (pool_p == NULL) {
S
slguan 已提交
42
    uError("mempool malloc failed\n");
H
hzcheng 已提交
43 44 45 46 47 48 49 50 51 52 53
    return NULL;
  } else {
    memset(pool_p, 0, sizeof(pool_t));
  }

  pool_p->blockSize = blockSize;
  pool_p->numOfBlock = numOfBlock;
  pool_p->pool = (char *)malloc((size_t)(blockSize * numOfBlock));
  pool_p->freeList = (int *)malloc(sizeof(int) * (size_t)numOfBlock);

  if (pool_p->pool == NULL || pool_p->freeList == NULL) {
S
slguan 已提交
54
    uError("failed to allocate memory\n");
S
TD-1848  
Shengliang Guan 已提交
55 56 57
    tfree(pool_p->freeList);
    tfree(pool_p->pool);
    tfree(pool_p);
H
hzcheng 已提交
58 59 60 61 62
    return NULL;
  }

  pthread_mutex_init(&(pool_p->mutex), NULL);

weixin_48148422's avatar
weixin_48148422 已提交
63
  memset(pool_p->pool, 0, (size_t)(blockSize * numOfBlock));
H
hzcheng 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77
  for (i = 0; i < pool_p->numOfBlock; ++i) pool_p->freeList[i] = i;

  pool_p->first = 0;
  pool_p->numOfFree = pool_p->numOfBlock;

  return (mpool_h)pool_p;
}

char *taosMemPoolMalloc(mpool_h handle) {
  char *  pos = NULL;
  pool_t *pool_p = (pool_t *)handle;

  pthread_mutex_lock(&(pool_p->mutex));

weixin_48148422's avatar
weixin_48148422 已提交
78
  if (pool_p->numOfFree > 0) {
H
hzcheng 已提交
79 80 81 82 83 84 85
    pos = pool_p->pool + pool_p->blockSize * (pool_p->freeList[pool_p->first]);
    pool_p->first++;
    pool_p->first = pool_p->first % pool_p->numOfBlock;
    pool_p->numOfFree--;
  }

  pthread_mutex_unlock(&(pool_p->mutex));
weixin_48148422's avatar
weixin_48148422 已提交
86

87
  if (pos == NULL) uDebug("mempool: out of memory");
H
hzcheng 已提交
88 89 90 91 92 93 94 95 96 97 98
  return pos;
}

void taosMemPoolFree(mpool_h handle, char *pMem) {
  int     index;
  pool_t *pool_p = (pool_t *)handle;

  if (pMem == NULL) return;

  index = (int)(pMem - pool_p->pool) % pool_p->blockSize;
  if (index != 0) {
S
slguan 已提交
99
    uError("invalid free address:%p\n", pMem);
weixin_48148422's avatar
weixin_48148422 已提交
100
    return;
H
hzcheng 已提交
101 102
  }

weixin_48148422's avatar
weixin_48148422 已提交
103 104
  index = (int)((pMem - pool_p->pool) / pool_p->blockSize);
  if (index < 0 || index >= pool_p->numOfBlock) {
S
slguan 已提交
105
    uError("mempool: error, invalid address:%p\n", pMem);
weixin_48148422's avatar
weixin_48148422 已提交
106 107 108 109 110 111 112 113 114 115
    return;
  }

  memset(pMem, 0, (size_t)pool_p->blockSize);

  pthread_mutex_lock(&pool_p->mutex);

  pool_p->freeList[(pool_p->first + pool_p->numOfFree) % pool_p->numOfBlock] = index;
  pool_p->numOfFree++;

H
hzcheng 已提交
116 117 118 119 120 121 122 123 124
  pthread_mutex_unlock(&pool_p->mutex);
}

void taosMemPoolCleanUp(mpool_h handle) {
  pool_t *pool_p = (pool_t *)handle;

  pthread_mutex_destroy(&pool_p->mutex);
  if (pool_p->pool) free(pool_p->pool);
  if (pool_p->freeList) free(pool_p->freeList);
weixin_48148422's avatar
weixin_48148422 已提交
125
  memset(pool_p, 0, sizeof(*pool_p));
H
hzcheng 已提交
126 127
  free(pool_p);
}