[Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.7,1.8

Fred L. Drake fdrake@users.sourceforge.net
2001年10月29日 12:45:59 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv8984/Modules
Modified Files:
	_hotshot.c 
Log Message:
Make the low-level log-reader object export a dictionary mapping keys
to lists of values, giving the contents of all the ADD_INFO records
seen so far. This is initialized agressively when the log file is
opened, so that whoever is looking at the log reader can always see
the initial data loaded into the data stream. ADD_INFO events later
in the log file continue to be reported to the application layer as
before.
Add a new method, addinfo(), to the profiler. This can be used to
insert additional ADD_INFO records into the profiler log.
Fix the tp_flags and tp_name slots on the type objects.
Index: _hotshot.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** _hotshot.c	2001年10月23日 22:26:16	1.7
--- _hotshot.c	2001年10月29日 20:45:57	1.8
***************
*** 83,86 ****
--- 83,87 ----
 typedef struct {
 PyObject_HEAD
+ PyObject *info;
 FILE *logfp;
 int filled;
***************
*** 258,261 ****
--- 259,263 ----
 #define ERR_EOF -1
 #define ERR_EXCEPTION -2
+ #define ERR_BAD_RECTYPE -3
 
 #define PISIZE (sizeof(int) + 1)
***************
*** 327,330 ****
--- 329,399 ----
 
 
+ static int
+ unpack_add_info(LogReaderObject *self, int skip_opcode)
+ {
+ PyObject *key;
+ PyObject *value = NULL;
+ int err;
+ 
+ if (skip_opcode) {
+ if (self->buffer[self->index] != WHAT_ADD_INFO)
+ return ERR_BAD_RECTYPE;
+ self->index++;
+ }
+ err = unpack_string(self, &key);
+ if (!err) {
+ err = unpack_string(self, &value);
+ if (err)
+ Py_DECREF(key);
+ else {
+ PyObject *list = PyDict_GetItem(self->info, key);
+ if (list == NULL) {
+ list = PyList_New(0);
+ if (list == NULL) {
+ err = ERR_EXCEPTION;
+ goto finally;
+ }
+ if (PyDict_SetItem(self->info, key, list)) {
+ err = ERR_EXCEPTION;
+ goto finally;
+ }
+ }
+ if (PyList_Append(list, value))
+ err = ERR_EXCEPTION;
+ }
+ }
+ finally:
+ Py_XDECREF(key);
+ Py_XDECREF(value);
+ return err;
+ }
+ 
+ 
+ static void
+ logreader_refill(LogReaderObject *self)
+ {
+ int needed;
+ size_t res;
+ 
+ if (self->index) {
+ memmove(self->buffer, &self->buffer[self->index],
+ self->filled - self->index);
+ self->filled = self->filled - self->index;
+ self->index = 0;
+ }
+ needed = BUFFERSIZE - self->filled;
+ if (needed > 0) {
+ res = fread(&self->buffer[self->filled], 1, needed, self->logfp);
+ self->filled += res;
+ }
+ }
+ 
+ static void
+ eof_error(void)
+ {
+ PyErr_SetString(PyExc_EOFError,
+ "end of file with incomplete profile record");
+ }
+ 
 static PyObject *
 logreader_tp_iternext(LogReaderObject *self)
***************
*** 347,365 ****
 }
 restart:
! if ((self->filled - self->index) < MAXEVENTSIZE) {
! /* add a little to the buffer */
! int needed;
! size_t res;
! refill:
! if (self->index) {
! memmove(self->buffer, &self->buffer[self->index],
! self->filled - self->index);
! self->filled = self->filled - self->index;
! self->index = 0;
! }
! needed = BUFFERSIZE - self->filled;
! res = fread(&self->buffer[self->filled], 1, needed, self->logfp);
! self->filled += res;
! }
 /* end of input */
 if (self->filled == 0)
--- 416,422 ----
 }
 restart:
! if ((self->filled - self->index) < MAXEVENTSIZE)
! logreader_refill(self);
! 
 /* end of input */
 if (self->filled == 0)
***************
*** 392,403 ****
 break;
 case WHAT_ADD_INFO:
! err = unpack_string(self, &s1);
! if (!err) {
! err = unpack_string(self, &s2);
! if (err) {
! Py_DECREF(s1);
! s1 = NULL;
! }
! }
 break;
 case WHAT_DEFINE_FILE:
--- 449,453 ----
 break;
 case WHAT_ADD_INFO:
! err = unpack_add_info(self, 0);
 break;
 case WHAT_DEFINE_FILE:
***************
*** 427,430 ****
--- 477,481 ----
 goto restart;
 }
+ break;
 case WHAT_FRAME_TIMES:
 if (self->index >= self->filled)
***************
*** 435,440 ****
 goto restart;
 }
 default:
! 	;
 }
 if (err == ERR_EOF && oldindex != 0) {
--- 486,492 ----
 goto restart;
 }
+ break;
 default:
! err = ERR_BAD_RECTYPE;
 }
 if (err == ERR_EOF && oldindex != 0) {
***************
*** 444,453 ****
 */
 err = ERR_NONE;
! goto refill;
 }
! if (err == ERR_EOF) {
 /* Could not avoid end-of-buffer error. */
! PyErr_SetString(PyExc_EOFError,
! "end of file with incomplete profile record");
 }
 else if (!err) {
--- 496,508 ----
 */
 err = ERR_NONE;
! logreader_refill(self);
 }
! if (err == ERR_BAD_RECTYPE) {
! PyErr_SetString(PyExc_ValueError,
! "unknown record type in log file");
! }
! else if (err == ERR_EOF) {
 /* Could not avoid end-of-buffer error. */
! eof_error();
 }
 else if (!err) {
***************
*** 974,977 ****
--- 1029,1054 ----
 /* Profiler object interface methods. */
 
+ static char addinfo__doc__[] =
+ "addinfo(key, value)\n"
+ "Insert an ADD_INFO record into the log.";
+ 
+ static PyObject *
+ profiler_addinfo(ProfilerObject *self, PyObject *args)
+ {
+ PyObject *result = NULL;
+ char *key, *value;
+ 
+ if (PyArg_ParseTuple(args, "ss:addinfo", &key, &value)) {
+ if (self->logfp == NULL)
+ PyErr_SetString(ProfilerError, "profiler already closed");
+ else {
+ pack_add_info(self, key, value);
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ }
+ return result;
+ }
+ 
 static char close__doc__[] =
 "close()\n"
***************
*** 1110,1113 ****
--- 1187,1191 ----
 */
 static PyMethodDef profiler_methods[] = {
+ {"addinfo", (PyCFunction)profiler_addinfo, METH_VARARGS, addinfo__doc__},
 {"close", (PyCFunction)profiler_close, METH_VARARGS, close__doc__},
 {"runcall", (PyCFunction)profiler_runcall, METH_VARARGS, runcall__doc__},
***************
*** 1169,1173 ****
 PyObject_HEAD_INIT(NULL)
 0,					/* ob_size		*/
! "HotShot-profiler",			/* tp_name		*/
 (int) sizeof(ProfilerObject),	/* tp_basicsize		*/
 0,					/* tp_itemsize		*/
--- 1247,1251 ----
 PyObject_HEAD_INIT(NULL)
 0,					/* ob_size		*/
! "_hotshot.ProfilerType",		/* tp_name		*/
 (int) sizeof(ProfilerObject),	/* tp_basicsize		*/
 0,					/* tp_itemsize		*/
***************
*** 1187,1191 ****
 0,					/* tp_setattro		*/
 0,					/* tp_as_buffer		*/
! 0,					/* tp_flags		*/
 profiler_object__doc__,		/* tp_doc		*/
 };
--- 1265,1269 ----
 0,					/* tp_setattro		*/
 0,					/* tp_as_buffer		*/
! Py_TPFLAGS_DEFAULT,			/* tp_flags		*/
 profiler_object__doc__,		/* tp_doc		*/
 };
***************
*** 1201,1206 ****
 
 static PyObject *
! logreader_getattr(ProfilerObject *self, char *name)
 {
 return Py_FindMethod(logreader_methods, (PyObject *)self, name);
 }
--- 1279,1288 ----
 
 static PyObject *
! logreader_getattr(LogReaderObject *self, char *name)
 {
+ if (strcmp(name, "info") == 0) {
+ Py_INCREF(self->info);
+ return self->info;
+ }
 return Py_FindMethod(logreader_methods, (PyObject *)self, name);
 }
***************
*** 1227,1231 ****
 PyObject_HEAD_INIT(NULL)
 0,					/* ob_size		*/
! "HotShot-logreader",		/* tp_name		*/
 (int) sizeof(LogReaderObject),	/* tp_basicsize		*/
 0,					/* tp_itemsize		*/
--- 1309,1313 ----
 PyObject_HEAD_INIT(NULL)
 0,					/* ob_size		*/
! "_hotshot.LogReaderType",		/* tp_name		*/
 (int) sizeof(LogReaderObject),	/* tp_basicsize		*/
 0,					/* tp_itemsize		*/
***************
*** 1245,1249 ****
 0,					/* tp_setattro		*/
 0,					/* tp_as_buffer		*/
! 0,					/* tp_flags		*/
 logreader__doc__,			/* tp_doc		*/
 #if Py_TPFLAGS_HAVE_ITER
--- 1327,1331 ----
 0,					/* tp_setattro		*/
 0,					/* tp_as_buffer		*/
! Py_TPFLAGS_DEFAULT,			/* tp_flags		*/
 logreader__doc__,			/* tp_doc		*/
 #if Py_TPFLAGS_HAVE_ITER
***************
*** 1270,1273 ****
--- 1352,1356 ----
 self->frametimings = 1;
 self->linetimings = 0;
+ self->info = NULL;
 self->logfp = fopen(filename, "rb");
 if (self->logfp == NULL) {
***************
*** 1275,1281 ****
--- 1358,1394 ----
 Py_DECREF(self);
 self = NULL;
+ goto finally;
+ }
+ self->info = PyDict_New();
+ if (self->info == NULL) {
+ Py_DECREF(self);
+ goto finally;
+ }
+ /* Aggressively attempt to load all preliminary ADD_INFO
+ * records from the log so the info records are available
+ * from a fresh logreader object.
+ */
+ logreader_refill(self);
+ while (self->filled > self->index
+ && self->buffer[self->index] == WHAT_ADD_INFO) {
+ int err = unpack_add_info(self, 1);
+ if (err) {
+ if (err == ERR_EOF)
+ eof_error();
+ else
+ PyErr_SetString(PyExc_RuntimeError,
+ "unexpected error");
+ break;
+ }
+ /* Refill agressively so we can avoid EOF during
+ * initialization unless there's a real EOF condition
+ * (the tp_iternext handler loops attempts to refill
+ * and try again).
+ */
+ logreader_refill(self);
 }
 }
 }
