Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | fix check event source threshold (corresponds 100-ns ranges, if the wide-clicks supported); because of variable width of 1 wide-click: windows - frequency dependent, unix - nanoseconds, darwin/osx - tb.numer / tb.denom nanoseconds. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | sebres-8-5-event-perf-branch |
Files: | files | file ages | folders |
SHA1: |
68ebe50d7b4b7e36fdad3933d2bc6359 |
User & Date: | sebres 2017-07-03 13:32:15 |
Context
2017-07-03
| ||
13:32 | code review and small optimizations check-in: 3fc8da2b5f user: sebres tags: sebres-8-5-event-perf-branch | |
13:32 | fix check event source threshold (corresponds 100-ns ranges, if the wide-clicks supported); because... check-in: 68ebe50d7b user: sebres tags: sebres-8-5-event-perf-branch | |
13:32 | unix: implements wide-clicks on unix (1 wide-click == 0.001 microseconds (1 nanosecond)), so more pr... check-in: 701d66ce66 user: sebres tags: sebres-8-5-event-perf-branch | |
Changes
Changes to generic/tclNotify.c.
︙ | ︙ | |||
29 30 31 32 33 34 35 | Tcl_EventCheckProc *checkProc; ClientData clientData; struct EventSource *nextPtr; } EventSource; /* * Used for performance purposes, threshold to bypass check source (if don't wait) | | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | Tcl_EventCheckProc *checkProc; ClientData clientData; struct EventSource *nextPtr; } EventSource; /* * Used for performance purposes, threshold to bypass check source (if don't wait) * Value should be approximately correspond 100-ns ranges, if the wide-clicks * supported, it is more precise so e. g. 5 is ca. 0.5 microseconds (500-ns). */ #ifndef TCL_CHECK_EVENT_SOURCE_THRESHOLD #define TCL_CHECK_EVENT_SOURCE_THRESHOLD 5 #endif /* * The following structure keeps track of the state of the notifier on a |
︙ | ︙ | |||
886 887 888 889 890 891 892 | } return result; } } return 0; } | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | } return result; } } return 0; } #if TCL_CHECK_EVENT_SOURCE_THRESHOLD /* *---------------------------------------------------------------------- * * CheckSourceThreshold -- * * Check whether we should iterate over event sources for availability. * * This is used to avoid too unneeded overhead (too often call checkProc). * * Results: * Returns 1 if threshold reached (check event sources), 0 otherwise. * *---------------------------------------------------------------------- */ static inline int CheckSourceThreshold( ThreadSpecificData *tsdPtr) { /* don't need to wait/check for events too often */ #ifndef TCL_WIDE_CLICKS unsigned long clickdiff, clicks = TclpGetClicks(); #else Tcl_WideInt clickdiff, clicks; /* in 100-ns */ clicks = TclpGetWideClicks() * (TclpWideClickInMicrosec() * 10); #endif /* considering possible clicks-jump */ if ( (clickdiff = (clicks - tsdPtr->lastCheckClicks)) >= 0 && clickdiff <= TCL_CHECK_EVENT_SOURCE_THRESHOLD) { return 0; } tsdPtr->lastCheckClicks = clicks; return 1; } #endif /* *---------------------------------------------------------------------- * * TclPeekEventQueued -- * * Check whether some event (except idle) available (async, queued, timer). * |
︙ | ︙ | |||
932 933 934 935 936 937 938 | /* once from here */ if (!repeat) { break; } if (flags & TCL_DONT_WAIT) { | < < < < < < < < | > < | < | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 | /* once from here */ if (!repeat) { break; } if (flags & TCL_DONT_WAIT) { /* don't need to wait/check for events too often */ #if TCL_CHECK_EVENT_SOURCE_THRESHOLD if (!CheckSourceThreshold(tsdPtr)) { return 0; } #endif } /* * Check all the event sources for new events. */ for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL; sourcePtr = sourcePtr->nextPtr) { if (sourcePtr->checkProc) { (sourcePtr->checkProc)(sourcePtr->clientData, flags); } } } while (repeat--); return 0; } /* *---------------------------------------------------------------------- * * TclSetTimerEventMarker -- * * Set timer event marker to the last pending event in the queue. * |
︙ | ︙ | |||
1000 1001 1002 1003 1004 1005 1006 | * if setup-proc resp. check-proc will not generate new events. * Force timer execution if flags specified (from checkProc). */ tsdPtr->timerMarkerPtr = flags ? INT2PTR(-1) : INT2PTR(-2); }; } } | | < | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | * if setup-proc resp. check-proc will not generate new events. * Force timer execution if flags specified (from checkProc). */ tsdPtr->timerMarkerPtr = flags ? INT2PTR(-1) : INT2PTR(-2); }; } } /* *---------------------------------------------------------------------- * * Tcl_GetServiceMode -- * * This routine returns the current service mode of the notifier. * |
︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 | int Tcl_GetServiceMode(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->serviceMode; } | | < | 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 | int Tcl_GetServiceMode(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->serviceMode; } /* *---------------------------------------------------------------------- * * Tcl_SetServiceMode -- * * This routine sets the current service mode of the tsdPtr-> * |
︙ | ︙ | |||
1058 1059 1060 1061 1062 1063 1064 | oldMode = tsdPtr->serviceMode; tsdPtr->serviceMode = mode; if (tclStubs.tcl_ServiceModeHook) { tclStubs.tcl_ServiceModeHook(mode); } return oldMode; } | | < | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | oldMode = tsdPtr->serviceMode; tsdPtr->serviceMode = mode; if (tclStubs.tcl_ServiceModeHook) { tclStubs.tcl_ServiceModeHook(mode); } return oldMode; } /* *---------------------------------------------------------------------- * * Tcl_SetMaxBlockTime -- * * This function is invoked by event sources to tell the notifier how * long it may block the next time it blocks. The timePtr argument gives |
︙ | ︙ | |||
1103 1104 1105 1106 1107 1108 1109 | * immediately. */ if (!tsdPtr->inTraversal) { Tcl_SetTimer(&tsdPtr->blockTime); } } | | < | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | * immediately. */ if (!tsdPtr->inTraversal) { Tcl_SetTimer(&tsdPtr->blockTime); } } /* *---------------------------------------------------------------------- * * Tcl_DoOneEvent -- * * Process a single event of some sort. If there's no work to do, wait * for an event to occur, then process it. |
︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 | * otherwise reset the block time to infinity. */ if (flags & TCL_DONT_WAIT) { /* don't need to wait/check for events too often */ #if TCL_CHECK_EVENT_SOURCE_THRESHOLD | < < < < < < | < < < | 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 | * otherwise reset the block time to infinity. */ if (flags & TCL_DONT_WAIT) { /* don't need to wait/check for events too often */ #if TCL_CHECK_EVENT_SOURCE_THRESHOLD if (!CheckSourceThreshold(tsdPtr)) { goto idleEvents; } #endif tsdPtr->blockTime.sec = 0; tsdPtr->blockTime.usec = 0; tsdPtr->blockTimeSet = 1; timePtr = &tsdPtr->blockTime; goto wait; /* for notifier resp. system events */ } |
︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 | /* Reset block time earliest at the end of event cycle */ tsdPtr->blockTimeSet = 0; tsdPtr->serviceMode = oldMode; return result; } | | < | 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 | /* Reset block time earliest at the end of event cycle */ tsdPtr->blockTimeSet = 0; tsdPtr->serviceMode = oldMode; return result; } /* *---------------------------------------------------------------------- * * Tcl_ServiceAll -- * * This routine checks all of the event sources, processes events that * are on the Tcl event queue, and then calls the any idle handlers. |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | } else { Tcl_SetTimer(&tsdPtr->blockTime); } tsdPtr->inTraversal = 0; tsdPtr->serviceMode = TCL_SERVICE_ALL; return result; } | | < | 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | } else { Tcl_SetTimer(&tsdPtr->blockTime); } tsdPtr->inTraversal = 0; tsdPtr->serviceMode = TCL_SERVICE_ALL; return result; } /* *---------------------------------------------------------------------- * * Tcl_ThreadAlert -- * * This function wakes up the notifier associated with the specified * thread (if there is one). |
︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 | tclStubs.tcl_AlertNotifier(tsdPtr->clientData); } break; } } Tcl_MutexUnlock(&listLock); } | | < | 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 | tclStubs.tcl_AlertNotifier(tsdPtr->clientData); } break; } } Tcl_MutexUnlock(&listLock); } /* *---------------------------------------------------------------------- * * Tcl_Sleep -- * * Delay execution for the specified number of milliseconds. * |
︙ | ︙ |