Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 152 additions & 5 deletions kern/mem/shared_memory_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,24 @@ inline struct FrameInfo** create_frames_storage(int numOfFrames)
{
//TODO: [PROJECT'24.MS2 - #16] [4] SHARED MEMORY - create_frames_storage()
//COMMENT THE FOLLOWING LINE BEFORE START CODING
panic("create_frames_storage is not implemented yet");
//panic("create_frames_storage is not implemented yet");
//Your Code is Here...

if(numOfFrames <= 0){
return NULL;
}

//cprintf("numbers of frames:%d\n", numOfFrames);
//cprintf("size of frames info%d\n", (uint32)sizeof(struct FrameInfo*));
struct FrameInfo** FramesArr = (struct FrameInfo**)kmalloc(sizeof(char)*numOfFrames);

// if allocation failed -> return NULL
if(FramesArr == NULL)
return NULL;
// initialize to zeros
memset(FramesArr, 0, sizeof(char)*numOfFrames);
return FramesArr;

}

//=====================================
Expand All @@ -81,9 +96,39 @@ struct Share* create_share(int32 ownerID, char* shareName, uint32 size, uint8 is
{
//TODO: [PROJECT'24.MS2 - #16] [4] SHARED MEMORY - create_share()
//COMMENT THE FOLLOWING LINE BEFORE START CODING
panic("create_share is not implemented yet");
//panic("create_share is not implemented yet");
//Your Code is Here...

struct Share* newShare = (struct Share *)kmalloc(sizeof(struct Share));
if(newShare == NULL){
return NULL;
}
uint32 nameSize = sizeof(newShare->name);
if (sizeof(shareName) < nameSize)
nameSize = sizeof(shareName);
// setup data
newShare->ID = (int32)newShare & 0x7FFFFFFF; //address of object + masking the MSB (make it +ve)
newShare->ownerID = ownerID;
uint32 i;
for(i = 0; i < nameSize; i++){
(newShare->name)[i] = shareName[i];
}
// pad with null terminator
for(; i < sizeof(newShare->name); i++)
(newShare->name)[i] = '\0';
//
//strcpy((new_object->name),shareName); // not safe
newShare->size = size;
newShare->isWritable = isWritable;
newShare->references = 1;
newShare->framesStorage = create_frames_storage(ROUNDUP(size/PAGE_SIZE, PAGE_SIZE));
// if allocating frames failed -> return null
if(newShare->framesStorage == NULL){
kfree(newShare);
return NULL;
}

return newShare;
}

//=============================
Expand All @@ -97,9 +142,24 @@ struct Share* get_share(int32 ownerID, char* name)
{
//TODO: [PROJECT'24.MS2 - #17] [4] SHARED MEMORY - get_share()
//COMMENT THE FOLLOWING LINE BEFORE START CODING
panic("get_share is not implemented yet");
//panic("get_share is not implemented yet");
//Your Code is Here...
acquire_spinlock(&AllShares.shareslock);

struct Share *desiredObject = NULL;
struct Share *currentOb = NULL;

LIST_FOREACH(currentOb, &(AllShares.shares_list)){
if(strcmp((currentOb->name), name)==0 && (currentOb->ownerID) == ownerID){
//cprintf("found obj");
desiredObject = currentOb;
break;
}
}

release_spinlock(&AllShares.shareslock);

return desiredObject;
}

//=========================
Expand All @@ -109,10 +169,70 @@ int createSharedObject(int32 ownerID, char* shareName, uint32 size, uint8 isWrit
{
//TODO: [PROJECT'24.MS2 - #19] [4] SHARED MEMORY [KERNEL SIDE] - createSharedObject()
//COMMENT THE FOLLOWING LINE BEFORE START CODING
panic("createSharedObject is not implemented yet");
//panic("createSharedObject is not implemented yet");
//Your Code is Here...

struct Env* myenv = get_cpu_proc(); //The calling environment

struct Share *isObjectExist = get_share(ownerID,shareName);
//cprintf("Owner with ID %d want to create obj with name: %s\n", ownerID, shareName);
//cprintf("\n Object value: %x\n", isObjectExist);
if(isObjectExist == NULL)
{
uint32 totalSpace = (uint32)virtual_address + size;
uint32 endOfObject = ROUNDUP(totalSpace,PAGE_SIZE);
// uint32 endOfObject = (uint32)virtual_address + size;
struct Share *new_object = create_share(ownerID,shareName,size,isWritable);

//check if the object created and allocated successfully
if(new_object != NULL)
{
int frameIndex = 0;
for(uint32 currentV = (uint32)virtual_address; currentV < endOfObject; currentV += PAGE_SIZE)
{
struct FrameInfo *objectFrame = NULL;
int check = allocate_frame(&(objectFrame));
if(check == E_NO_MEM)
{
//panic("There is no enough memory!");
// free allocated frames
uint32 startVa = (uint32)virtual_address;
while(currentV >= startVa){
frameIndex--;
currentV-=PAGE_SIZE;
new_object->framesStorage[frameIndex] = NULL;
unmap_frame((myenv->env_page_directory), currentV);
}

return E_NO_SHARE;
}

//map each VA to frame and add the frame to framesStorage array
map_frame((myenv->env_page_directory),objectFrame,currentV,PERM_USER | PERM_WRITEABLE);
new_object->framesStorage[frameIndex] = objectFrame;
frameIndex++;
}
//cprintf("virtual_address%p , endOfObject:%p frameIndex:%d\n",virtual_address,endOfObject,frameIndex);

//add the new object to the shared list
acquire_spinlock(&(AllShares.shareslock));
LIST_INSERT_TAIL(&(AllShares.shares_list), new_object);
release_spinlock(&(AllShares.shareslock));

return new_object->ID;
}

else
{
return E_NO_SHARE;
}
}

else
{
return E_SHARED_MEM_EXISTS;
}

}


Expand All @@ -123,10 +243,37 @@ int getSharedObject(int32 ownerID, char* shareName, void* virtual_address)
{
//TODO: [PROJECT'24.MS2 - #21] [4] SHARED MEMORY [KERNEL SIDE] - getSharedObject()
//COMMENT THE FOLLOWING LINE BEFORE START CODING
panic("getSharedObject is not implemented yet");
//panic("getSharedObject is not implemented yet");
//Your Code is Here...

struct Env* myenv = get_cpu_proc(); //The calling environment

struct Share *requestedObject = get_share(ownerID,shareName);
if(requestedObject != NULL)
{
uint8 isWrite = 0;
if(requestedObject->isWritable)
isWrite = PERM_WRITEABLE;
int count = 0;
struct FrameInfo *sharedFrame;
uint32 VA = (uint32)virtual_address;
int numOfFrames = sizeof(requestedObject->framesStorage)/sizeof(requestedObject->framesStorage[0]);
while(count < numOfFrames)
{
sharedFrame = requestedObject->framesStorage[count];
//map each page to each shared frame with the permission isWritable
map_frame((myenv->env_page_directory), sharedFrame, VA+(count*PAGE_SIZE), PERM_USER | isWrite);
count++;
}

//update the references
requestedObject->references++;
return requestedObject->ID;
}

//return if the object does not exist
return E_SHARED_MEM_NOT_EXISTS;

}

//==================================================================================//
Expand Down
97 changes: 91 additions & 6 deletions lib/uheap.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void free(void* virtual_address)
// uint32 page_index = (va - myEnv->rlimit) / PAGE_SIZE;
uint32 page_index = (va - USER_HEAP_START) / PAGE_SIZE;


// Find how many pages were allocated for the given virtual address
uint32 num_pages = 0;
while (page_allocation_status[page_index + num_pages] == page_index) {
Expand All @@ -133,15 +133,15 @@ void free(void* virtual_address)
for (uint32 i = 0; i < num_pages; i++) {
page_allocation_status[page_index + i] = 0;
}

// Call the system function to free the user memory and page file
sys_free_user_mem(va, num_pages * PAGE_SIZE);
}
}
}
else {
panic("Invalid address: Address is not allocated.");
}

}
//=================================
// [4] ALLOCATE SHARED VARIABLE:
Expand All @@ -154,7 +154,44 @@ void* smalloc(char *sharedVarName, uint32 size, uint8 isWritable)
//==============================================================
//TODO: [PROJECT'24.MS2 - #18] [4] SHARED MEMORY [USER SIDE] - smalloc()
// Write your code here, remove the panic and write your code
panic("smalloc() is not implemented yet...!!");
// panic("smalloc() is not implemented yet...!!");
uint32 num_pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; // Round up to nearest page

// Page Allocator for larger allocations
uint32 required_size = num_pages * PAGE_SIZE; // Total required size in bytes
// First-Fit Strategy
for (uint32 addr = myEnv->rlimit+PAGE_SIZE; addr + required_size <= USER_HEAP_MAX - PAGE_SIZE; addr += PAGE_SIZE)
{
uint32 index = (addr - USER_HEAP_START) / PAGE_SIZE;
uint8 is_free = 1;
// // Check if all pages in the range are free
for (uint32 i = 0; i < num_pages; i++)
{
if (page_allocation_status[index + i] != 0)
{
is_free = 0;
break;
}
}
// cprintf("addr: %p , pagestatus[idx] %d\n", addr, page_allocation_status[index]);
// if(page_allocation_status[index ] == 0 ) return (void*)addr;
if (is_free)
{
// Mark the pages as allocated
for (uint32 i = 0; i < num_pages; i++)
{
page_allocation_status[index + i] = index;
}

uint32 sharedObjId = sys_createSharedObject(sharedVarName,required_size,isWritable,(void*)addr);
if(sharedObjId == E_SHARED_MEM_EXISTS){
//cprintf("exists\n");
return NULL;
}

return (void*)addr;
}
}
return NULL;
}

Expand All @@ -165,8 +202,56 @@ void* sget(int32 ownerEnvID, char *sharedVarName)
{
//TODO: [PROJECT'24.MS2 - #20] [4] SHARED MEMORY [USER SIDE] - sget()
// Write your code here, remove the panic and write your code
panic("sget() is not implemented yet...!!");
// panic("sget() is not implemented yet...!!");
//return NULL;

// get obj size
uint32 size = sys_getSizeOfSharedObject(ownerEnvID, sharedVarName);
if(size == (uint32)NULL){
return NULL;
}

// find space in current process virtual memory
uint32 num_pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; // Round up to nearest page
// Page Allocator for larger allocations
uint32 required_size = num_pages * PAGE_SIZE; // Total required size in bytes
// First-Fit Strategy
for (uint32 addr = myEnv->rlimit+PAGE_SIZE; addr + required_size <= USER_HEAP_MAX - PAGE_SIZE; addr += PAGE_SIZE)
{
uint32 index = (addr - USER_HEAP_START) / PAGE_SIZE;
uint8 is_free = 1;
// // Check if all pages in the range are free
for (uint32 i = 0; i < num_pages; i++)
{
if (page_allocation_status[index + i] != 0)
{
is_free = 0;
break;
}
}
// cprintf("addr: %p , pagestatus[idx] %d\n", addr, page_allocation_status[index]);
// if(page_allocation_status[index ] == 0 ) return (void*)addr;
// found enough space in VM
if (is_free)
{
// Mark the pages as allocated
for (uint32 i = 0; i < num_pages; i++)
{
page_allocation_status[index + i] = index;
}

uint32 sharedObjId = sys_getSharedObject(ownerEnvID, sharedVarName, (void*)addr);
if(sharedObjId == E_SHARED_MEM_NOT_EXISTS){
return NULL;
}

return (void*)addr;
}
}

// If no space in vm
return NULL;

}


Expand Down