summaryrefslogtreecommitdiff
path: root/src/pal/src/include/pal/shmemory.h
blob: 5ca848148c61b72a3c6d29994661c1155101723c (plain)
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*++



Module Name:

    include/pal/shmemory.h

Abstract:
    Header file for interface to shared memory

How to use :

The SHMalloc function can be used to allocate memory in the shared memory area.
It returns a value of type SHMPTR, which will be useable in all participating
processes. The SHMPTR_TO_PTR macro can be used to convert a SHMPTR value into
an address valid *only* within the current process. Do NOT store pointers in
shared memory, since those will not be valid for other processes. If you need
to construct linked lists or other strctures that usually use pointers, use
SHMPTR values instead of pointers. In addition, Lock/Release functions must be
used when manipulating data in shared memory, to ensure inter-process synchronization.

Example :

//a simple linked list type
typedef struct
{
int count;
SHMPTR string;
SHMPTR next;
}SHMLIST;

// Allocate a new list item
SHMPTR new_item = SHMalloc(sizeof(SHMLIST));

// get a pointer to it
SHMLIST *item_ptr = (SHMLIST *)SHMPTR_TO_PTR(new_item);

// Allocate memory for the "string" member, initialize it
item_ptr->string = SHMalloc(strlen("string"));
LPSTR str_ptr = (LPSTR)SHMPTR_TO_PTR(item_ptr->string);
strcpy(str_ptr, "string");

//Take the shared memory lock to prevent anyone from modifying the linked list
SHMLock();

//get the list's head from somewhere
SHMPTR list_head = get_list_head();

//link the list to our new item
item_ptr->next = list_head

//get a pointer to the list head's structure
SHMLIST *head_ptr = (SHMLIST *)SHMPTR_TO_PTR(list_head);

//set the new item's count value based on the head's count value
item_ptr->count = head_ptr->count + 1;

//save the new item as the new head of the list
set_list_head(new_item);

//We're done modifying the list, release the lock
SHMRelease



--*/

#ifndef _PAL_SHMEMORY_H_
#define _PAL_SHMEMORY_H_

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

/*
Type for shared memory blocks. use SHMPTR_TO_PTR to get a useable address.
 */
typedef DWORD_PTR SHMPTR;

#define MAX_SEGMENTS 256


typedef enum {
    SIID_PROCESS_INFO,/* pointers to PROCESS structures? */
    SIID_NAMED_OBJECTS,
    SIID_FILE_LOCKS,

    SIID_LAST
} SHM_INFO_ID;

typedef enum
{
    SHM_NAMED_MAPPINGS,      /* structs with map name, file name & flags? */
    SHM_NAMED_EVENTS,        /* structs with event names & ThreadWaitingList struct? */
    SHM_NAMED_MUTEXS,        /* structs with mutext names, and ThreadWaitingList struct */

    SHM_NAMED_LAST
} SHM_NAMED_OBJECTS_ID;

typedef struct _SMNO
{
    SHM_NAMED_OBJECTS_ID ObjectType;
    SHMPTR ShmNext;
    SHMPTR ShmObjectName;
    SHMPTR ShmSelf;

}SHM_NAMED_OBJECTS, * PSHM_NAMED_OBJECTS;


/*
SHMPTR_TO_PTR

Macro to convert a SHMPTR value into a valid (for this process) pointer.

In debug builds, we always call the function to do full checks.
In release builds, check if the segment is known, and if it is, do only minimal
validation (if segment is unknown, we have to call the function)
 */
#if _DEBUG

#define SHMPTR_TO_PTR(shmptr) \
    SHMPtrToPtr(shmptr)

#else /* !_DEBUG */

extern int shm_numsegments;

/* array containing the base address of each segment */
extern Volatile<LPVOID> shm_segment_bases[MAX_SEGMENTS];

#define SHMPTR_TO_PTR(shmptr)\
    ((shmptr)?(((static_cast<int>(shmptr)>>24)<shm_numsegments)?\
    reinterpret_cast<LPVOID>(reinterpret_cast<size_t>(shm_segment_bases[static_cast<int>(shmptr)>>24].Load())+(static_cast<int>(shmptr)&0x00FFFFFF)):\
    SHMPtrToPtr(shmptr)): static_cast<LPVOID>(NULL))


#endif /* _DEBUG */

