Schrift
[thread]1117[/thread]

linux: mlock getpagesize



<< >> 5 Einträge, 1 Seite
esskar
 2004-06-30 16:53
#11078 #11078
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
mit mlock kann ich ja speicher locken;
dabei muss man aber aufpassen, dass man nicht gleiche speicherseiten (pages) zweimal lockt, da sonst der letzte lock auf die seite aufgehoben wird;
wie bekomm ich heraus, in welcher page sich mein buffer befindet?
esskar
 2004-06-30 20:14
#11079 #11079
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
hab jetzt festgestellt, dass ein linux malloc wirklich den speicher hintereinander allokiert und das man sich so die page durch ein wenig modulo rechnung bestimmen kann
kabel
 2004-07-03 01:06
#11080 #11080
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
.oO wieder was gelernt :)
irgendwie macht der parser probleme :(
ich hab mein posting online gestellt:
http://induhviduals.de/~kabel/tmp/post.txt

[esskar]url fixed[/esskar]\n\n

<!--EDIT|esskar|1088807752-->
-- stefan
esskar
 2004-07-03 02:40
#11081 #11081
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
danke...
hier mal meine lösung:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include <limits.h>
#include <sys/mman.h>

#include "bufhandle.h"

#define BH_PAGEMAXCOUNT     32

//typedefs
typedef unsigned char byte;

//memory struct
typedef struct tag_bh_struct
{
   size_t struct_size;
   size_t buffer_size;
   byte*  buffer_block;
} bh_struct, *pbh_struct;

//lock struct
typedef struct tag_bh_page
{
   unsigned long addr;
   size_t count;
} bh_page, *pbh_page;

static bh_page bh_pages[BH_PAGEMAXCOUNT];
static bool bh_init = false;

/* find page index
  returns index < BH_PAGEMAXCOUNT if is found
  returns free index if index is not found
  returns BH_PAGEMAXCOUNT if no index is available*/
int bh_findpage(unsigned long addr)
{
   int i;
   int freeidx = BH_PAGEMAXCOUNT;

   for(i = 0; i < BH_PAGEMAXCOUNT; i++)
   {
       if(bh_pages[i].addr == 0) freeidx = i;
       else if(bh_pages[i].addr == addr) break;
   }

   if(i == BH_PAGEMAXCOUNT) i = freeidx;

   return i;
}

size_t bh_pagelock(unsigned long page)
{
   int idx = 0;
   if((idx = bh_findpage(page)) != BH_PAGEMAXCOUNT)
       return (++bh_pages[idx].count); //increased page counter
   else
       return 0; //page not locked
}

size_t bh_pageunlock(unsigned long page)
{
   int idx = 0;
   if((idx = bh_findpage(page)) != BH_PAGEMAXCOUNT)
   {
       if(bh_pages[idx].count == 0) //page not locked
           return 0;
       else if(bh_pages[idx].count == 1) //last lock; delete
           bh_pages[idx].addr = 0;

       return (--bh_pages[idx].count); //decreased page counter
   }
   else
       return 0; //page not locked
}

// lock memory aligned
bh_error_t bh_mlock(byte *addr, size_t len)
{
   unsigned long page_offset, page_size;

   if(bh_init == false)
   {
       memset(bh_pages, 0, sizeof(bh_page)*BH_PAGEMAXCOUNT);
       bh_init = true;
   }

   page_size = getpagesize();
   page_offset = (unsigned long) addr % page_size;
   addr -= page_offset; /* Adjust addr to page boundary */
   len += page_offset; /* Adjust len with page_offset */

   //no page available
   if(bh_pagelock((unsigned long)addr) == 0)
       return bh_maxhandlecount;

   return (mlock(addr, len) == 0 ? bh_no_error : bh_errno); /* Lock the memory */
}

// unlock memory aligned
bh_error_t bh_unlock(byte *addr, size_t len)
{
   unsigned long page_offset, page_size;

   page_size = getpagesize();
   page_offset = (unsigned long) addr % page_size;
   addr -= page_offset; /* Adjust addr to page boundary */
   len  += page_offset; /* Adjust len with page_offset */

   // no lock in that page
   if(bh_pageunlock((unsigned long)addr) == 0)
       return (munlock(addr, len) == 0 ? bh_no_error : bh_errno); /* Unlock the memory */

   return bh_no_error;
}

// allocate memory and lock
void* bh_alloc(size_t size)
{
   void* block = NULL;

   if(bh_init == false)
   {
       memset(bh_pages, 0, BH_PAGEMAXCOUNT * sizeof(size_t));
       bh_init = true;
   }

   block = malloc(size);
   if(block == NULL) return NULL;

   if(bh_mlock((byte*)block, size) != bh_no_error)
   {
       //lock not possible
       free(block);
       return NULL;
   }

   /*The write to each page forces Linux to
     assign a unique, unshared memory page to
     the process for that page. */
   memset(block, 0, size);

   return block;
}

// delocate memory and unlock
void bh_free(void* block, size_t size)
{
   if(block == NULL) return;

   memset(block, 0, size);

   //pretend it works
   bh_unlock((byte*)block, size);

   free(block);
}

extern bh_error_t buffer_create(size_t size, buffer_handle_t *handle)
{
   pbh_struct bufstruct = NULL;
   byte* buffer = NULL;

   // handle is not valid
   if(handle == NULL) return bh_invalid_handle;

   // allocate handle structure
   bufstruct = (pbh_struct)bh_alloc(sizeof(bh_struct));
   if(bufstruct == NULL) return bh_errno;

   // allocate buffer
   buffer = (byte*)bh_alloc(size);
   if(buffer == NULL) return bh_errno;

   //fill buffer
   bufstruct->struct_size = sizeof(bh_struct);
   bufstruct->buffer_size = size;
   bufstruct->buffer_block = buffer;

   // set handle
   *handle = (buffer_handle_t)bufstruct;

   return bh_no_error;
}

extern bh_error_t buffer_release(buffer_handle_t handle)
{
   // handle check
   if(handle == 0) return bh_invalid_handle;

   pbh_struct bufstruct = (pbh_struct)handle;
   if(bufstruct->struct_size != sizeof(bh_struct)) return bh_invalid_handle;

   // free data
   bh_free(bufstruct->buffer_block, bufstruct->buffer_size);
   bh_free(bufstruct, sizeof(bh_struct));

   return bh_no_error;
}

extern bh_error_t buffer_copy_in(buffer_handle_t handle, void* buffer,
                size_t size, size_t offset)
{
   if(handle == 0) return bh_invalid_handle;

   pbh_struct bufstruct = (pbh_struct)handle;
   if(bufstruct->struct_size != sizeof(bh_struct)) return bh_invalid_handle;

   if(bufstruct->buffer_size < offset ||
      bufstruct->buffer_size - offset < size) return bh_overflow;

   memcpy(bufstruct->buffer_block + offset, buffer, size);

   return bh_no_error;
}

extern bh_error_t buffer_copy_out(buffer_handle_t handle, void* buffer,
                size_t size, size_t offset)
{
   if(handle == 0) return bh_invalid_handle;

   pbh_struct bufstruct = (pbh_struct)handle;
   if(bufstruct->struct_size != sizeof(bh_struct)) return bh_invalid_handle;

   if(bufstruct->buffer_size < offset ||
      bufstruct->buffer_size - offset < size) return bh_overflow;

   memcpy(buffer, bufstruct->buffer_block + offset, size);

   return bh_no_error;
}
kabel
 2004-07-03 09:55
#11082 #11082
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
hehe richtig geraten :)

das mit den addressen müsste eigentlich gehen, malloc.h arbeitet ja mit brk/mmap und die greifen direkt auf vm-addressen.

ich hab hier noch was cooles entdeckt, und zwar gibt es /debugging hooks/ -- malloc_hook(3) --, die sich für deine zwecke missbrauchen lassen. da ist sogar ein fast funkionsfähiges beispiel drin :p

harhar, ich denke gerade voller schadenfreude an einige kommilitonen, die segfaults mittlerweile hassen dürften ... nun ja, die programmieraufgaben sind ja jetzt vorbei, da kann ich diese sehr schöne debugging-möglichkeit ja weitersagen =) harhar 8)
-- stefan
<< >> 5 Einträge, 1 Seite



View all threads created 2004-06-30 16:53.