Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Process ID management
- * $Rev: 9 $$Date: 2009-09-30 20:09:09 +0200 (Mi, 30 Sep 2009) $
- */
- #include <types.h>
- #include <kern/errno.h>
- #include <kern/wait.h>
- #include <limits.h>
- #include <lib.h>
- #include <array.h>
- #include <clock.h>
- #include <thread.h>
- #include <current.h>
- #include <synch.h>
- #include <pid.h>
- static struct pidinfo *p_table[PROC_MAX];
- static struct lock *testlock;
- static struct cv *cv;
- volatile int counter; // counts the amount of given threads
- volatile int thread_count; // Counts the amount of threads in the table
- /*
- * pid_disown - disown any interest in waiting for a child's exit
- * status.
- */
- void
- pid_disown(pid_t theirpid)
- {
- lock_acquire(testlock);
- p_table[pid_hash(theirpid)]->interested = false;
- lock_release(testlock);
- }
- /*
- * Waits on a pid, returning the exit status when it's available.
- *
- * status may be null, in which case the status is thrown away.
- */
- int
- pid_wait(pid_t theirpid, int *status, int flags, pid_t *ret)
- {
- (void) flags;
- (void) ret;
- lock_acquire(testlock);
- if(p_table[pid_hash(theirpid)] != NULL){ // Existiert das Kind noch?
- if(p_table[pid_hash(theirpid)]->interested==true ){ //Besteht Interesse?
- if(p_table[pid_hash(curthread->th_pid)]->children == true){ // Hat der Thread ueberhaupt ein kind?
- while(p_table[pid_hash(theirpid)]->exitstatus == 1){
- cv_wait(cv, testlock);
- }
- /*Exitstatus == 0 bzw. obrige Bedingung ( exitstatus = 1 wird zu 0 )*/
- *status = p_table[pid_hash(theirpid)]->exitstatus;
- pid_unalloc(theirpid); // Child PID wird gelöscht
- }
- else {
- lock_release(testlock);
- return ECHILD; /* No child processes */
- }
- }
- }
- else{
- lock_release(testlock);
- return -1;
- }
- lock_release(testlock);
- return 0;
- }
- void
- pid_bootstrap(void)
- {
- struct pidinfo *pidinfo;
- counter = 2;
- thread_count = 1;
- if (cv==NULL){
- cv = cv_create("testlock");
- if (cv == NULL) {
- panic("pid: cv_create failed\n");
- }
- }
- if (testlock==NULL){
- testlock = lock_create("testlock");
- if (testlock == NULL) {
- panic("pid: lock_create failed\n");
- }
- }
- pidinfo = kmalloc(sizeof(struct pidinfo));
- if (pidinfo == NULL){
- return;
- }
- for(int i = 0; i < PROC_MAX; i++){
- p_table[i] = NULL;
- }
- curthread->th_pid = 1;
- p_table[1] = pidinfo;
- p_table[1]->pid = BOOTUP_PID;
- p_table[1]->ppid = INVALID_PID;
- p_table[1]->children = false;
- p_table[1]->exitstatus = 0;
- }
- int
- pid_alloc(pid_t *retval)
- {
- if(thread_count == PROC_MAX){
- return ENPROC; /* Too many processes in system */
- }
- struct pidinfo *pidinfo;
- pidinfo = kmalloc(sizeof(struct pidinfo));
- if (pidinfo == NULL) {
- return 0;
- }
- lock_acquire(testlock); // Da der counter abgefragt wird, muss gelockt werden
- while(p_table[pid_hash(counter)] != NULL){
- if(counter == PID_MAX){
- counter = PID_MIN;
- }
- else{
- counter++;
- }
- }
- ++thread_count;
- int value = pid_hash(counter);
- p_table[value] = pidinfo;
- p_table[value]->pid = counter;
- p_table[value]->ppid = curthread->th_pid;
- p_table[value]->children = false;
- p_table[pid_hash(curthread->th_pid)]->children = true;
- if(retval == NULL){
- p_table[value]->interested = false;
- p_table[value]->exitstatus = 1;
- }
- else{
- p_table[value]->interested = true;
- p_table[value]->exitstatus = 1;
- }
- *retval = p_table[value]->pid;
- lock_release(testlock);
- return 0;
- }
- void
- pid_unalloc(pid_t targetpid)
- {
- if(p_table[pid_hash(p_table[pid_hash(curthread->th_pid)]->ppid)] == NULL &&
- p_table[curthread->th_pid]->interested == false){
- int index = pid_hash(pid_hash(p_table[pid_hash(curthread->th_pid)]->ppid));
- kfree(p_table[pid_hash(p_table[pid_hash(curthread->th_pid)]->ppid)]);
- p_table[index] = NULL;
- --thread_count;
- }
- if(targetpid != 0){
- int index = pid_hash(targetpid);
- kfree(p_table[pid_hash(targetpid)]);
- p_table[index] = NULL;
- --thread_count;
- }
- // if(p_table[pid_hash(p_table[pid_hash(curthread->th_pid)]->ppid)] == NULL ){
- // if((p_table[curthread->th_pid]->interested == false) || targetpid != 0){
- // --thread_count;
- // kfree(p_table[pid_hash(targetpid)]);
- // p_table[pid_hash(targetpid)] = NULL;
- // }
- // }
- }
- void
- pid_setexitstatus(int status)
- {
- lock_acquire(testlock);
- if(status == 0){
- p_table[pid_hash(curthread->th_pid)]->exitstatus = status;
- cv_broadcast(cv, testlock);
- }
- else{
- p_table[pid_hash(curthread->th_pid)]->exitstatus = status;
- }
- lock_release(testlock);
- }
- int pid_hash(pid_t pid)
- {
- if(pid > PID_MAX){
- panic("Error: PID is invalid! It's bigger than PID_MAX");
- }
- pid=pid%PROC_MAX;
- return pid;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement