Compare commits
5 Commits
c5e24e478f
...
bfcca3a220
Author | SHA1 | Date | |
---|---|---|---|
bfcca3a220 | |||
b5d146b492 | |||
b447c1a261 | |||
f8e86b3b01 | |||
d8f6af99b8 |
35
apps/gol.cpp
35
apps/gol.cpp
@ -6,6 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ static int g_fb_height;
|
|||||||
static int g_fd;
|
static int g_fd;
|
||||||
|
|
||||||
static Cell* g_cells;
|
static Cell* g_cells;
|
||||||
|
static char* g_fb;
|
||||||
|
|
||||||
static Result<void> fill_cells()
|
static Result<void> fill_cells()
|
||||||
{
|
{
|
||||||
@ -47,27 +49,29 @@ static Cell& find_cell(int row, int column)
|
|||||||
|
|
||||||
static constexpr int BYTES_PER_PIXEL = 4;
|
static constexpr int BYTES_PER_PIXEL = 4;
|
||||||
|
|
||||||
static char* g_buf;
|
|
||||||
|
|
||||||
static void draw_cells()
|
static void draw_cells()
|
||||||
{
|
{
|
||||||
lseek(g_fd, 0, SEEK_SET);
|
|
||||||
|
|
||||||
const int CELL_WIDTH = g_fb_width / g_num_columns;
|
const int CELL_WIDTH = g_fb_width / g_num_columns;
|
||||||
const int CELL_HEIGHT = g_fb_height / g_num_rows;
|
const int CELL_HEIGHT = g_fb_height / g_num_rows;
|
||||||
|
|
||||||
for (int i = 0; i < g_num_rows; i++)
|
for (int i = 0; i < g_num_rows; i++)
|
||||||
{
|
{
|
||||||
memset(g_buf, 0, g_fb_width * BYTES_PER_PIXEL);
|
|
||||||
|
|
||||||
for (int j = 0; j < g_num_columns; j++)
|
for (int j = 0; j < g_num_columns; j++)
|
||||||
{
|
{
|
||||||
auto& cell = find_cell(i, j);
|
char* buf = g_fb + (i * g_fb_width * CELL_HEIGHT * BYTES_PER_PIXEL);
|
||||||
if (cell.state) memset(g_buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), 0xff, CELL_WIDTH * BYTES_PER_PIXEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < CELL_HEIGHT; j++) { write(g_fd, g_buf, g_fb_width * BYTES_PER_PIXEL); }
|
auto& cell = find_cell(i, j);
|
||||||
|
u8 color = cell.state ? 0xff : 0x00;
|
||||||
|
for (int k = 0; k < CELL_HEIGHT; k++)
|
||||||
|
{
|
||||||
|
memset(buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), color, CELL_WIDTH * BYTES_PER_PIXEL);
|
||||||
|
buf += g_fb_width * BYTES_PER_PIXEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msync(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL, MS_SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_neighbors(int row, int column)
|
static int find_neighbors(int row, int column)
|
||||||
@ -137,7 +141,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
else
|
else
|
||||||
srand((unsigned)time(NULL));
|
srand((unsigned)time(NULL));
|
||||||
|
|
||||||
g_fd = open("/dev/fb0", O_WRONLY);
|
g_fd = open("/dev/fb0", O_RDWR);
|
||||||
if (g_fd < 0)
|
if (g_fd < 0)
|
||||||
{
|
{
|
||||||
perror("gol: cannot open framebuffer for writing");
|
perror("gol: cannot open framebuffer for writing");
|
||||||
@ -149,7 +153,13 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
TRY(fill_cells());
|
TRY(fill_cells());
|
||||||
|
|
||||||
g_buf = (char*)TRY(calloc_impl(g_fb_width, BYTES_PER_PIXEL));
|
g_fb =
|
||||||
|
(char*)mmap(nullptr, g_fb_height * g_fb_width * BYTES_PER_PIXEL, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
|
||||||
|
if (g_fb == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("gol: cannot map framebuffer into memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
draw_cells();
|
draw_cells();
|
||||||
|
|
||||||
@ -162,5 +172,8 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
usleep(delay_at_end * 1000);
|
usleep(delay_at_end * 1000);
|
||||||
|
|
||||||
|
munmap(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL);
|
||||||
|
free(g_cells);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,11 @@ class Device : public Shareable
|
|||||||
|
|
||||||
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
|
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
|
||||||
|
|
||||||
|
virtual Result<u64> query_shared_memory(off_t, usize)
|
||||||
|
{
|
||||||
|
return err(EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
virtual Result<u64> ioctl(int, void*)
|
virtual Result<u64> ioctl(int, void*)
|
||||||
{
|
{
|
||||||
return err(ENOTTY);
|
return err(ENOTTY);
|
||||||
@ -44,4 +49,7 @@ class Device : public Shareable
|
|||||||
virtual bool will_block_if_read() const = 0;
|
virtual bool will_block_if_read() const = 0;
|
||||||
|
|
||||||
virtual ~Device() = default;
|
virtual ~Device() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Option<u64> m_shmid;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "fs/devices/FramebufferDevice.h"
|
#include "fs/devices/FramebufferDevice.h"
|
||||||
|
#include "arch/MMU.h"
|
||||||
|
#include "memory/SharedMemory.h"
|
||||||
#include "video/Framebuffer.h"
|
#include "video/Framebuffer.h"
|
||||||
#include <bits/ioctl-defs.h>
|
#include <bits/ioctl-defs.h>
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
@ -23,6 +25,32 @@ Result<usize> FramebufferDevice::write(const u8* buf, usize offset, usize length
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> FramebufferDevice::query_shared_memory(off_t offset, usize count)
|
||||||
|
{
|
||||||
|
if (offset + (count * ARCH_PAGE_SIZE) > Framebuffer::size()) return err(EINVAL);
|
||||||
|
|
||||||
|
if (!m_shmid.has_value())
|
||||||
|
{
|
||||||
|
u64 shmid = TRY(SharedMemory::create(Framebuffer::ptr() + offset, offset, count));
|
||||||
|
m_shmid = shmid;
|
||||||
|
auto* shm = g_shared_memory_map.try_get_ref(shmid);
|
||||||
|
shm->device = SharedPtr<Device> { this };
|
||||||
|
return shmid;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* shm = g_shared_memory_map.try_get_ref(*m_shmid);
|
||||||
|
if (shm->offset > offset)
|
||||||
|
{
|
||||||
|
TRY(shm->grow_backward(Framebuffer::ptr() + offset, (shm->offset - offset) / ARCH_PAGE_SIZE));
|
||||||
|
}
|
||||||
|
if (shm->frames.size() < count)
|
||||||
|
{
|
||||||
|
TRY(shm->grow_forward(Framebuffer::ptr() + offset + (shm->frames.size() * ARCH_PAGE_SIZE),
|
||||||
|
count - shm->frames.size()));
|
||||||
|
}
|
||||||
|
return *m_shmid;
|
||||||
|
}
|
||||||
|
|
||||||
usize FramebufferDevice::size() const
|
usize FramebufferDevice::size() const
|
||||||
{
|
{
|
||||||
return Framebuffer::size();
|
return Framebuffer::size();
|
||||||
|
@ -11,6 +11,8 @@ class FramebufferDevice : public Device
|
|||||||
|
|
||||||
Result<usize> write(const u8*, usize, usize) override;
|
Result<usize> write(const u8*, usize, usize) override;
|
||||||
|
|
||||||
|
Result<u64> query_shared_memory(off_t offset, usize count) override;
|
||||||
|
|
||||||
bool will_block_if_read() const override;
|
bool will_block_if_read() const override;
|
||||||
|
|
||||||
bool is_block_device() const override
|
bool is_block_device() const override
|
||||||
|
@ -138,6 +138,8 @@ namespace TmpFS
|
|||||||
{
|
{
|
||||||
u64 shmid = TRY(SharedMemory::create(m_data_buffer.data() + offset, offset, count));
|
u64 shmid = TRY(SharedMemory::create(m_data_buffer.data() + offset, offset, count));
|
||||||
m_shmid = shmid;
|
m_shmid = shmid;
|
||||||
|
auto* shm = g_shared_memory_map.try_get_ref(shmid);
|
||||||
|
shm->inode = SharedPtr<VFS::Inode> { (VFS::Inode*)this };
|
||||||
return shmid;
|
return shmid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +154,11 @@ namespace TmpFS
|
|||||||
m_metadata.devid = id;
|
m_metadata.devid = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> query_shared_memory(off_t offset, usize count) override
|
||||||
|
{
|
||||||
|
return m_device->query_shared_memory(offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
VFS::FileSystem* fs() const override
|
VFS::FileSystem* fs() const override
|
||||||
{
|
{
|
||||||
return m_fs;
|
return m_fs;
|
||||||
|
@ -304,6 +304,10 @@ void VMRegion::sync_shared()
|
|||||||
if (used && (flags & MAP_SHARED) && (prot & PROT_WRITE))
|
if (used && (flags & MAP_SHARED) && (prot & PROT_WRITE))
|
||||||
{
|
{
|
||||||
SharedMemory* shmem = g_shared_memory_map.try_get_ref(shmid);
|
SharedMemory* shmem = g_shared_memory_map.try_get_ref(shmid);
|
||||||
if (shmem) { shmem->inode->write((const u8*)start, offset, count * ARCH_PAGE_SIZE); }
|
if (shmem)
|
||||||
|
{
|
||||||
|
if (shmem->inode) shmem->inode->write((const u8*)start, offset, count * ARCH_PAGE_SIZE);
|
||||||
|
if (shmem->device) shmem->device->write((const u8*)start, offset, count * ARCH_PAGE_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "fs/VFS.h"
|
#include "fs/VFS.h"
|
||||||
|
#include "fs/devices/Device.h"
|
||||||
#include <luna/HashMap.h>
|
#include <luna/HashMap.h>
|
||||||
#include <luna/Vector.h>
|
#include <luna/Vector.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -10,6 +11,7 @@ struct SharedMemory
|
|||||||
off_t offset;
|
off_t offset;
|
||||||
int prot;
|
int prot;
|
||||||
SharedPtr<VFS::Inode> inode {};
|
SharedPtr<VFS::Inode> inode {};
|
||||||
|
SharedPtr<Device> device {};
|
||||||
int refs { 0 };
|
int refs { 0 };
|
||||||
|
|
||||||
static Result<u64> create(u8* mem, off_t offset, usize count);
|
static Result<u64> create(u8* mem, off_t offset, usize count);
|
||||||
|
@ -46,7 +46,7 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((params.prot & PROT_WRITE) && !(description->flags & O_WRONLY)) return err(EACCES);
|
if ((params.prot & PROT_WRITE) && !(description->flags & O_WRONLY)) return err(EACCES);
|
||||||
shmid = TRY(description->inode->query_shared_memory(params.offset, params.len));
|
shmid = TRY(description->inode->query_shared_memory(params.offset, params.len / ARCH_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
shmem = g_shared_memory_map.try_get_ref(shmid);
|
shmem = g_shared_memory_map.try_get_ref(shmid);
|
||||||
shmem->refs++;
|
shmem->refs++;
|
||||||
@ -72,10 +72,10 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
if (params.prot == PROT_NONE) mmu_flags = MMU::NoExecute;
|
if (params.prot == PROT_NONE) mmu_flags = MMU::NoExecute;
|
||||||
|
|
||||||
#ifdef MMAP_DEBUG
|
#ifdef MMAP_DEBUG
|
||||||
kdbgln("mmap: mapping memory at %#lx, size=%zu", address, len);
|
kdbgln("mmap: mapping memory at %#lx, size=%zu", address, params.len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (shmem) { TRY(shmem->map(address, mmu_flags, params.offset, get_blocks_from_size(params.len, ARCH_PAGE_SIZE))); }
|
if (shmem) { TRY(shmem->map(address, mmu_flags, params.offset, params.len / ARCH_PAGE_SIZE)); }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRY(MemoryManager::alloc_at_zeroed(address, get_blocks_from_size(params.len, ARCH_PAGE_SIZE), mmu_flags));
|
TRY(MemoryManager::alloc_at_zeroed(address, get_blocks_from_size(params.len, ARCH_PAGE_SIZE), mmu_flags));
|
||||||
|
Loading…
Reference in New Issue
Block a user