kDefs.h: Added risc-v to the K_ARCH_XXX defines.
[kstuff-mirror.git] / kProfiler2 / prfcoremodseg.cpp.h
blobd25223a69952d5a92eef3ea0d15c5a7b523759f7
1 /* $Id$ */
2 /** @file
3 * kProfiler Mark 2 - Core Module Segment Code Template.
4 */
6 /*
7 * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
32 /**
33 * Adds a module segment.
35 * @returns Offset to the module if existing or successfully added
36 * @returns 0 if not found.
38 * @param pHdr The profiler header.
39 * @param pModSeg Pointer to the module segment to insert (it's copied of course).
40 * @param off The offset into the modseg area which has been searched.
41 * (This is relative to the first moddule segment record (at pHdr->offModSegs).)
43 static KU32 KPRF_NAME(InsertModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(PC,MODSEG) pModSeg, KU32 off)
46 * Lookup the module segment, inserting it if not found (and there is room).
48 for (;;)
50 if (off >= pHdr->cbModSegs)
53 * It was the end, let's try insert it.
55 * This is where we lock the modseg stuff. The deal is that we
56 * serialize the actual inserting without blocking lookups. This
57 * means that we may end up with potential racing inserts, but
58 * unless there is a large amount of modules being profiled that's
59 * probably not going to be much of a problem. Anyway if we race,
60 * we'll simply have to search the new additions before we add our
61 * own stuff.
63 KPRF_MODSEGS_LOCK();
64 if (off >= pHdr->cbModSegs)
66 KU32 cbModSeg = KPRF_OFFSETOF(MODSEG, szPath[pModSeg->cchPath + 1]);
67 cbModSeg = KPRF_ALIGN(cbModSeg, KPRF_SIZEOF(UPTR));
68 if (off + cbModSeg <= pHdr->cbMaxModSegs)
70 KPRF_TYPE(P,MODSEG) pNew = KPRF_OFF2PTR(P,MODSEG, off + pHdr->offModSegs, pHdr);
71 pNew->uBasePtr = pModSeg->uBasePtr;
72 pNew->cbSegmentMinusOne = pModSeg->cbSegmentMinusOne;
73 pNew->iSegment = pModSeg->iSegment;
74 pNew->fLoaded = pModSeg->fLoaded;
75 pNew->cchPath = pModSeg->cchPath;
77 KI32 iPath = pModSeg->cchPath;
78 do pNew->szPath[iPath] = pModSeg->szPath[iPath];
79 while (--iPath >= 0);
81 /* commit it */
82 KPRF_ATOMIC_SET32(&pHdr->cbModSegs, off + cbModSeg);
83 off += pHdr->offModSegs;
85 else
86 off = 0;
87 KPRF_MODSEGS_UNLOCK();
88 return off;
90 KPRF_MODSEGS_UNLOCK();
91 /* someone raced us, check the new entries. */
95 * Match?
97 KPRF_TYPE(PC,MODSEG) pCur = KPRF_OFF2PTR(P,MODSEG, off + pHdr->offModSegs, pHdr);
98 if ( pCur->uBasePtr == pModSeg->uBasePtr
99 && pCur->fLoaded == pModSeg->fLoaded
100 && pCur->cchPath == pModSeg->cchPath
101 && pCur->iSegment == pModSeg->iSegment
102 && pCur->cbSegmentMinusOne == pModSeg->cbSegmentMinusOne
105 KI32 iPath = pModSeg->cchPath;
106 for (;;)
108 if (!iPath--)
109 return off + pHdr->offModSegs;
110 if (pModSeg->szPath[iPath] != pCur->szPath[iPath])
111 break;
113 /* didn't match, continue searching */
115 KU32 cbCur = KPRF_OFFSETOF(MODSEG, szPath[pCur->cchPath + 1]);
116 off += KPRF_ALIGN(cbCur, KPRF_SIZEOF(UPTR));
122 * Queries data for and inserts a new module segment.
125 * @returns Offset to the module if existing or successfully added
126 * @returns 0 if not found.
128 * @param pHdr The profiler header.
129 * @param uPC Address within the module.
130 * @param off The offset into the modseg area which has been searched.
131 * (This is relative to the first moddule segment record (at pHdr->offModSegs).)
133 static KU32 KPRF_NAME(NewModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(,UPTR) uPC, KU32 off)
136 * Query the module name and object of the function.
138 #pragma pack(1)
139 struct
141 KPRF_TYPE(,MODSEG) ModSeg;
142 char szMorePath[260];
143 } s;
144 #pragma pack()
145 if (KPRF_GET_MODSEG(uPC + pHdr->uBasePtr, s.ModSeg.szPath, sizeof(s.ModSeg.szPath) + sizeof(s.szMorePath),
146 &s.ModSeg.iSegment, &s.ModSeg.uBasePtr, &s.ModSeg.cbSegmentMinusOne))
147 return 0;
148 s.ModSeg.uBasePtr -= pHdr->uBasePtr;
149 s.ModSeg.fLoaded = 1;
150 s.ModSeg.cchPath = 0;
151 while (s.ModSeg.szPath[s.ModSeg.cchPath])
152 s.ModSeg.cchPath++;
154 return KPRF_NAME(InsertModSeg)(pHdr, &s.ModSeg, off);
159 * Record a module segment.
161 * This is an internal worker for recording a module segment when adding
162 * a new function.
164 * @returns Offset to the module if existing or successfully added
165 * @returns 0 if not found.
167 * @param pHdr The profiler header.
168 * @param uPC Address within the module.
170 static KU32 KPRF_NAME(RecordModSeg)(KPRF_TYPE(P,HDR) pHdr, KPRF_TYPE(,UPTR) uPC)
173 * Lookup the module segment, inserting it if not found (and there is room).
175 KU32 off = 0;
176 KPRF_TYPE(PC,MODSEG) pCur = KPRF_OFF2PTR(P,MODSEG, pHdr->offModSegs, pHdr);
177 const KU32 cbModSegs = pHdr->cbModSegs;
178 for (;;)
180 /* done and not found? */
181 if (off >= cbModSegs)
182 return KPRF_NAME(NewModSeg)(pHdr, uPC, off);
185 * Match?
187 if ( pCur->fLoaded
188 && uPC - pCur->uBasePtr <= pCur->cbSegmentMinusOne)
189 return off + pHdr->offModSegs;
191 KU32 cbCur = KPRF_OFFSETOF(MODSEG, szPath[pCur->cchPath + 1]);
192 cbCur = KPRF_ALIGN(cbCur, KPRF_SIZEOF(UPTR));
193 off += cbCur;
194 pCur = (KPRF_TYPE(PC,MODSEG))((KU8 *)pCur + cbCur);