root / Whitix / branches / hybrid / memory / shmem.c

Revision 240, 4.2 kB (checked in by mwhitworth, 6 months ago)

Add to shared memory and mmap implementations.

Line 
1/*  This file is part of Whitix.
2 *
3 *  Whitix is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  Whitix is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with Whitix; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#include <fs/vfs.h>
20#include <vmm.h>
21#include <llist.h>
22#include <malloc.h>
23#include <typedefs.h>
24#include <i386/i386.h>
25#include <slab.h>
26#include <user_acc.h>
27
28#define SHMEM_MAX_DESCS         10
29
30struct SharedMemoryDesc
31{
32        int creatorPid;
33        DWORD size;
34        DWORD* pages;
35};
36
37struct SharedMemoryDesc* shMemDescs[SHMEM_MAX_DESCS];
38
39int ShMemNoPage(struct VMArea* area, DWORD address, DWORD offset);
40int ShMemAddPage(struct VMArea* area, DWORD address);
41
42struct VmAreaOps shMemOps=
43{
44        .handleNoPage = ShMemNoPage,
45        .addPage = ShMemAddPage,
46};
47
48static struct SharedMemoryDesc* ShMemGetDesc(int i)
49{
50        if (i < 0 || i >= SHMEM_MAX_DESCS)
51                return NULL;
52
53        return shMemDescs[i];
54}
55
56int SharedMemCreate(size_t size, int flags)
57{
58        int numPages=PAGE_ALIGN_UP(size) >> PAGE_SHIFT;
59        int i, id;
60        struct SharedMemoryDesc* shDesc;
61
62        if (!numPages)
63                return -EINVAL;
64
65        /* Find an empty shared memory description slot. */
66        for (i=0; i<SHMEM_MAX_DESCS; i++)
67                /* Descriptor slot not occupied? */
68                if (!shMemDescs[i])
69                        break;
70
71        if (i == SHMEM_MAX_DESCS)
72                return -EMFILE;
73
74        shMemDescs[i]=shDesc=(struct SharedMemoryDesc*)malloc(sizeof(struct SharedMemoryDesc));
75
76        id=i;
77
78        if (!shDesc)
79                return -ENOMEM;
80
81        /* Fill in the shared memory descriptor */
82        shDesc->size=PAGE_ALIGN_UP(size);
83        shDesc->pages=(DWORD*)malloc(sizeof(DWORD)*numPages);
84
85        printf("size = %u\n", size);
86
87        if (!shDesc->pages)
88                return -ENOMEM;
89
90        for (i=0; i<numPages; i++)
91                shDesc->pages[i]=0;
92
93        return id+1;
94}
95
96int SysSharedMemoryGet(unsigned int key, size_t size, int flags)
97{
98//      printf("SysSharedMemoryGet(%d, %u)\n", key, size);
99        if (key == 0)
100                return SharedMemCreate(size, flags);
101        else{
102                printf("SysSharedMemoryGet: key > 0\n");
103                return -EINVAL;
104        }
105
106        return 0;
107}
108
109DWORD SysSharedMemoryAttach(int id, DWORD address, int flags)
110{
111        struct SharedMemoryDesc* desc=ShMemGetDesc(id-1);
112
113//      printf("%s: SysSharedMemoryAttach(%d, %#X), %#X, size = %#X\n", current->name, id, address, desc, desc->size);
114
115        if (!desc)
116                return 0;
117
118        return MMapDo(current, NULL, address, desc->size, 7, 0, MMAP_PRIVATE, &shMemOps);
119}
120
121/* FIXME: Rewrite. */
122struct SharedMemoryDesc* ShMemFind(DWORD length)
123{
124        /* FIXME: Have private field for VMArea. */
125        int i=0;
126
127        for (i=0; i<SHMEM_MAX_DESCS; i++)
128        {
129                /* FIXME: Hack! */
130                if (shMemDescs[i] && shMemDescs[i]->size == length)
131                        break;
132        }
133
134        if (i == SHMEM_MAX_DESCS)
135                return NULL;
136
137        return shMemDescs[i];
138}
139
140int ShMemAddPage(struct VMArea* area, DWORD address)
141{
142        struct SharedMemoryDesc* shMem=ShMemFind(area->length);
143        int pageIndex=(address-area->start) >> PAGE_SHIFT;
144
145        printf("pageIndex = %d\n", pageIndex);
146
147        if (!shMem)
148                return -EFAULT;
149
150        while (1);
151
152        return 0;
153}
154
155/* TODO: Try to merge with the general mmap code perhaps? */
156int ShMemNoPage(struct VMArea* area, DWORD address, DWORD offset)
157{
158        int pageIndex=offset >> PAGE_SHIFT;
159        struct SharedMemoryDesc* shMem=ShMemFind(area->length);
160
161        if (!shMem)
162                return -EFAULT;
163
164        if (!shMem->pages[pageIndex])
165                shMem->pages[pageIndex]=PageAlloc()->physAddr;
166
167        /* HACK: Need to have flag and reconsider whether should map here. */
168        struct VNode* vNode;
169
170        NameToVNode(&vNode,DEVICES_PATH "Special/Zero",0);
171
172        if (area->vNode->id == vNode->id)
173        {
174                VirtMemMapPage(address, shMem->pages[pageIndex], 7);
175                return 0;
176        }
177
178        return -EFAULT;
179}
180
181int SysSharedMemoryControl(int id, int command, void* buffer)
182{
183        printf("SysSharedMemoryControl(%d)\n", id);
184        return 0;
185}
186
187int SysSharedMemoryDetach(const void* address)
188{
189        printf("SysSharedMemoryDetach(%#X)\n", address);
190        return 0;
191}
Note: See TracBrowser for help on using the browser.