Mercurial > cpython-lru_cache-weakref
comparison Objects/floatobject.c @ 10374:48141da518df legacy-trunk
Patch by Vladimir Marangoz to allow freeing of the allocated blocks of
floats on finalization.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Wed, 10 Mar 1999 22:55:47 +0000 |
| parents | 25505e563b37 |
| children | 417aa425013a |
comparison
equal
deleted
inserted
replaced
| 10373:07ee795774d8 | 10374:48141da518df |
|---|---|
| 93 }; | 93 }; |
| 94 #endif | 94 #endif |
| 95 | 95 |
| 96 /* Special free list -- see comments for same code in intobject.c. */ | 96 /* Special free list -- see comments for same code in intobject.c. */ |
| 97 static PyFloatObject *free_list = NULL; | 97 static PyFloatObject *free_list = NULL; |
| 98 static PyFloatObject *block_list = NULL; | |
| 98 #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ | 99 #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ |
| 99 #define N_FLOATOBJECTS (BLOCK_SIZE / sizeof(PyFloatObject)) | 100 #define N_FLOATOBJECTS ((BLOCK_SIZE - sizeof(PyFloatObject *)) / \ |
| 101 sizeof(PyFloatObject)) | |
| 102 #define PyMem_MALLOC malloc | |
| 103 #define PyMem_FREE free | |
| 100 | 104 |
| 101 static PyFloatObject * | 105 static PyFloatObject * |
| 102 fill_free_list() | 106 fill_free_list() |
| 103 { | 107 { |
| 104 PyFloatObject *p, *q; | 108 PyFloatObject *p, *q; |
| 105 p = PyMem_NEW(PyFloatObject, N_FLOATOBJECTS); | 109 p = (PyFloatObject *)PyMem_MALLOC(BLOCK_SIZE); |
| 106 if (p == NULL) | 110 if (p == NULL) |
| 107 return (PyFloatObject *)PyErr_NoMemory(); | 111 return (PyFloatObject *)PyErr_NoMemory(); |
| 112 *(PyFloatObject **)p = block_list; | |
| 113 block_list = p; | |
| 114 p = (PyFloatObject *)((char *)p + sizeof(PyFloatObject *)); | |
| 108 q = p + N_FLOATOBJECTS; | 115 q = p + N_FLOATOBJECTS; |
| 109 while (--q > p) | 116 while (--q > p) |
| 110 *(PyFloatObject **)q = q-1; | 117 q->ob_type = (struct _typeobject *)(q-1); |
| 111 *(PyFloatObject **)q = NULL; | 118 q->ob_type = NULL; |
| 112 return p + N_FLOATOBJECTS - 1; | 119 return p + N_FLOATOBJECTS - 1; |
| 113 } | 120 } |
| 114 | 121 |
| 115 PyObject * | 122 PyObject * |
| 116 #ifdef __SC__ | 123 #ifdef __SC__ |
| 124 if (free_list == NULL) { | 131 if (free_list == NULL) { |
| 125 if ((free_list = fill_free_list()) == NULL) | 132 if ((free_list = fill_free_list()) == NULL) |
| 126 return NULL; | 133 return NULL; |
| 127 } | 134 } |
| 128 op = free_list; | 135 op = free_list; |
| 129 free_list = *(PyFloatObject **)free_list; | 136 free_list = (PyFloatObject *)op->ob_type; |
| 130 op->ob_type = &PyFloat_Type; | 137 op->ob_type = &PyFloat_Type; |
| 131 op->ob_fval = fval; | 138 op->ob_fval = fval; |
| 132 _Py_NewReference(op); | 139 _Py_NewReference(op); |
| 133 return (PyObject *) op; | 140 return (PyObject *) op; |
| 134 } | 141 } |
| 135 | 142 |
| 136 static void | 143 static void |
| 137 float_dealloc(op) | 144 float_dealloc(op) |
| 138 PyFloatObject *op; | 145 PyFloatObject *op; |
| 139 { | 146 { |
| 140 *(PyFloatObject **)op = free_list; | 147 op->ob_type = (struct _typeobject *)free_list; |
| 141 free_list = op; | 148 free_list = op; |
| 142 } | 149 } |
| 143 | 150 |
| 144 double | 151 double |
| 145 PyFloat_AsDouble(op) | 152 PyFloat_AsDouble(op) |
| 602 }; | 609 }; |
| 603 | 610 |
| 604 void | 611 void |
| 605 PyFloat_Fini() | 612 PyFloat_Fini() |
| 606 { | 613 { |
| 607 /* XXX Alas, the free list is not easily and safely freeable */ | 614 PyFloatObject *p, *list; |
| 608 } | 615 int i; |
| 616 int bc, bf; /* block count, number of freed blocks */ | |
| 617 int frem, fsum; /* remaining unfreed floats per block, total */ | |
| 618 | |
| 619 bc = 0; | |
| 620 bf = 0; | |
| 621 fsum = 0; | |
| 622 list = block_list; | |
| 623 block_list = NULL; | |
| 624 while (list != NULL) { | |
| 625 p = list; | |
| 626 p = (PyFloatObject *)((char *)p + sizeof(PyFloatObject *)); | |
| 627 bc++; | |
| 628 frem = 0; | |
| 629 for (i = 0; i < N_FLOATOBJECTS; i++, p++) { | |
| 630 if (PyFloat_Check(p) && p->ob_refcnt != 0) | |
| 631 frem++; | |
| 632 } | |
| 633 p = list; | |
| 634 list = *(PyFloatObject **)p; | |
| 635 if (frem) { | |
| 636 *(PyFloatObject **)p = block_list; | |
| 637 block_list = p; | |
| 638 } | |
| 639 else { | |
| 640 PyMem_FREE(p); | |
| 641 bf++; | |
| 642 } | |
| 643 fsum += frem; | |
| 644 } | |
| 645 if (Py_VerboseFlag) { | |
| 646 fprintf(stderr, "# cleanup floats"); | |
| 647 if (!fsum) { | |
| 648 fprintf(stderr, "\n"); | |
| 649 } | |
| 650 else { | |
| 651 fprintf(stderr, | |
| 652 ": %d unfreed float%s in %d out of %d block%s\n", | |
| 653 fsum, fsum == 1 ? "" : "s", | |
| 654 bc - bf, bc, bc == 1 ? "" : "s"); | |
| 655 } | |
| 656 } | |
| 657 } |
