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);