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 }