Return to ngx_palloc.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / nginx / src / core |
1.1 ! misho 1: ! 2: /* ! 3: * Copyright (C) Igor Sysoev ! 4: * Copyright (C) Nginx, Inc. ! 5: */ ! 6: ! 7: ! 8: #include <ngx_config.h> ! 9: #include <ngx_core.h> ! 10: ! 11: ! 12: static void *ngx_palloc_block(ngx_pool_t *pool, size_t size); ! 13: static void *ngx_palloc_large(ngx_pool_t *pool, size_t size); ! 14: ! 15: ! 16: ngx_pool_t * ! 17: ngx_create_pool(size_t size, ngx_log_t *log) ! 18: { ! 19: ngx_pool_t *p; ! 20: ! 21: p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log); ! 22: if (p == NULL) { ! 23: return NULL; ! 24: } ! 25: ! 26: p->d.last = (u_char *) p + sizeof(ngx_pool_t); ! 27: p->d.end = (u_char *) p + size; ! 28: p->d.next = NULL; ! 29: p->d.failed = 0; ! 30: ! 31: size = size - sizeof(ngx_pool_t); ! 32: p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL; ! 33: ! 34: p->current = p; ! 35: p->chain = NULL; ! 36: p->large = NULL; ! 37: p->cleanup = NULL; ! 38: p->log = log; ! 39: ! 40: return p; ! 41: } ! 42: ! 43: ! 44: void ! 45: ngx_destroy_pool(ngx_pool_t *pool) ! 46: { ! 47: ngx_pool_t *p, *n; ! 48: ngx_pool_large_t *l; ! 49: ngx_pool_cleanup_t *c; ! 50: ! 51: for (c = pool->cleanup; c; c = c->next) { ! 52: if (c->handler) { ! 53: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, ! 54: "run cleanup: %p", c); ! 55: c->handler(c->data); ! 56: } ! 57: } ! 58: ! 59: for (l = pool->large; l; l = l->next) { ! 60: ! 61: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); ! 62: ! 63: if (l->alloc) { ! 64: ngx_free(l->alloc); ! 65: } ! 66: } ! 67: ! 68: #if (NGX_DEBUG) ! 69: ! 70: /* ! 71: * we could allocate the pool->log from this pool ! 72: * so we cannot use this log while free()ing the pool ! 73: */ ! 74: ! 75: for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { ! 76: ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0, ! 77: "free: %p, unused: %uz", p, p->d.end - p->d.last); ! 78: ! 79: if (n == NULL) { ! 80: break; ! 81: } ! 82: } ! 83: ! 84: #endif ! 85: ! 86: for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { ! 87: ngx_free(p); ! 88: ! 89: if (n == NULL) { ! 90: break; ! 91: } ! 92: } ! 93: } ! 94: ! 95: ! 96: void ! 97: ngx_reset_pool(ngx_pool_t *pool) ! 98: { ! 99: ngx_pool_t *p; ! 100: ngx_pool_large_t *l; ! 101: ! 102: for (l = pool->large; l; l = l->next) { ! 103: if (l->alloc) { ! 104: ngx_free(l->alloc); ! 105: } ! 106: } ! 107: ! 108: pool->large = NULL; ! 109: ! 110: for (p = pool; p; p = p->d.next) { ! 111: p->d.last = (u_char *) p + sizeof(ngx_pool_t); ! 112: } ! 113: } ! 114: ! 115: ! 116: void * ! 117: ngx_palloc(ngx_pool_t *pool, size_t size) ! 118: { ! 119: u_char *m; ! 120: ngx_pool_t *p; ! 121: ! 122: if (size <= pool->max) { ! 123: ! 124: p = pool->current; ! 125: ! 126: do { ! 127: m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT); ! 128: ! 129: if ((size_t) (p->d.end - m) >= size) { ! 130: p->d.last = m + size; ! 131: ! 132: return m; ! 133: } ! 134: ! 135: p = p->d.next; ! 136: ! 137: } while (p); ! 138: ! 139: return ngx_palloc_block(pool, size); ! 140: } ! 141: ! 142: return ngx_palloc_large(pool, size); ! 143: } ! 144: ! 145: ! 146: void * ! 147: ngx_pnalloc(ngx_pool_t *pool, size_t size) ! 148: { ! 149: u_char *m; ! 150: ngx_pool_t *p; ! 151: ! 152: if (size <= pool->max) { ! 153: ! 154: p = pool->current; ! 155: ! 156: do { ! 157: m = p->d.last; ! 158: ! 159: if ((size_t) (p->d.end - m) >= size) { ! 160: p->d.last = m + size; ! 161: ! 162: return m; ! 163: } ! 164: ! 165: p = p->d.next; ! 166: ! 167: } while (p); ! 168: ! 169: return ngx_palloc_block(pool, size); ! 170: } ! 171: ! 172: return ngx_palloc_large(pool, size); ! 173: } ! 174: ! 175: ! 176: static void * ! 177: ngx_palloc_block(ngx_pool_t *pool, size_t size) ! 178: { ! 179: u_char *m; ! 180: size_t psize; ! 181: ngx_pool_t *p, *new, *current; ! 182: ! 183: psize = (size_t) (pool->d.end - (u_char *) pool); ! 184: ! 185: m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log); ! 186: if (m == NULL) { ! 187: return NULL; ! 188: } ! 189: ! 190: new = (ngx_pool_t *) m; ! 191: ! 192: new->d.end = m + psize; ! 193: new->d.next = NULL; ! 194: new->d.failed = 0; ! 195: ! 196: m += sizeof(ngx_pool_data_t); ! 197: m = ngx_align_ptr(m, NGX_ALIGNMENT); ! 198: new->d.last = m + size; ! 199: ! 200: current = pool->current; ! 201: ! 202: for (p = current; p->d.next; p = p->d.next) { ! 203: if (p->d.failed++ > 4) { ! 204: current = p->d.next; ! 205: } ! 206: } ! 207: ! 208: p->d.next = new; ! 209: ! 210: pool->current = current ? current : new; ! 211: ! 212: return m; ! 213: } ! 214: ! 215: ! 216: static void * ! 217: ngx_palloc_large(ngx_pool_t *pool, size_t size) ! 218: { ! 219: void *p; ! 220: ngx_uint_t n; ! 221: ngx_pool_large_t *large; ! 222: ! 223: p = ngx_alloc(size, pool->log); ! 224: if (p == NULL) { ! 225: return NULL; ! 226: } ! 227: ! 228: n = 0; ! 229: ! 230: for (large = pool->large; large; large = large->next) { ! 231: if (large->alloc == NULL) { ! 232: large->alloc = p; ! 233: return p; ! 234: } ! 235: ! 236: if (n++ > 3) { ! 237: break; ! 238: } ! 239: } ! 240: ! 241: large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); ! 242: if (large == NULL) { ! 243: ngx_free(p); ! 244: return NULL; ! 245: } ! 246: ! 247: large->alloc = p; ! 248: large->next = pool->large; ! 249: pool->large = large; ! 250: ! 251: return p; ! 252: } ! 253: ! 254: ! 255: void * ! 256: ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment) ! 257: { ! 258: void *p; ! 259: ngx_pool_large_t *large; ! 260: ! 261: p = ngx_memalign(alignment, size, pool->log); ! 262: if (p == NULL) { ! 263: return NULL; ! 264: } ! 265: ! 266: large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); ! 267: if (large == NULL) { ! 268: ngx_free(p); ! 269: return NULL; ! 270: } ! 271: ! 272: large->alloc = p; ! 273: large->next = pool->large; ! 274: pool->large = large; ! 275: ! 276: return p; ! 277: } ! 278: ! 279: ! 280: ngx_int_t ! 281: ngx_pfree(ngx_pool_t *pool, void *p) ! 282: { ! 283: ngx_pool_large_t *l; ! 284: ! 285: for (l = pool->large; l; l = l->next) { ! 286: if (p == l->alloc) { ! 287: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, ! 288: "free: %p", l->alloc); ! 289: ngx_free(l->alloc); ! 290: l->alloc = NULL; ! 291: ! 292: return NGX_OK; ! 293: } ! 294: } ! 295: ! 296: return NGX_DECLINED; ! 297: } ! 298: ! 299: ! 300: void * ! 301: ngx_pcalloc(ngx_pool_t *pool, size_t size) ! 302: { ! 303: void *p; ! 304: ! 305: p = ngx_palloc(pool, size); ! 306: if (p) { ! 307: ngx_memzero(p, size); ! 308: } ! 309: ! 310: return p; ! 311: } ! 312: ! 313: ! 314: ngx_pool_cleanup_t * ! 315: ngx_pool_cleanup_add(ngx_pool_t *p, size_t size) ! 316: { ! 317: ngx_pool_cleanup_t *c; ! 318: ! 319: c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t)); ! 320: if (c == NULL) { ! 321: return NULL; ! 322: } ! 323: ! 324: if (size) { ! 325: c->data = ngx_palloc(p, size); ! 326: if (c->data == NULL) { ! 327: return NULL; ! 328: } ! 329: ! 330: } else { ! 331: c->data = NULL; ! 332: } ! 333: ! 334: c->handler = NULL; ! 335: c->next = p->cleanup; ! 336: ! 337: p->cleanup = c; ! 338: ! 339: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c); ! 340: ! 341: return c; ! 342: } ! 343: ! 344: ! 345: void ! 346: ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd) ! 347: { ! 348: ngx_pool_cleanup_t *c; ! 349: ngx_pool_cleanup_file_t *cf; ! 350: ! 351: for (c = p->cleanup; c; c = c->next) { ! 352: if (c->handler == ngx_pool_cleanup_file) { ! 353: ! 354: cf = c->data; ! 355: ! 356: if (cf->fd == fd) { ! 357: c->handler(cf); ! 358: c->handler = NULL; ! 359: return; ! 360: } ! 361: } ! 362: } ! 363: } ! 364: ! 365: ! 366: void ! 367: ngx_pool_cleanup_file(void *data) ! 368: { ! 369: ngx_pool_cleanup_file_t *c = data; ! 370: ! 371: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d", ! 372: c->fd); ! 373: ! 374: if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ! 375: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ! 376: ngx_close_file_n " \"%s\" failed", c->name); ! 377: } ! 378: } ! 379: ! 380: ! 381: void ! 382: ngx_pool_delete_file(void *data) ! 383: { ! 384: ngx_pool_cleanup_file_t *c = data; ! 385: ! 386: ngx_err_t err; ! 387: ! 388: ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s", ! 389: c->fd, c->name); ! 390: ! 391: if (ngx_delete_file(c->name) == NGX_FILE_ERROR) { ! 392: err = ngx_errno; ! 393: ! 394: if (err != NGX_ENOENT) { ! 395: ngx_log_error(NGX_LOG_CRIT, c->log, err, ! 396: ngx_delete_file_n " \"%s\" failed", c->name); ! 397: } ! 398: } ! 399: ! 400: if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ! 401: ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ! 402: ngx_close_file_n " \"%s\" failed", c->name); ! 403: } ! 404: } ! 405: ! 406: ! 407: #if 0 ! 408: ! 409: static void * ! 410: ngx_get_cached_block(size_t size) ! 411: { ! 412: void *p; ! 413: ngx_cached_block_slot_t *slot; ! 414: ! 415: if (ngx_cycle->cache == NULL) { ! 416: return NULL; ! 417: } ! 418: ! 419: slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize]; ! 420: ! 421: slot->tries++; ! 422: ! 423: if (slot->number) { ! 424: p = slot->block; ! 425: slot->block = slot->block->next; ! 426: slot->number--; ! 427: return p; ! 428: } ! 429: ! 430: return NULL; ! 431: } ! 432: ! 433: #endif