/* Set ptr to NULL if shmPtr == 0, else set ptr to SHMPTR_TO_PTR(shmptr) 
   return FALSE if SHMPTR_TO_PTR returns NULL ptr from non null shmptr, 
   TRUE otherwise */
#define SHMPTR_TO_PTR_BOOL(ptr, shmptr) \
    ((shmptr != 0) ? ((ptr = SHMPTR_TO_PTR(shmptr)) != NULL) : ((ptr = NULL) == NULL))

/*++
SHMPtrToPtr

Convert a SHMPTR value into a useable pointer.

Unlike the macro defined above, this function performs as much validation as
possible, and can handle cases when the SHMPTR is located in an aread of shared
memory the process doesn't yet know about.
--*/
LPVOID SHMPtrToPtr(SHMPTR shmptr);

/*++
SHMInitialize

Hook this process into the PAL shared memory system; initialize the shared
memory if no other process has done it.
--*/
BOOL SHMInitialize(void);

/*++
SHMCleanup

Release all shared memory resources held; remove ourselves from the list of
registered processes, and remove all shared memory files if no process remains
--*/
void SHMCleanup(void);

/*++
SHMalloc

Allocate a block of memory of the specified size

Parameters :
    size_t size : size of block required

Return value :
    A SHMPTR identifying the new block, or 0 on failure. Use SHMPtrToPtr to
    convert a SHMPTR into a useable pointer (but remember to lock the shared
    memory first!)

Notes :
    SHMalloc will fail if the requested size is larger than a certain maximum.
    At the moment, the maximum is 520 bytes (MAX_PATH_FNAME*2).
--*/
SHMPTR SHMalloc(size_t size);

/*++
SHMfree

Release a block of shared memory and put it back in the shared memory pool

Parameters :
    SHMPTR shmptr : identifier of block to release

(no return value)
--*/
void SHMfree(SHMPTR shmptr);

/*++
SHMLock

Restrict shared memory access to the current thread of the current process

(no parameters)

Return value :
    New lock count
--*/
int SHMLock(void);

/*++
SHMRelease

Release a lock on shared memory taken with SHMLock.

(no parameters)

Return value :
    New lock count
--*/
int SHMRelease(void);


/*++
Function :
    SHMGetInfo

    Retrieve some information from shared memory

Parameters :
    SHM_INFO_ID element : identifier of element to retrieve

Return value :
    Value of specified element

Notes :
    The SHM lock should be held while manipulating shared memory
--*/
SHMPTR SHMGetInfo(SHM_INFO_ID element);

/*++
Function :
    SHMSetInfo

    Place some information into shared memory

Parameters :
    SHM_INFO_ID element : identifier of element to save
    SHMPTR value : new value of element

Return value :
    TRUE if successfull, FALSE otherwise.

Notes :
    The SHM lock should be held while manipulating shared memory
--*/
BOOL SHMSetInfo(SHM_INFO_ID element, SHMPTR value);


/********************** Shared memory help functions ********************/

/*++
SHMStrDup

Duplicates the string in shared memory.

Returns the new address as SHMPTR on success.
Returns (SHMPTR)NULL on failure.
--*/
SHMPTR SHMStrDup( LPCSTR string );

/*++
SHMWStrDup

Duplicates the wide string in shared memory.

Returns the new address as SHMPTR on success.
Returns (SHMPTR)NULL on failure.
--*/
SHMPTR SHMWStrDup( LPCWSTR string );


/*++
SHMFindNamedObjectByName

Searches for an object whose name matches the name and ID passed in.

Returns a SHMPTR to its location in shared memory. If no object
matches the name, the function returns NULL and sets pbNameExists to FALSE.
If an object matches the name but is of a different type, the function
returns NULL and sets pbNameExists to TRUE.

--*/
SHMPTR SHMFindNamedObjectByName( LPCWSTR lpName, SHM_NAMED_OBJECTS_ID oid,
                                 BOOL *pbNameExists );

/*++ 
SHMRemoveNamedObject

Removes the specified named object from the list

No return.

note : the caller is reponsible for releasing all associated memory
--*/
void SHMRemoveNamedObject( SHMPTR shmNamedObject );

/*++ SHMAddNamedObject

Adds the specified named object to the list.

No return.
--*/
void SHMAddNamedObject( SHMPTR shmNewNamedObject );

#ifdef __cplusplus
}
#endif // __cplusplus

#endif /* _PAL_SHMEMORY_H_ */