};
+struct ptid_entry
+{
+ void *ptr; /* entry ptr */
+ unsigned int next; /* next free entry */
+};
+
+static struct ptid_entry *ptid_entries; /* array of ptid entries */
+static unsigned int used_ptid_entries; /* number of entries in use */
+static unsigned int alloc_ptid_entries; /* number of allocated entries */
+static unsigned int next_free_ptid; /* next free entry */
+static unsigned int last_free_ptid; /* last free entry */
+
+#define PTID_OFFSET 8 /* offset for first ptid value */
+
+/* allocate a new process or thread id */
+unsigned int alloc_ptid( void *ptr )
+{
+ struct ptid_entry *entry;
+ unsigned int id;
+
+ if (used_ptid_entries < alloc_ptid_entries)
+ {
+ id = used_ptid_entries + PTID_OFFSET;
+ entry = &ptid_entries[used_ptid_entries++];
+ }
+ else if (next_free_ptid)
+ {
+ id = next_free_ptid;
+ entry = &ptid_entries[id - PTID_OFFSET];
+ if (!(next_free_ptid = entry->next)) last_free_ptid = 0;
+ }
+ else /* need to grow the array */
+ {
+ unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2);
+ if (!count) count = 64;
+ if (!(entry = realloc( ptid_entries, count * sizeof(*entry) )))
+ {
+ set_error( STATUS_NO_MEMORY );
+ return 0;
+ }
+ ptid_entries = entry;
+ alloc_ptid_entries = count;
+ id = used_ptid_entries + PTID_OFFSET;
+ entry = &ptid_entries[used_ptid_entries++];
+ }
+
+ entry->ptr = ptr;
+ return id;
+}
+
+/* free a process or thread id */
+void free_ptid( unsigned int id )
+{
+ struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];
+
+ entry->ptr = NULL;
+ entry->next = 0;
+
+ /* append to end of free list so that we don't reuse it too early */
+ if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id;
+ else next_free_ptid = id;
+
+ last_free_ptid = id;
+}
+
+/* retrieve the pointer corresponding to a process or thread id */
+void *get_ptid_entry( unsigned int id )
+{
+ if (id < PTID_OFFSET) return NULL;
+ if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
+ return ptid_entries[id - PTID_OFFSET].ptr;
+}
+
/* set the state of the process startup info */
static void set_process_startup_state( struct process *process, enum startup_state state )
{
if ((process->next = first_process) != NULL) process->next->prev = process;
first_process = process;
+ if (!(process->id = alloc_ptid( process ))) goto error;
+
/* create the main thread */
if (pipe( request_pipe ) == -1)
{
if (process->atom_table) release_object( process->atom_table );
if (process->exe.file) release_object( process->exe.file );
if (process->exe.filename) free( process->exe.filename );
+ if (process->id) free_ptid( process->id );
}
/* dump a process on stdout for debugging purposes */
struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops );
- fprintf( stderr, "Process next=%p prev=%p handles=%p\n",
- process->next, process->prev, process->handles );
+ fprintf( stderr, "Process id=%04x next=%p prev=%p handles=%p\n",
+ process->id, process->next, process->prev, process->handles );
}
static int process_signaled( struct object *obj, struct thread *thread )
/* get a process from an id (and increment the refcount) */
struct process *get_process_from_id( process_id_t id )
{
- struct process *p = first_process;
- while (p && (get_process_id(p) != id)) p = p->next;
- if (p) grab_object( p );
- else set_error( STATUS_INVALID_PARAMETER );
- return p;
+ struct object *obj = get_ptid_entry( id );
+
+ if (obj && obj->ops == &process_ops) return (struct process *)grab_object( obj );
+ set_error( STATUS_INVALID_PARAMETER );
+ return NULL;
}
/* get a process from a handle (and increment the refcount) */
if ((thread->next = first_thread) != NULL) thread->next->prev = thread;
first_thread = thread;
+ if (!(thread->id = alloc_ptid( thread )))
+ {
+ release_object( thread );
+ return NULL;
+ }
+
set_select_events( &thread->obj, POLLIN ); /* start listening to events */
add_process_thread( thread->process, thread );
return thread;
if (thread->info) release_object( thread->info );
cleanup_thread( thread );
release_object( thread->process );
+ if (thread->id) free_ptid( thread->id );
}
/* dump a thread on stdout for debugging purposes */
struct thread *thread = (struct thread *)obj;
assert( obj->ops == &thread_ops );
- fprintf( stderr, "Thread pid=%d teb=%p state=%d\n",
- thread->unix_pid, thread->teb, thread->state );
+ fprintf( stderr, "Thread id=%04x unix pid=%d teb=%p state=%d\n",
+ thread->id, thread->unix_pid, thread->teb, thread->state );
}
static int thread_signaled( struct object *obj, struct thread *thread )
/* get a thread pointer from a thread id (and increment the refcount) */
struct thread *get_thread_from_id( thread_id_t id )
{
- struct thread *t = first_thread;
- while (t && (get_thread_id(t) != id)) t = t->next;
- if (t) grab_object( t );
- else set_error( STATUS_INVALID_PARAMETER );
- return t;
+ struct object *obj = get_ptid_entry( id );
+
+ if (obj && obj->ops == &thread_ops) return (struct thread *)grab_object( obj );
+ set_error( STATUS_INVALID_PARAMETER );
+ return NULL;
}
/* get a thread from a handle (and increment the refcount) */
if ((signaled = check_wait( thread )) == -1) break;
cookie = thread->wait->cookie;
- if (debug_level) fprintf( stderr, "%08x: *wakeup* signaled=%d cookie=%p\n",
- (unsigned int)thread, signaled, cookie );
+ if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d cookie=%p\n",
+ thread->id, signaled, cookie );
end_wait( thread );
if (send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */
break;
wait->user = NULL;
if (thread->wait != wait) return; /* not the top-level wait, ignore it */
- if (debug_level) fprintf( stderr, "%08x: *wakeup* signaled=%d cookie=%p\n",
- (unsigned int)thread, STATUS_TIMEOUT, cookie );
+ if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d cookie=%p\n",
+ thread->id, STATUS_TIMEOUT, cookie );
end_wait( thread );
if (send_thread_wakeup( thread, cookie, STATUS_TIMEOUT ) == -1) return;
/* check if other objects have become signaled in the meantime */
thread->exit_time = time(NULL);
if (current == thread) current = NULL;
if (debug_level)
- fprintf( stderr,"%08x: *killed* exit_code=%d\n",
- (unsigned int)thread, thread->exit_code );
+ fprintf( stderr,"%04x: *killed* exit_code=%d\n",
+ thread->id, thread->exit_code );
if (thread->wait)
{
while (thread->wait) end_wait( thread );
static void dump_get_new_process_info_reply( const struct get_new_process_info_reply *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
+ fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " phandle=%p,", req->phandle );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " thandle=%p,", req->thandle );
fprintf( stderr, " success=%d", req->success );
}
static void dump_new_thread_reply( const struct new_thread_reply *req )
{
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " handle=%p", req->handle );
}
static void dump_init_thread_reply( const struct init_thread_reply *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " boot=%d,", req->boot );
fprintf( stderr, " version=%d", req->version );
}
static void dump_get_process_info_reply( const struct get_process_info_reply *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
+ fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " debugged=%d,", req->debugged );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d,", req->priority );
static void dump_get_thread_info_request( const struct get_thread_info_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
- fprintf( stderr, " tid_in=%08x", req->tid_in );
+ fprintf( stderr, " tid_in=%04x", req->tid_in );
}
static void dump_get_thread_info_reply( const struct get_thread_info_reply *req )
{
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " teb=%p,", req->teb );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d,", req->priority );
static void dump_open_process_request( const struct open_process_request *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
+ fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
}
static void dump_open_thread_request( const struct open_thread_request *req )
{
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
}
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
- fprintf( stderr, " pid=%08x", req->pid );
+ fprintf( stderr, " pid=%04x", req->pid );
}
static void dump_alloc_console_reply( const struct alloc_console_reply *req )
static void dump_send_console_signal_request( const struct send_console_signal_request *req )
{
fprintf( stderr, " signal=%d,", req->signal );
- fprintf( stderr, " group_id=%08x", req->group_id );
+ fprintf( stderr, " group_id=%04x", req->group_id );
}
static void dump_create_change_notification_request( const struct create_change_notification_request *req )
{
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " flags=%d,", req->flags );
- fprintf( stderr, " pid=%08x", req->pid );
+ fprintf( stderr, " pid=%04x", req->pid );
}
static void dump_create_snapshot_reply( const struct create_snapshot_reply *req )
static void dump_next_process_reply( const struct next_process_reply *req )
{
fprintf( stderr, " count=%d,", req->count );
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " ppid=%08x,", req->ppid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " ppid=%04x,", req->ppid );
fprintf( stderr, " heap=%p,", req->heap );
fprintf( stderr, " module=%p,", req->module );
fprintf( stderr, " threads=%d,", req->threads );
static void dump_next_thread_reply( const struct next_thread_reply *req )
{
fprintf( stderr, " count=%d,", req->count );
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " base_pri=%d,", req->base_pri );
fprintf( stderr, " delta_pri=%d", req->delta_pri );
}
static void dump_next_module_reply( const struct next_module_reply *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
+ fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " base=%p,", req->base );
fprintf( stderr, " size=%d,", req->size );
fprintf( stderr, " filename=" );
static void dump_wait_debug_event_reply( const struct wait_debug_event_reply *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " wait=%p,", req->wait );
fprintf( stderr, " event=" );
dump_varargs_debug_event( cur_size );
static void dump_continue_debug_event_request( const struct continue_debug_event_request *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " status=%d", req->status );
}
static void dump_debug_process_request( const struct debug_process_request *req )
{
- fprintf( stderr, " pid=%08x,", req->pid );
+ fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " attach=%d", req->attach );
}
static void dump_send_message_request( const struct send_message_request *req )
{
- fprintf( stderr, " id=%08x,", req->id );
+ fprintf( stderr, " id=%04x,", req->id );
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " win=%p,", req->win );
fprintf( stderr, " msg=%08x,", req->msg );
{
fprintf( stderr, " full_handle=%p,", req->full_handle );
fprintf( stderr, " last_active=%p,", req->last_active );
- fprintf( stderr, " pid=%08x,", req->pid );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " pid=%04x,", req->pid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " atom=%04x", req->atom );
}
{
fprintf( stderr, " parent=%p,", req->parent );
fprintf( stderr, " atom=%04x,", req->atom );
- fprintf( stderr, " tid=%08x", req->tid );
+ fprintf( stderr, " tid=%04x", req->tid );
}
static void dump_get_window_children_reply( const struct get_window_children_reply *req )
static void dump_attach_thread_input_request( const struct attach_thread_input_request *req )
{
- fprintf( stderr, " tid_from=%08x,", req->tid_from );
- fprintf( stderr, " tid_to=%08x,", req->tid_to );
+ fprintf( stderr, " tid_from=%04x,", req->tid_from );
+ fprintf( stderr, " tid_to=%04x,", req->tid_to );
fprintf( stderr, " attach=%d", req->attach );
}
static void dump_get_thread_input_request( const struct get_thread_input_request *req )
{
- fprintf( stderr, " tid=%08x", req->tid );
+ fprintf( stderr, " tid=%04x", req->tid );
}
static void dump_get_thread_input_reply( const struct get_thread_input_reply *req )
static void dump_get_key_state_request( const struct get_key_state_request *req )
{
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " key=%d", req->key );
}
static void dump_set_key_state_request( const struct set_key_state_request *req )
{
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " keystate=" );
dump_varargs_bytes( cur_size );
}
static void dump_set_hook_request( const struct set_hook_request *req )
{
fprintf( stderr, " id=%d,", req->id );
- fprintf( stderr, " tid=%08x,", req->tid );
+ fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " proc=%p,", req->proc );
fprintf( stderr, " unicode=%d,", req->unicode );
fprintf( stderr, " module=" );
enum request req = current->req.request_header.req;
if (req < REQ_NB_REQUESTS)
{
- fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] );
+ fprintf( stderr, "%04x: %s(", current->id, req_names[req] );
if (req_dumpers[req])
{
cur_pos = 0;
}
fprintf( stderr, " )\n" );
}
- else fprintf( stderr, "%08x: %d(?)\n", (unsigned int)current, req );
+ else fprintf( stderr, "%04x: %d(?)\n", current->id, req );
}
void trace_reply( enum request req, const union generic_reply *reply )
{
if (req < REQ_NB_REQUESTS)
{
- fprintf( stderr, "%08x: %s() = %s",
- (unsigned int)current, req_names[req], get_status_name(current->error) );
+ fprintf( stderr, "%04x: %s() = %s",
+ current->id, req_names[req], get_status_name(current->error) );
if (reply_dumpers[req])
{
fprintf( stderr, " {" );
}
fputc( '\n', stderr );
}
- else fprintf( stderr, "%08x: %d() = %s\n",
- (unsigned int)current, req, get_status_name(current->error) );
+ else fprintf( stderr, "%04x: %d() = %s\n",
+ current->id, req, get_status_name(current->error) );
}