+ finally:
 return (PyObject *) self;
 }
***************
*** 1323,1350 ****
 return -1;
 }
! pack_add_info(self, "HotShot-Version", buffer);
! pack_add_info(self, "Requested-Line-Events",
 (self->lineevents ? "yes" : "no"));
! pack_add_info(self, "Platform", Py_GetPlatform());
! pack_add_info(self, "Executable", Py_GetProgramFullPath());
 buffer = (char *) Py_GetVersion();
 if (buffer == NULL)
 PyErr_Clear();
 else
! pack_add_info(self, "Executable-Version", buffer);
 
 #ifdef MS_WIN32
 sprintf(cwdbuffer, "%I64d", frequency.QuadPart);
! pack_add_info(self, "Reported-Performance-Frequency", cwdbuffer);
 #else
 sprintf(cwdbuffer, "%lu", rusage_diff);
! pack_add_info(self, "Observed-Interval-getrusage", cwdbuffer);
 sprintf(cwdbuffer, "%lu", timeofday_diff);
! pack_add_info(self, "Observed-Interval-gettimeofday", cwdbuffer);
 #endif
- pack_frame_times(self);
- pack_line_times(self);
 
! pack_add_info(self, "Current-Directory",
 getcwd(cwdbuffer, sizeof cwdbuffer));
 
--- 1436,1465 ----
 return -1;
 }
! pack_add_info(self, "hotshot-version", buffer);
! pack_add_info(self, "requested-frame-timings",
! (self->frametimings ? "yes" : "no"));
! pack_add_info(self, "requested-line-events",
 (self->lineevents ? "yes" : "no"));
! pack_add_info(self, "requested-line-timings",
! (self->linetimings ? "yes" : "no"));
! pack_add_info(self, "platform", Py_GetPlatform());
! pack_add_info(self, "executable", Py_GetProgramFullPath());
 buffer = (char *) Py_GetVersion();
 if (buffer == NULL)
 PyErr_Clear();
 else
! pack_add_info(self, "executable-version", buffer);
 
 #ifdef MS_WIN32
 sprintf(cwdbuffer, "%I64d", frequency.QuadPart);
! pack_add_info(self, "reported-performance-frequency", cwdbuffer);
 #else
 sprintf(cwdbuffer, "%lu", rusage_diff);
! pack_add_info(self, "observed-interval-getrusage", cwdbuffer);
 sprintf(cwdbuffer, "%lu", timeofday_diff);
! pack_add_info(self, "observed-interval-gettimeofday", cwdbuffer);
 #endif
 
! pack_add_info(self, "current-directory",
 getcwd(cwdbuffer, sizeof cwdbuffer));
 
***************
*** 1356,1361 ****
 if (buffer == NULL)
 return -1;
! pack_add_info(self, "Sys-Path-Entry", buffer);
 }
 return 0;
 }
--- 1471,1479 ----
 if (buffer == NULL)
 return -1;
! pack_add_info(self, "sys-path-entry", buffer);
 }
+ pack_frame_times(self);
+ pack_line_times(self);
+ 
 return 0;
 }

AltStyle によって変換されたページ (->オリジナル) /