2 static char RCSId[] = "$Id$";
3 static char Copyright[] = "Copyright Robert J. Amstadt, 1994";
8 #include "prototypes.h"
13 static key_t MemoryKeys
[SHMSEG
]; /* Keep track of keys were using */
14 static int LinearInitialized
= 0;
19 /**********************************************************************
23 LinearFindSpace(int n_segments
)
27 if (!LinearInitialized
)
29 memset(MemoryKeys
, -1, sizeof(MemoryKeys
));
33 for (i
= 0, n
= 0; i
< SHMSEG
, n
!= n_segments
; i
++)
35 if (MemoryKeys
[i
] < 0)
48 /**********************************************************************
51 * OK, this is an evil beast. We will do one of two things:
53 * 1. If the data item <= 64k, then just call GlobalLock().
54 * 2. If the data item > 64k, then map memory.
57 GlobalLinearLock(unsigned int block
)
64 /******************************************************************
65 * Get GDESC for this block.
67 g_first
= GlobalGetGDesc(block
);
71 /******************************************************************
72 * Is block less then 64k in length?
74 if (g_first
->sequence
!= 1 || g_first
->length
== 1)
76 return (void *) GlobalLock(block
);
79 /******************************************************************
80 * If there is already a linear lock on this memory, then
81 * just return a pointer to it.
83 if (g_first
->linear_count
)
85 g_first
->linear_count
++;
86 return g_first
->linear_addr
;
89 /******************************************************************
90 * No luck. We need to do the linear mapping right now.
93 loc_idx
= LinearFindSpace(g_first
->length
);
97 addr
= (unsigned long) SHM_RANGE_START
+ (0x10000 * loc_idx
);
100 i
< loc_idx
+ g_first
->length
;
101 i
++, addr
+= 0x10000, g
= g
->next
)
103 if ((MemoryKeys
[i
] = IPCCopySelector(g
->handle
>> __AHSHIFT
,
106 g
->linear_addr
= (void *) addr
;
109 #endif /* HAVE_IPC */
111 return g_first
->linear_addr
;
114 /**********************************************************************
119 GlobalLinearUnlock(unsigned int block
)
125 /******************************************************************
126 * Get GDESC for this block.
128 g_first
= GlobalGetGDesc(block
);
132 /******************************************************************
133 * Is block less then 64k in length?
135 if (g_first
->sequence
!= 1 || g_first
->length
== 1)
137 return GlobalUnlock(block
);
140 /******************************************************************
141 * Make sure we have a lock on this block.
144 if (g_first
->linear_count
> 1)
146 g_first
->linear_count
--;
148 else if (g_first
->linear_count
== 1)
151 loc_idx
= (((unsigned int) g_first
- (unsigned int) SHM_RANGE_START
)
153 for (i
= 0; i
< g_first
->length
; i
++, g
= g
->next
)
155 shmdt(g
->linear_addr
);
156 g
->linear_addr
= NULL
;
160 g_first
->linear_count
= 0;
163 #endif /* HAVE_IPC */
167 /**********************************************************************/
178 handle
= GlobalAlloc(0, 0x40000);
179 seg_ptr
= GlobalLock(handle
);
180 lin_ptr
= GlobalLinearLock(handle
);
182 for (seg
= 0; seg
< 4; seg
++)
184 p
= (int *) ((char *) seg_ptr
+ (0x80000 * seg
));
185 for (i
= 0; i
< (0x10000 / sizeof(int)); i
++, p
++)
186 *p
= (seg
* (0x10000 / sizeof(int))) + i
;
190 for (i
= 0; i
< (0x40000 / sizeof(int)); i
++, p
++)
193 printf("lin_ptr[%x] = %x\n", i
, *p
);