VirtualBox

source: kStuff/trunk/kProfiler2/prfcoremodseg.cpp.h@ 2

Last change on this file since 2 was 2, checked in by bird, 17 years ago

Imported http://svn.netlabs.org/repos/libc/trunk/kStuff, revision 3612.

  • Property svn:keywords set to Id Revision
File size: 6.7 KB
Line 
1/* $Id: prfcoremodseg.cpp.h 2 2007-11-16 16:07:14Z bird $ */
2/** @file
3 * kProfiler Mark 2 - Core Module Segment Code Template.
4 */
5
6/*
7 * Copyright (c) 2006-2007 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kProfiler.
10 *
11 * kProfiler is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * kProfiler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with kProfiler; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27
28/**
29 * Adds a module segment.
30 *
31 * @returns Offset to the module if existing or successfully added
32 * @returns 0 if not found.
33 *
34 * @param pHdr The profiler header.
35 * @param pModSeg Pointer to the module segment to insert (it's copied of course).
36 * @param off The offset into the modseg area which has been searched.
37 * (This is relative to the first moddule segment record (at pHdr->offModSegs).)
38 */
39static KU32 KPRF_NAME(InsertModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(PC,MODSEG) pModSeg, KU32 off)
40{
41 /*
42 * Lookup the module segment, inserting it if not found (and there is room).
43 */
44 for (;;)
45 {
46 if (off >= pHdr->cbModSegs)
47 {
48 /*
49 * It was the end, let's try insert it.
50 *
51 * This is where we lock the modseg stuff. The deal is that we
52 * serialize the actual inserting without blocking lookups. This
53 * means that we may end up with potential racing inserts, but
54 * unless there is a large amount of modules being profiled that's
55 * probably not going to be much of a problem. Anyway if we race,
56 * we'll simply have to search the new additions before we add our
57 * own stuff.
58 */
59 KPRF_MODSEGS_LOCK();
60 if (off >= pHdr->cbModSegs)
61 {
62 KU32 cbModSeg = KPRF_OFFSETOF(MODSEG, szPath[pModSeg->cchPath + 1]);
63 cbModSeg = KPRF_ALIGN(cbModSeg, KPRF_SIZEOF(UPTR));
64 if (off + cbModSeg <= pHdr->cbMaxModSegs)
65 {
66 KPRF_TYPE(P,MODSEG) pNew = KPRF_OFF2PTR(P,MODSEG, off + pHdr->offModSegs, pHdr);
67 pNew->uBasePtr = pModSeg->uBasePtr;
68 pNew->cbSegmentMinusOne = pModSeg->cbSegmentMinusOne;
69 pNew->iSegment = pModSeg->iSegment;
70 pNew->fLoaded = pModSeg->fLoaded;
71 pNew->cchPath = pModSeg->cchPath;
72
73 KI32 iPath = pModSeg->cchPath;
74 do pNew->szPath[iPath] = pModSeg->szPath[iPath];
75 while (--iPath >= 0);
76
77 /* commit it */
78 KPRF_ATOMIC_SET32(&pHdr->cbModSegs, off + cbModSeg);
79 off += pHdr->offModSegs;
80 }
81 else
82 off = 0;
83 KPRF_MODSEGS_UNLOCK();
84 return off;
85 }
86 KPRF_MODSEGS_UNLOCK();
87 /* someone raced us, check the new entries. */
88 }
89
90 /*
91 * Match?
92 */
93 KPRF_TYPE(PC,MODSEG) pCur = KPRF_OFF2PTR(P,MODSEG, off + pHdr->offModSegs, pHdr);
94 if ( pCur->uBasePtr == pModSeg->uBasePtr
95 && pCur->fLoaded == pModSeg->fLoaded
96 && pCur->cchPath == pModSeg->cchPath
97 && pCur->iSegment == pModSeg->iSegment
98 && pCur->cbSegmentMinusOne == pModSeg->cbSegmentMinusOne
99 )
100 {
101 KI32 iPath = pModSeg->cchPath;
102 for (;;)
103 {
104 if (!iPath--)
105 return off + pHdr->offModSegs;
106 if (pModSeg->szPath[iPath] != pCur->szPath[iPath])
107 break;
108 }
109 /* didn't match, continue searching */
110 }
111 KU32 cbCur = KPRF_OFFSETOF(MODSEG, szPath[pCur->cchPath + 1]);
112 off += KPRF_ALIGN(cbCur, KPRF_SIZEOF(UPTR));
113 }
114}
115
116
117/**
118 * Queries data for and inserts a new module segment.
119 *
120 *
121 * @returns Offset to the module if existing or successfully added
122 * @returns 0 if not found.
123 *
124 * @param pHdr The profiler header.
125 * @param uPC Address within the module.
126 * @param off The offset into the modseg area which has been searched.
127 * (This is relative to the first moddule segment record (at pHdr->offModSegs).)
128 */
129static KU32 KPRF_NAME(NewModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(,UPTR) uPC, KU32 off)
130{
131 /*
132 * Query the module name and object of the function.
133 */
134#pragma pack(1)
135 struct
136 {
137 KPRF_TYPE(,MODSEG) ModSeg;
138 char szMorePath[260];
139 } s;
140#pragma pack()
141 if (KPRF_GET_MODSEG(uPC + pHdr->uBasePtr, s.ModSeg.szPath, sizeof(s.ModSeg.szPath) + sizeof(s.szMorePath),
142 &s.ModSeg.iSegment, &s.ModSeg.uBasePtr, &s.ModSeg.cbSegmentMinusOne))
143 return 0;
144 s.ModSeg.uBasePtr -= pHdr->uBasePtr;
145 s.ModSeg.fLoaded = 1;
146 s.ModSeg.cchPath = 0;
147 while (s.ModSeg.szPath[s.ModSeg.cchPath])
148 s.ModSeg.cchPath++;
149
150 return KPRF_NAME(InsertModSeg)(pHdr, &s.ModSeg, off);
151}
152
153
154/**
155 * Record a module segment.
156 *
157 * This is an internal worker for recording a module segment when adding
158 * a new function.
159 *
160 * @returns Offset to the module if existing or successfully added
161 * @returns 0 if not found.
162 *
163 * @param pHdr The profiler header.
164 * @param uPC Address within the module.
165 */
166static KU32 KPRF_NAME(RecordModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(,UPTR) uPC)
167{
168 /*
169 * Lookup the module segment, inserting it if not found (and there is room).
170 */
171 KU32 off = 0;
172 KPRF_TYPE(PC,MODSEG) pCur = KPRF_OFF2PTR(P,MODSEG, pHdr->offModSegs, pHdr);
173 const KU32 cbModSegs = pHdr->cbModSegs;
174 for (;;)
175 {
176 /* done and not found? */
177 if (off >= cbModSegs)
178 return KPRF_NAME(NewModSeg)(pHdr, uPC, off);
179
180 /*
181 * Match?
182 */
183 if ( pCur->fLoaded
184 && uPC - pCur->uBasePtr <= pCur->cbSegmentMinusOne)
185 return off + pHdr->offModSegs;
186
187 KU32 cbCur = KPRF_OFFSETOF(MODSEG, szPath[pCur->cchPath + 1]);
188 cbCur = KPRF_ALIGN(cbCur, KPRF_SIZEOF(UPTR));
189 off += cbCur;
190 pCur = (KPRF_TYPE(PC,MODSEG))((KU8 *)pCur + cbCur);
191 }
192}
193
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette