Move list of semaphores inside semid_ds structure.

This commit is contained in:
Enrico Fraccaroli (Galfurian)
2023-05-24 13:31:44 -04:00
parent 1acec3e7b3
commit db050db01c
7 changed files with 103 additions and 120 deletions
+3
View File
@@ -117,3 +117,6 @@ files/bin/**
# ISO creation files. # ISO creation files.
iso/boot/*.bin iso/boot/*.bin
# ClangD stuff.
.cache
-8
View File
@@ -1,8 +0,0 @@
{
"files.associations": {
"*.h": "c",
"*.c": "c"
},
"cmake.configureOnOpen": false,
"C_Cpp.intelliSenseEngine" : "Tag Parser"
}
+2
View File
@@ -63,6 +63,8 @@ struct semid_ds {
time_t sem_otime; time_t sem_otime;
/// @brief Last change time. /// @brief Last change time.
time_t sem_ctime; time_t sem_ctime;
/// @brief List of all the semaphores.
struct sem *sem_base;
/// @brief Number of semaphores in set. /// @brief Number of semaphores in set.
unsigned short sem_nsems; unsigned short sem_nsems;
}; };
+41 -49
View File
@@ -60,8 +60,6 @@ typedef struct {
int id; int id;
/// @brief The semaphore data strcutre. /// @brief The semaphore data strcutre.
struct semid_ds semid; struct semid_ds semid;
/// @brief List of all the semaphores.
struct sem *sems;
/// Reference inside the list of semaphore management structures. /// Reference inside the list of semaphore management structures.
list_head list; list_head list;
} sem_info_t; } sem_info_t;
@@ -106,11 +104,11 @@ static inline sem_info_t *__sem_info_alloc(key_t key, int nsems, int semflg)
// Clean the memory. // Clean the memory.
memset(sem_info, 0, sizeof(sem_info_t)); memset(sem_info, 0, sizeof(sem_info_t));
// Allocate the memory for semaphores. // Allocate the memory for semaphores.
sem_info->sems = (struct sem *)kmalloc(sizeof(struct sem) * nsems); sem_info->semid.sem_base = (struct sem *)kmalloc(sizeof(struct sem) * nsems);
// Check the allocated memory. // Check the allocated memory.
assert(sem_info->sems && "Failed to allocate memory for a set of semaphores."); assert(sem_info->semid.sem_base && "Failed to allocate memory for a set of semaphores.");
// Clean the memory. // Clean the memory.
memset(sem_info->sems, 0, sizeof(struct sem) * nsems); memset(sem_info->semid.sem_base, 0, sizeof(struct sem) * nsems);
// Initialize its values. // Initialize its values.
sem_info->id = ++__sem_id; sem_info->id = ++__sem_id;
sem_info->semid.sem_perm = register_ipc(key, semflg & 0x1FF); sem_info->semid.sem_perm = register_ipc(key, semflg & 0x1FF);
@@ -118,10 +116,10 @@ static inline sem_info_t *__sem_info_alloc(key_t key, int nsems, int semflg)
sem_info->semid.sem_ctime = 0; sem_info->semid.sem_ctime = 0;
sem_info->semid.sem_nsems = nsems; sem_info->semid.sem_nsems = nsems;
for (int i = 0; i < nsems; i++) { for (int i = 0; i < nsems; i++) {
sem_info->sems[i].sem_pid = sys_getpid(); sem_info->semid.sem_base[i].sem_pid = sys_getpid();
sem_info->sems[i].sem_val = 0; sem_info->semid.sem_base[i].sem_val = 0;
sem_info->sems[i].sem_ncnt = 0; sem_info->semid.sem_base[i].sem_ncnt = 0;
sem_info->sems[i].sem_zcnt = 0; sem_info->semid.sem_base[i].sem_zcnt = 0;
} }
// Return the semaphore management structure. // Return the semaphore management structure.
return sem_info; return sem_info;
@@ -133,7 +131,7 @@ static inline void __sem_info_dealloc(sem_info_t *sem_info)
{ {
assert(sem_info && "Received a NULL pointer."); assert(sem_info && "Received a NULL pointer.");
// Deallocate the array of semaphores. // Deallocate the array of semaphores.
kfree(sem_info->sems); kfree(sem_info->semid.sem_base);
// Deallocate the semid memory. // Deallocate the semid memory.
kfree(sem_info); kfree(sem_info);
} }
@@ -305,14 +303,14 @@ long sys_semop(int semid, struct sembuf *sops, unsigned nsops)
// If the operation is negative then we need to check for possible blocking // If the operation is negative then we need to check for possible blocking
// operation. If the value of the sem were to become negative then we return // operation. If the value of the sem were to become negative then we return
// a special value. // a special value.
if (((int)sem_info->sems[sops->sem_num].sem_val + (int)sops->sem_op) < 0) { if (((int)sem_info->semid.sem_base[sops->sem_num].sem_val + (int)sops->sem_op) < 0) {
// The value would become negative, we cannot perform the operation. // The value would become negative, we cannot perform the operation.
return -EAGAIN; return -EAGAIN;
} }
// Update the semaphore value. // Update the semaphore value.
sem_info->sems[sops->sem_num].sem_val += sops->sem_op; sem_info->semid.sem_base[sops->sem_num].sem_val += sops->sem_op;
// Update the pid of the process that did last op. // Update the pid of the process that did last op.
sem_info->sems[sops->sem_num].sem_pid = sys_getpid(); sem_info->semid.sem_base[sops->sem_num].sem_pid = sys_getpid();
// Update the time. // Update the time.
sem_info->semid.sem_ctime = sys_time(NULL); sem_info->semid.sem_ctime = sys_time(NULL);
return 0; return 0;
@@ -321,6 +319,7 @@ long sys_semop(int semid, struct sembuf *sops, unsigned nsops)
long sys_semctl(int semid, int semnum, int cmd, union semun *arg) long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
{ {
sem_info_t *sem_info = NULL; sem_info_t *sem_info = NULL;
task_struct *task = NULL;
// Search for the semaphore. // Search for the semaphore.
sem_info = __list_find_sem_info_by_id(semid); sem_info = __list_find_sem_info_by_id(semid);
// The semaphore set doesn't exist. // The semaphore set doesn't exist.
@@ -328,15 +327,14 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
pr_err("The semaphore set doesn't exist.\n"); pr_err("The semaphore set doesn't exist.\n");
return -EINVAL; return -EINVAL;
} }
// Get the calling task. // Get the calling task.
task_struct *task = scheduler_get_current_process(); task = scheduler_get_current_process();
assert(task && "Failed to get the current running process."); assert(task && "Failed to get the current running process.");
switch (cmd) { if (cmd == IPC_RMID) {
// Remove the semaphore set; any processes blocked is awakened (errno set to // Remove the semaphore set; any processes blocked is awakened (errno set to
// EIDRM); no argument required. // EIDRM); no argument required.
case IPC_RMID:
if ((sem_info->semid.sem_perm.uid != task->uid) && (sem_info->semid.sem_perm.cuid != task->uid)) { if ((sem_info->semid.sem_perm.uid != task->uid) && (sem_info->semid.sem_perm.cuid != task->uid)) {
pr_err("The calling process is not the creator or the owner of the semaphore set.\n"); pr_err("The calling process is not the creator or the owner of the semaphore set.\n");
return -EPERM; return -EPERM;
@@ -345,11 +343,10 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
__list_remove_sem_info(sem_info); __list_remove_sem_info(sem_info);
// Delete the set. // Delete the set.
__sem_info_dealloc(sem_info); __sem_info_dealloc(sem_info);
break; } else if (cmd == SETVAL) {
// The value of the semnum-th semaphore in the set is initialized to the // The value of the semnum-th semaphore in the set is initialized to the
// value specified in arg.val. // value specified in arg.val.
case SETVAL:
// Check if the index is valid. // Check if the index is valid.
if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) { if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) {
pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems); pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems);
@@ -371,14 +368,13 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
return -EACCES; return -EACCES;
} }
// Setting the value. // Setting the value.
sem_info->sems[semnum].sem_val = arg->val; sem_info->semid.sem_base[semnum].sem_val = arg->val;
// Update the last change time. // Update the last change time.
sem_info->semid.sem_ctime = sys_time(NULL); sem_info->semid.sem_ctime = sys_time(NULL);
return 0; } else if (cmd == SETALL) {
// Initialize all semaphore in the set referred to by semid, using the // Initialize all semaphore in the set referred to by semid, using the
// values supplied in the array pointed to by arg.array. // values supplied in the array pointed to by arg.array.
case SETALL:
// Check if the argument is a null pointer. // Check if the argument is a null pointer.
if (!arg) { if (!arg) {
pr_err("The argument is NULL.\n"); pr_err("The argument is NULL.\n");
@@ -396,15 +392,14 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
} }
// Setting the values. // Setting the values.
for (unsigned i = 0; i < sem_info->semid.sem_nsems; ++i) { for (unsigned i = 0; i < sem_info->semid.sem_nsems; ++i) {
sem_info->sems[i].sem_val = arg->array[i]; sem_info->semid.sem_base[i].sem_val = arg->array[i];
} }
// Update the last change time. // Update the last change time.
sem_info->semid.sem_ctime = sys_time(NULL); sem_info->semid.sem_ctime = sys_time(NULL);
return 0; } else if (cmd == IPC_STAT) {
// Place a copy of the semid_ds data structure in the buffer pointed to by // Place a copy of the semid_ds data structure in the buffer pointed to by
// arg.buf. // arg.buf.
case IPC_STAT:
// Check if the argument is a null pointer. // Check if the argument is a null pointer.
if (!arg) { if (!arg) {
pr_err("The argument is NULL.\n"); pr_err("The argument is NULL.\n");
@@ -422,11 +417,10 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
} }
// Copying all the data. // Copying all the data.
memcpy(arg->buf, &sem_info->semid, sizeof(struct semid_ds)); memcpy(arg->buf, &sem_info->semid, sizeof(struct semid_ds));
return 0; } else if (cmd == GETALL) {
// Retrieve the values of all of the semaphores in the set referred to by // Retrieve the values of all of the semaphores in the set referred to by
// semid, placing them in the array pointed to by arg.array. // semid, placing them in the array pointed to by arg.array.
case GETALL:
// Check if the argument is a null pointer. // Check if the argument is a null pointer.
if (!arg) { if (!arg) {
pr_err("The argument is NULL.\n"); pr_err("The argument is NULL.\n");
@@ -438,12 +432,12 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
return -EINVAL; return -EINVAL;
} }
for (unsigned i = 0; i < sem_info->semid.sem_nsems; ++i) { for (unsigned i = 0; i < sem_info->semid.sem_nsems; ++i) {
arg->array[i] = sem_info->sems[i].sem_val; arg->array[i] = sem_info->semid.sem_base[i].sem_val;
} }
return 0; } else if (cmd == GETVAL) {
// Returns the value of the semnum-th semaphore in the set specified by // Returns the value of the semnum-th semaphore in the set specified by
// semid; no argument required. // semid; no argument required.
case GETVAL:
// Check if the index is valid. // Check if the index is valid.
if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) { if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) {
pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems); pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems);
@@ -454,10 +448,11 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
pr_err("The calling process does not have read permission to access the set.\n"); pr_err("The calling process does not have read permission to access the set.\n");
return -EACCES; return -EACCES;
} }
return sem_info->sems[semnum].sem_val; return sem_info->semid.sem_base[semnum].sem_val;
} else if (cmd == GETPID) {
// Return the process ID of the last process to perform a semop on the // Return the process ID of the last process to perform a semop on the
// semnum-th semaphore. // semnum-th semaphore.
case GETPID:
// Check if the index is valid. // Check if the index is valid.
if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) { if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) {
pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems); pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems);
@@ -468,10 +463,11 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
pr_err("The calling process does not have read permission to access the set.\n"); pr_err("The calling process does not have read permission to access the set.\n");
return -EACCES; return -EACCES;
} }
return sem_info->sems[semnum].sem_pid; return sem_info->semid.sem_base[semnum].sem_pid;
} else if (cmd == GETNCNT) {
// Return the number of processes currently waiting for the resources to // Return the number of processes currently waiting for the resources to
// become available. // become available.
case GETNCNT:
// Check if the index is valid. // Check if the index is valid.
if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) { if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) {
pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems); pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems);
@@ -482,10 +478,11 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
pr_err("The calling process does not have read permission to access the set.\n"); pr_err("The calling process does not have read permission to access the set.\n");
return -EACCES; return -EACCES;
} }
return sem_info->sems[semnum].sem_ncnt; return sem_info->semid.sem_base[semnum].sem_ncnt;
} else if (cmd == GETZCNT) {
// Return the number of processes currently waiting for the value of the // Return the number of processes currently waiting for the value of the
// semnum-th semaphore to become 0. // semnum-th semaphore to become 0.
case GETZCNT:
// Check if the index is valid. // Check if the index is valid.
if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) { if ((semnum < 0) || (semnum >= (sem_info->semid.sem_nsems))) {
pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems); pr_err("Semaphore number out of bound (%d not in [%d, %d])\n", semnum, 0, sem_info->semid.sem_nsems);
@@ -496,21 +493,16 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
pr_err("The calling process does not have read permission to access the set.\n"); pr_err("The calling process does not have read permission to access the set.\n");
return -EACCES; return -EACCES;
} }
return sem_info->sems[semnum].sem_zcnt; return sem_info->semid.sem_base[semnum].sem_zcnt;
} else if (cmd == SEM_STAT) {
case SEM_STAT:
pr_err("Not implemented.\n"); pr_err("Not implemented.\n");
return -ENOSYS; return -ENOSYS;
} else if (cmd == SEM_INFO) {
case SEM_INFO:
pr_err("Not implemented.\n"); pr_err("Not implemented.\n");
return -ENOSYS; return -ENOSYS;
} else {
// Not a valid argument.
default:
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
} }
-1
View File
@@ -412,7 +412,6 @@ ssize_t procipc_shm_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte
return -ENOENT; return -ENOENT;
} }
size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0; size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0;
struct semid_ds *entry = NULL;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
// Prepare a buffer. // Prepare a buffer.
-2
View File
@@ -74,8 +74,6 @@ int main(int argc, char **argv)
ret = semctl(semid, 0, IPC_STAT, &temp); ret = semctl(semid, 0, IPC_STAT, &temp);
// Check if we succeded. // Check if we succeded.
if (!ret) { if (!ret) {
//ret = semctl(atoi(argv[2]), 0, GETNSEMS, NULL);
//temp.buf->sems = (struct sem *)malloc(sizeof(struct sem) * ret);
printf("key semid owner perms nsems\n"); printf("key semid owner perms nsems\n");
printf("%10d %10d %10d %10d %d\n", sem.sem_perm.key, semid, sem.sem_perm.uid, sem.sem_perm.mode, sem.sem_nsems); printf("%10d %10d %10d %10d %d\n", sem.sem_perm.key, semid, sem.sem_perm.uid, sem.sem_perm.mode, sem.sem_nsems);
return 0; return 0;
-3
View File
@@ -53,9 +53,6 @@ static inline void __iterate_proc_dirs(int proc_fd)
strcat(absolute_path, "/stat"); strcat(absolute_path, "/stat");
// Open the `/proc/<pid>/stat` file. // Open the `/proc/<pid>/stat` file.
if ((stat_fd = open(absolute_path, O_RDONLY, 0)) == -1) { if ((stat_fd = open(absolute_path, O_RDONLY, 0)) == -1) {
printf("Failed to open `%s`: ", absolute_path);
perror(NULL);
putchar('\n');
continue; continue;
} }
// Reset the stat buffer. // Reset the stat buffer.