I've been using this for quite a while, and I haven't seen problems, but I am concerned about changing something as fundamental as process IDs. Does anyone have a good stress test for process creation and destruction?
Alex Pasadyn
ajp@mail.utexas.edu
ChangeLog:
- Ensure all Win32 pids generated fit in 16 bits
Index: server/process.c =================================================================== RCS file: /home/wine/wine/server/process.c,v retrieving revision 1.92 diff -u -r1.92 process.c --- server/process.c 9 Jan 2003 00:01:28 -0000 1.92 +++ server/process.c 23 Jan 2003 18:12:52 -0000 @@ -46,6 +46,7 @@ /* process structure */ static struct process *first_process; +static process_id_t last_pid; static int running_processes; /* process operations */ @@ -113,6 +114,57 @@ }; +/* generate a new (unique) process ID */ +static process_id_t make_new_process_id ( void ) +{ + struct process *p; + process_id_t new_id; + process_id_t safe_id; + process_id_t temp_id; + process_id_t min_used; + process_id_t max_used; + const process_id_t max_id = 32768; + + if (running_processes >= max_id) + { + /* no more room -- return 0 */ + return 0; + } + safe_id = 0; + new_id = (last_pid%max_id)+1; + p = first_process; + min_used = 0; + max_used = max_id; + /* assume processes are stored in ascending order */ + while (p) + { + temp_id = get_process_id(p); + if (!min_used) min_used = temp_id; + max_used = temp_id; + if (temp_id == new_id) new_id = 0; + if ( p->next && (get_process_id(p->next) != temp_id+1) ) safe_id = temp_id+1; + p = p->next; + } + if (!new_id) + { + if (max_used < max_id) + { + new_id = max_used+1; + } + else if (min_used > 1) + { + new_id = 1; + } + else + { + new_id = safe_id; + } + + } + last_pid = new_id; + return new_id; +} + /* set the state of the process startup info */ static void set_process_startup_state( struct process *process, enum startup_state state ) { @@ -188,6 +240,7 @@ struct thread *create_process( int fd ) { struct process *process; + struct process *iter; struct thread *thread = NULL; int request_pipe[2]; @@ -219,10 +272,35 @@ process->exe.namelen = 0; process->exe.filename = NULL; process->group_id = 0; + process->id = make_new_process_id(); gettimeofday( &process->start_time, NULL ); - if ((process->next = first_process) != NULL) process->next->prev = process; - first_process = process; + /* put process ids in ascending order */ + iter = first_process; + while (iter && (iter->id < process->id)) + { + if (!iter->next) + { + process->prev = iter; + } + iter = iter->next; + } + if ((process->next = iter) != NULL) + { + process->prev = iter->prev; + process->next->prev = process; + } + if (process->prev) + { + process->prev->next = process; + } + else + { + first_process = process; + } + /* must do this check AFTER adding to linked list */ + /* because destroying the process removes it from the list */ + if (!process->id) goto error; /* create the main thread */ if (pipe( request_pipe ) == -1) Index: server/process.h =================================================================== RCS file: /home/wine/wine/server/process.h,v retrieving revision 1.34 diff -u -r1.34 process.h --- server/process.h 3 Oct 2002 19:54:58 -0000 1.34 +++ server/process.h 23 Jan 2003 18:12:52 -0000 @@ -74,6 +74,7 @@ void *ldt_copy; /* pointer to LDT copy in client addr space */ void *ldt_flags; /* pointer to LDT flags in client addr space */ process_id_t group_id; /* group ID of the process */ + process_id_t id; /* the PID for this process */ }; struct process_snapshot @@ -115,7 +116,7 @@ extern struct module_snapshot *module_snap( struct process *process, int *count ); extern void enum_processes( int (*cb)(struct process*, void*), void *user); -inline static process_id_t get_process_id( struct process *process ) { return (process_id_t)process; } +inline static process_id_t get_process_id( struct process *process ) { if (process) return process->id; else return (process_id_t)process; } inline static int is_process_init_done( struct process *process ) { return process->startup_state == STARTUP_DONE;