Better PID allocation technique

This commit is contained in:
Dale Weiler 2015-05-21 16:23:31 -04:00
parent e27cb1b96f
commit d6ff2dc428
3 changed files with 104 additions and 8 deletions

64
kernel/ds/bitset.c Normal file
View File

@ -0,0 +1,64 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2015 Dale Weiler
*/
#include "bitset.h"
#define CEIL(NUMBER, BASE) \
(((NUMBER) + (BASE) - 1) & ~((BASE) - 1))
void bitset_init(bitset_t *set, size_t size) {
set->size = CEIL(size, 8);
set->data = malloc(set->size);
}
void bitset_free(bitset_t *set) {
free(set->data);
}
static void bitset_resize(bitset_t *set, size_t size) {
if (set->size >= size) {
return;
}
unsigned char *temp = malloc(size);
memcpy(temp, set->data, set->size);
free(set->data);
set->data = temp;
set->size = size;
}
void bitset_set(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
if (set->size <= index) {
bitset_resize(set, set->size << 1);
}
size_t offset = index & 7;
size_t mask = 1 << offset;
set->data[index] |= mask;
}
int bitset_ffub(bitset_t *set) {
for (size_t i = 0; i < set->size * 8; i++) {
if (bitset_test(set, i)) {
continue;
}
return (int)i;
}
return -1;
}
void bitset_clear(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
size_t offset = index & 7;
size_t mask = 1 << offset;
set->data[index] &= ~mask;
}
int bitset_test(bitset_t *set, size_t bit) {
size_t index = bit >> 3;
size_t offset = index & 7;
size_t mask = 1 << offset;
return mask & set->data[index];
}

20
kernel/include/bitset.h Normal file
View File

@ -0,0 +1,20 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
*/
#ifndef BITSET_H
#define BITSET_H
#include <system.h>
typedef struct {
unsigned char *data;
size_t size;
} bitset_t;
void bitset_init(bitset_t *set, size_t size);
void bitset_free(bitset_t *set);
void bitset_set(bitset_t *set, size_t bit);
void bitset_clear(bitset_t *set, size_t bit);
int bitset_test(bitset_t *set, size_t bit);
/* Find first unset bit */
int bitset_ffub(bitset_t *set);
#endif

View File

@ -3,6 +3,7 @@
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2011-2014 Kevin Lange
* Copyright (C) 2012 Markus Schober
* Copyright (C) 2015 Dale Weiler
*
* Processes
*
@ -13,6 +14,7 @@
#include <process.h>
#include <tree.h>
#include <list.h>
#include <bitset.h>
#include <logging.h>
#include <shm.h>
#include <printf.h>
@ -24,16 +26,13 @@ list_t * sleep_queue;
volatile process_t * current_process = NULL;
process_t * kernel_idle_task = NULL;
//static uint8_t volatile tree_lock = 0;
//static uint8_t volatile process_queue_lock = 0;
//static uint8_t volatile wait_lock_tmp = 0;
//static uint8_t volatile sleep_lock = 0;
static spin_lock_t tree_lock = { 0 };
static spin_lock_t process_queue_lock = { 0 };
static spin_lock_t wait_lock_tmp = { 0 };
static spin_lock_t sleep_lock = { 0 };
static bitset_t pid_set;
/* Default process name string */
char * default_name = "[unnamed]";
@ -45,6 +44,12 @@ void initialize_process_tree(void) {
process_list = list_create();
process_queue = list_create();
sleep_queue = list_create();
/* Start off with enough bits for 64 processes */
bitset_init(&pid_set, 64 / 8);
/* First two bits are set by default */
bitset_set(&pid_set, 0);
bitset_set(&pid_set, 1);
}
/*
@ -166,6 +171,8 @@ void delete_process(process_t * proc) {
list_delete(process_list, list_find(process_list, proc));
spin_unlock(tree_lock);
bitset_clear(&pid_set, proc->id);
/* Uh... */
free(proc);
}
@ -283,9 +290,14 @@ process_t * spawn_init(void) {
* @return A usable PID for a new process.
*/
pid_t get_next_pid(void) {
/* Terribly naïve, I know, but it works for now */
static pid_t next = 2;
return (next++);
int index = bitset_ffub(&pid_set);
if (index == -1) {
int next = pid_set.size * 8;
bitset_set(&pid_set, next);
return next;
}
bitset_set(&pid_set, index);
return index;
}
/*