blob: 7d46d36823ed9caa11d60a5ff9e58df2311b242e [file] [log] [blame]
/*
* 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--;
}
}