1 static char RCSId
[] = "$Id$";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1994";
7 #include "prototypes.h"
12 static key_t MemoryKeys
[SHMSEG
]; /* Keep track of keys were using */
13 static int LinearInitialized
= 0;
18 /**********************************************************************
22 LinearFindSpace(int n_segments
)
26 if (!LinearInitialized
)
28 memset(MemoryKeys
, -1, sizeof(MemoryKeys
));
32 for (i
= 0, n
= 0; i
< SHMSEG
, n
!= n_segments
; i
++)
34 if (MemoryKeys
[i
] < 0)
47 /**********************************************************************
50 * OK, this is an evil beast. We will do one of two things:
52 * 1. If the data item <= 64k, then just call GlobalLock().
53 * 2. If the data item > 64k, then map memory.
56 GlobalLinearLock(unsigned int block
)
63 /******************************************************************
64 * Get GDESC for this block.
66 g_first
= GlobalGetGDesc(block
);
70 /******************************************************************
71 * Is block less then 64k in length?
73 if (g_first
->sequence
!= 1 || g_first
->length
== 1)
75 return (void *) GlobalLock(block
);
78 /******************************************************************
79 * If there is already a linear lock on this memory, then
80 * just return a pointer to it.
82 if (g_first
->linear_count
)
84 g_first
->linear_count
++;
85 return g_first
->linear_addr
;
88 /******************************************************************
89 * No luck. We need to do the linear mapping right now.
92 loc_idx
= LinearFindSpace(g_first
->length
);
96 addr
= (unsigned long) SHM_RANGE_START
+ (0x10000 * loc_idx
);
99 i
< loc_idx
+ g_first
->length
;
100 i
++, addr
+= 0x10000, g
= g
->next
)
102 if ((MemoryKeys
[i
] = IPCCopySelector(g
->handle
>> 3, addr
, 0)) < 0)
104 g
->linear_addr
= (void *) addr
;
107 #endif /* HAVE_IPC */
109 return g_first
->linear_addr
;
112 /**********************************************************************
117 GlobalLinearUnlock(unsigned int block
)
123 /******************************************************************
124 * Get GDESC for this block.
126 g_first
= GlobalGetGDesc(block
);
130 /******************************************************************
131 * Is block less then 64k in length?
133 if (g_first
->sequence
!= 1 || g_first
->length
== 1)
135 return GlobalUnlock(block
);
138 /******************************************************************
139 * Make sure we have a lock on this block.
142 if (g_first
->linear_count
> 1)
144 g_first
->linear_count
--;
146 else if (g_first
->linear_count
== 1)
149 loc_idx
= (((unsigned int) g_first
- (unsigned int) SHM_RANGE_START
)
151 for (i
= 0; i
< g_first
->length
; i
++, g
= g
->next
)
153 shmdt(g
->linear_addr
);
154 g
->linear_addr
= NULL
;
158 g_first
->linear_count
= 0;
161 #endif /* HAVE_IPC */
165 /**********************************************************************/
176 handle
= GlobalAlloc(0, 0x40000);
177 seg_ptr
= GlobalLock(handle
);
178 lin_ptr
= GlobalLinearLock(handle
);
180 for (seg
= 0; seg
< 4; seg
++)
182 p
= (int *) ((char *) seg_ptr
+ (0x80000 * seg
));
183 for (i
= 0; i
< (0x10000 / sizeof(int)); i
++, p
++)
184 *p
= (seg
* (0x10000 / sizeof(int))) + i
;
188 for (i
= 0; i
< (0x40000 / sizeof(int)); i
++, p
++)
191 printf("lin_ptr[%x] = %x\n", i
, *p
);