| /* | |
| * Copyright (c) 2010 IBM Corporation. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v1.0 | |
| * which accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-v10.html | |
| */ | |
| /* | |
| * Keeps a map of thread ID's, and its information. | |
| */ | |
| #ifdef __gnu_linux__ | |
| #define _GNU_SOURCE | |
| #endif /* __gnu_linux__ */ | |
| #include "config.h" | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <string.h> | |
| #include "gdb.h" | |
| #include "dbg.h" | |
| #include "dbg_error.h" | |
| #include "threadmap.h" | |
| struct thread_map { | |
| int nels; // number of elements currently in map | |
| int size; // total size of map | |
| thread_entry * maps; | |
| }; | |
| static struct thread_map _thread_map = {0, 0, NULL}; | |
| /* | |
| * Add a thread entry to thread map. | |
| * | |
| */ | |
| thread_entry * | |
| AddThreadMap(int threadID, int stopStatus, int statementHookBPNum, int stepNop) | |
| { | |
| int i; | |
| thread_entry * map = NULL; | |
| if (_thread_map.size == 0) { | |
| thread_entry *thisMaps = (thread_entry *)malloc(sizeof(thread_entry) * 10); | |
| _thread_map.maps = thisMaps; | |
| _thread_map.size = 10; | |
| for (i = 0; i < _thread_map.size; i++) { | |
| map = &_thread_map.maps[i]; | |
| map->thread_id = -1; | |
| map->statement_hook_bp_num = -1; | |
| map->stop_status = THREAD_STATUS_STOP_UNKNOWN; | |
| map->skip_statement_hook = 0; | |
| map->step_nop = 0; | |
| map->stackframes = NULL; | |
| } | |
| } | |
| if (_thread_map.nels == _thread_map.size) { | |
| i = _thread_map.size; | |
| _thread_map.size *= 2; | |
| _thread_map.maps = (thread_entry *)realloc(_thread_map.maps, sizeof(thread_entry) * _thread_map.size); | |
| for (; i < _thread_map.size; i++) { | |
| map = &_thread_map.maps[i]; | |
| map->thread_id = -1; | |
| map->statement_hook_bp_num = -1; | |
| map->stop_status = THREAD_STATUS_STOP_UNKNOWN; | |
| map->skip_statement_hook = 0; | |
| map->step_nop = 0; | |
| map->stackframes = NULL; | |
| } | |
| } | |
| for (i = 0; i < _thread_map.size; i++) { | |
| map = &_thread_map.maps[i]; | |
| if (map->thread_id == -1) { | |
| map->thread_id = threadID; | |
| map->statement_hook_bp_num = statementHookBPNum; | |
| map->stop_status = stopStatus; | |
| map->skip_statement_hook = 0; | |
| map->step_nop = stepNop; | |
| map->stackframes = NULL; | |
| _thread_map.nels++; | |
| break; | |
| } | |
| } | |
| return map; | |
| } | |
| /* | |
| * Remove a thread entry from thread map. | |
| * | |
| */ | |
| void | |
| RemoveThreadMap(int id) | |
| { | |
| int i; | |
| thread_entry * map; | |
| for (i = 0; i < _thread_map.size; i++) { | |
| map = &_thread_map.maps[i]; | |
| if (map->thread_id == id) { | |
| map->thread_id = -1; | |
| map->statement_hook_bp_num = -1; | |
| map->stop_status = THREAD_STATUS_STOP_UNKNOWN; | |
| map->skip_statement_hook = 0; | |
| map->step_nop = 0; | |
| if (NULL == map->stackframes) | |
| { | |
| DestroyList(map->stackframes, FreeStackframe); | |
| map->stackframes = NULL; | |
| } | |
| _thread_map.nels--; | |
| break; | |
| } | |
| } | |
| } | |
| /* | |
| * Find a thread entry in thread map. | |
| * | |
| */ | |
| thread_entry * | |
| FindThreadEntry(int threadID) | |
| { | |
| int i; | |
| thread_entry * map; | |
| for (i = 0; i < _thread_map.size; i++) { | |
| map = &_thread_map.maps[i]; | |
| if (map->thread_id == threadID) { | |
| return map; | |
| } | |
| } | |
| return NULL; | |
| } | |
| /* | |
| * Remove all the entries in the thread map. | |
| * | |
| */ | |
| void | |
| ClearThreadMaps() | |
| { | |
| int i; | |
| thread_entry * map; | |
| int length = _thread_map.size; | |
| for (i = 0; i < length; i++) { | |
| map = &_thread_map.maps[i]; | |
| if (map == NULL) | |
| return; | |
| map->thread_id = -1; | |
| map->statement_hook_bp_num = -1; | |
| map->stop_status = THREAD_STATUS_STOP_UNKNOWN; | |
| map->skip_statement_hook = 0; | |
| map->step_nop = 0; | |
| if (NULL == map->stackframes) | |
| { | |
| DestroyList(map->stackframes, FreeStackframe); | |
| map->stackframes = NULL; | |
| } | |
| _thread_map.nels--; | |
| } | |
| } |