/programs/develop/libraries/menuetlibc/src/libc/crt0/Makefile |
---|
0,0 → 1,4 |
THIS_SRCS= brk.c c1loadef.c c1pglob.c crt0.c crt1.c _main.c \ |
env.c nullcall.c |
include $(MENUET_LIBC_TOPDIR)/Make.rules |
/programs/develop/libraries/menuetlibc/src/libc/crt0/_main.c |
---|
0,0 → 1,19 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/internal.h> |
#include <libc/bss.h> |
typedef void (*FUNC)(void); |
extern FUNC djgpp_first_ctor[] __asm__("djgpp_first_ctor"); |
extern FUNC djgpp_last_ctor[] __asm__("djgpp_last_ctor"); |
void |
__main(void) |
{ |
static int been_there_done_that = -1; |
int i; |
if (been_there_done_that == __bss_count) |
return; |
been_there_done_that = __bss_count; |
for (i=0; i<djgpp_last_ctor-djgpp_first_ctor; i++) |
djgpp_first_ctor[i](); |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/brk.c |
---|
0,0 → 1,135 |
#include <unistd.h> |
#include <errno.h> |
#include <sys/types.h> |
static void * ___brk_addr = 0; |
extern char end[]; |
static unsigned long min_brk,max_brk,cur_brk; |
extern unsigned long __menuet__memsize; |
static void* cur_dynamic_area; |
static unsigned cur_total_size; |
static inline void heap_init(void) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(11)); |
} |
static inline void* heap_alloc(unsigned size) |
{ |
void* res; |
__asm__("int $0x40" : "=a"(res) : "a"(68),"b"(12),"c"(size)); |
return res; |
} |
static inline void heap_free(void* ptr) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(13),"c"(ptr)); |
} |
void init_brk(void) |
{ |
cur_brk=min_brk=(((unsigned long)&end)+0xfff)&~0xfff; |
max_brk=(__menuet__memsize-32768)&~0xfff; |
___brk_addr=(void *)min_brk; |
cur_dynamic_area = NULL; |
cur_total_size = max_brk; |
heap_init(); |
} |
/*static int sys_brk(unsigned long end_data_seg) |
{ |
if(!end_data_seg) return cur_brk; |
if (end_data_seg >= min_brk && |
end_data_seg < max_brk) |
cur_brk = end_data_seg; |
return cur_brk; |
}*/ |
/*int brk(void *_heaptop) |
{ |
return sys_brk((unsigned long)_heaptop); |
} |
static int __init_brk (void) |
{ |
if (___brk_addr == 0) |
{ |
___brk_addr=(void *)sys_brk(0); |
if (___brk_addr == 0) |
{ |
errno = ENOMEM; |
return -1; |
} |
} |
return 0; |
}*/ |
void * sbrk(int increment) |
{ |
/* if (__init_brk () == 0) |
{ |
void * tmp = ___brk_addr+increment; |
___brk_addr=(void *)sys_brk((unsigned long)tmp); |
if (___brk_addr == tmp) return tmp-increment; |
errno = ENOMEM; |
return ((void *) -1); |
} |
return ((void *) -1);*/ |
void* res; |
unsigned long tmp; |
if (increment <= 0) |
{ |
/* release memory */ |
while (cur_dynamic_area && increment) |
{ |
tmp = cur_brk - (unsigned long)cur_dynamic_area - |
3*sizeof(void*); |
if (tmp > increment) |
tmp = increment; |
cur_brk -= tmp; |
increment -= tmp; |
if (cur_brk == (unsigned long)cur_dynamic_area + 3*sizeof(void*)) |
{ |
cur_brk = (unsigned long)((void**)cur_dynamic_area)[1]; |
max_brk = (unsigned long)((void**)cur_dynamic_area)[2]; |
res = cur_dynamic_area; |
cur_dynamic_area = ((void**)cur_dynamic_area)[0]; |
heap_free(res); |
} |
} |
if (!cur_dynamic_area) |
{ |
cur_brk += increment; |
if (cur_brk < min_brk) |
cur_brk = min_brk; |
} |
return (void*)cur_brk; |
} |
/* allocate memory */ |
if (cur_brk + increment <= max_brk) |
{ |
/* We have memory in current block, so use it */ |
res = (void*)cur_brk; |
cur_brk += increment; |
return res; |
} |
tmp = 65536; |
/* We do not have memory in current block, so allocate new one */ |
if (increment > 65536 - 3*sizeof(void*)) |
tmp = (increment + 3*sizeof(void*) + 0xFFF) & ~0xFFF; |
res = heap_alloc(tmp); |
if (!res) |
{ |
errno = ENOMEM; |
return (void*)-1; |
} |
((void**)res)[0] = cur_dynamic_area; |
((void**)res)[1] = (void*)cur_brk; |
((void**)res)[2] = (void*)max_brk; |
cur_dynamic_area = res; |
cur_brk = (unsigned long)res + 3*sizeof(void*); |
max_brk = (unsigned long)res + tmp; |
res = (void*)cur_brk; |
cur_brk += increment; |
return (void*)res; |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/c1loadef.c |
---|
0,0 → 1,159 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <crt0.h> |
#include <stdlib.h> |
#include <io.h> |
#include <fcntl.h> |
#include <string.h> |
#include <ctype.h> |
#include <unistd.h> |
void __crt0_load_environment_file(char *app_name) |
{ |
int djgpp_env; |
char *djgpp_var = getenv("DJGPP"); |
if (djgpp_var) |
{ |
djgpp_env = _open(djgpp_var, O_RDONLY); |
if (djgpp_env >= 0) |
{ |
char *file; |
char base[120], *bp, *a0p, *tb; |
int this_prog = 1; |
int fsize = lseek(djgpp_env, 0L, SEEK_END); |
file = (char *)malloc(fsize+2); |
if (file == 0) |
return; |
lseek(djgpp_env, 0L, 0); |
_read(djgpp_env, file, fsize); |
_close(djgpp_env); |
if (file[fsize-1] == '\n') |
{ |
file[fsize] = 0; |
} |
else |
{ |
file[fsize] = '\n'; |
file[fsize+1] = 0; |
} |
tb = file; |
base[0] = '['; |
bp = app_name; |
for (a0p = bp; *a0p; a0p++) |
if (strchr("\\/:", *a0p)) |
bp = a0p+1; |
for (a0p=base+1; *bp && *bp != '.';) |
*a0p++ = tolower(*bp++); |
*a0p++ = ']'; |
*a0p++ = 0; |
bp = tb; |
while (1) |
{ |
tb = bp; |
while (*tb && (*tb == '\n' || *tb == '\r')) |
tb++; |
bp = tb; |
while (*bp && *bp != '\n' && *bp != '\r') |
bp++; |
if (*bp == 0) |
break; |
*bp++ = 0; |
if (tb[0] == 0 || tb[0] == '#') |
continue; |
if (tb[0] == '[') |
{ |
if (strcmp(tb, base) == 0) |
this_prog = 1; |
else |
this_prog = 0; |
} |
else |
{ |
if (this_prog) |
{ |
char *buf = alloca(fsize); |
char *tb2 = buf; |
char *sp=tb, *dp=tb2; |
while (*sp != '=') |
*dp++ = *sp++; |
if (*tb2 == '+') /* non-overriding */ |
{ |
*dp = 0; |
tb2++; |
if (getenv(tb2)) |
continue; /* while scanning bytes */ |
} |
*dp++ = *sp++; /* copy the '=' */ |
while (*sp) |
{ |
if (*sp == '%') |
{ |
char *pp; |
if (sp[1] == '%') |
{ |
*dp++ = '%'; |
sp += 2; |
} |
else |
{ |
char ps, *e, *dirend; |
int dirpart=0, apsemi=0; |
int mapup=0, maplow=0, mapfs=0, mapbs=0; |
while (strchr(":;/\\<>", sp[1])) |
{ |
switch (sp[1]) |
{ |
case ':': dirpart=1; break; |
case ';': apsemi=1; break; |
case '/': mapfs=1; break; |
case '\\': mapbs=1; break; |
case '<': mapup=1; break; |
case '>': maplow=1; break; |
} |
sp++; |
} |
for (pp=sp+1; *pp && *pp != '%'; pp++); |
ps = *pp; |
*pp = 0; |
e = getenv(sp+1); |
dirend = dp; |
if (e) |
{ |
while (*e) |
{ |
char ec = *e++; |
if (strchr("\\/:", ec)) |
dirend=dp; |
if (mapup) ec = toupper(ec); |
if (maplow) ec = tolower(ec); |
if (mapfs && ec == '\\') ec = '/'; |
if (mapbs && ec == '/') ec = '\\'; |
*dp++ = ec; |
} |
} |
if (dirpart) |
dp = dirend; |
if (apsemi && e) |
*dp++ = ';'; |
if (ps == 0) |
break; |
sp = pp+1; |
} |
} |
else |
*dp++ = *sp++; |
} |
*dp++ = 0; |
putenv(tb2); |
} |
} |
} |
free(file); |
} |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/c1pglob.c |
---|
0,0 → 1,14 |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <crt0.h> |
#include <glob.h> |
char ** __crt0_glob_function(char *arg) |
{ |
char **rv; |
glob_t g; |
if (glob(arg, GLOB_NOCHECK, 0, &g) != 0) |
return 0; |
rv = g.gl_pathv; |
return rv; |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/crt0.c |
---|
0,0 → 1,401 |
#include<menuet/os.h> |
#include<unistd.h> |
void _exit(int code) |
{ |
__asm__ __volatile__("int $0x40"::"a"(-1)); |
for(;;); |
} |
#include <libc/stubs.h> |
#include <io.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <crt0.h> |
#include <libc/farptrgs.h> |
#include <ctype.h> |
#include <string.h> |
#include <fcntl.h> |
#define ds _my_ds() |
extern char __menuet__app_param_area[]; |
extern char __menuet__app_path_area[]; |
static void * c1xmalloc(size_t s) |
{ |
void *q = malloc(s); |
if (q == 0) |
{ |
#define err(x) |
err("No memory to gather arguments\r\n"); |
_exit(1); |
} |
return q; |
} |
static int atohex(char *s) |
{ |
int rv = 0; |
while (*s) |
{ |
int v = *s - '0'; |
if (v > 9) |
v -= 7; |
v &= 15; /* in case it's lower case */ |
rv = rv*16 + v; |
s++; |
} |
return rv; |
} |
typedef struct Arg { |
char *arg; |
char **arg_globbed; |
struct ArgList *arg_file; |
struct Arg *next; |
int was_quoted; |
} Arg; |
typedef struct ArgList { |
int argc; |
Arg **argv; |
} ArgList; |
static Arg *new_arg(void) |
{ |
Arg *a = (Arg *)c1xmalloc(sizeof(Arg)); |
memset(a, 0, sizeof(Arg)); |
return a; |
} |
static void delete_arglist(ArgList *al); |
static void delete_arg(Arg *a) |
{ |
if (a->arg) free(a->arg); |
if (a->arg_globbed) |
{ |
int i; |
for (i=0; a->arg_globbed[i]; i++) |
free(a->arg_globbed[i]); |
free(a->arg_globbed); |
} |
if (a->arg_file) |
delete_arglist(a->arg_file); |
free(a); |
} |
static ArgList * new_arglist(int count) |
{ |
ArgList *al = (ArgList *)c1xmalloc(sizeof(ArgList)); |
al->argc = count; |
al->argv = (Arg **)c1xmalloc((count+1)*sizeof(Arg *)); |
memset(al->argv, 0, (count+1)*sizeof(Arg *)); |
return al; |
} |
static void delete_arglist(ArgList *al) |
{ |
int i; |
for (i=0; i<al->argc; i++) |
delete_arg(al->argv[i]); |
free(al->argv); |
free(al); |
} |
static char * parse_arg(char *bp, char *last, int unquote, size_t *len, int *was_quoted) |
{ |
char *ep = bp, *epp = bp; |
int quote=0; |
while ((quote || !isspace(*(unsigned char *)ep)) && ep < last) |
{ |
if (quote && *ep == quote) |
{ |
quote = 0; |
if (!unquote) |
*epp++ = *ep; |
ep++; |
} |
else if (!quote && (*ep == '\'' || *ep == '"')) |
{ |
quote = *ep++; |
if (!unquote) |
*epp++ = quote; |
} |
else if (*ep == '\\' && strchr("'\"", ep[1]) && ep < last-1) |
{ |
if (!unquote) |
*epp++ = *ep; |
ep++; |
*epp++ = *ep++; |
/* *was_quoted = 1; - This makes no sense. */ |
} |
else |
{ |
if ((quote && (strchr("[?*", *ep) || strncmp(ep, "...", 3) == 0)) |
&& unquote) |
*was_quoted = 1; |
*epp++ = *ep++; |
} |
} |
*len = epp - bp; |
return ep; |
} |
static ArgList * parse_bytes(char *bytes, int length, int unquote) |
{ |
int largc, i; |
Arg *a, **anext, *afirst; |
ArgList *al; |
char *bp=bytes, *ep, *last=bytes+length; |
anext = &afirst; |
largc = 0; |
while (bp<last) |
{ |
size_t arg_len; |
while (isspace(*(unsigned char *)bp) && bp < last) |
bp++; |
if (bp == last) |
break; |
*anext = a = new_arg(); |
ep = parse_arg(bp, last, unquote, &arg_len, &(a->was_quoted)); |
anext = &(a->next); |
largc++; |
a->arg = (char *)c1xmalloc(arg_len+1); |
memcpy(a->arg, bp, arg_len); |
a->arg[arg_len] = 0; |
bp = ep+1; |
} |
al = new_arglist(largc); |
for (i=0, a=afirst; i<largc; i++, a=a->next) |
al->argv[i] = a; |
return al; |
} |
static ArgList * parse_print0(char *bytes, int length) |
{ |
int largc, i; |
Arg *a, **anext, *afirst; |
ArgList *al; |
char *bp=bytes, *ep, *last=bytes+length; |
anext = &afirst; |
largc = 0; |
while (bp<last) |
{ |
size_t arg_len = strlen(bp); |
ep = bp; |
bp += arg_len + 1; |
*anext = a = new_arg(); |
a->was_quoted = 1; |
anext = &(a->next); |
largc++; |
a->arg = (char *)c1xmalloc(arg_len+1); |
memcpy(a->arg, ep, arg_len); |
a->arg[arg_len] = 0; |
} |
al = new_arglist(largc); |
for (i=0, a=afirst; i<largc; i++, a=a->next) |
al->argv[i] = a; |
return al; |
} |
static int count_args(ArgList *al) |
{ |
int i, r=0; |
for (i=0; i<al->argc; i++) |
{ |
int j; |
if (al->argv[i]->arg_globbed) |
{ |
for (j=0; al->argv[i]->arg_globbed[j]; j++); |
r += j; |
} |
else if (al->argv[i]->arg_file) |
{ |
r += count_args(al->argv[i]->arg_file); |
} |
else |
{ |
r++; |
} |
} |
return r; |
} |
static char ** fill_args(char **largv, ArgList *al) |
{ |
int i; |
for (i=0; i<al->argc; i++) |
{ |
int j; |
if (al->argv[i]->arg_globbed) |
{ |
for (j=0; al->argv[i]->arg_globbed[j]; j++) |
{ |
*largv++ = al->argv[i]->arg_globbed[j]; |
al->argv[i]->arg_globbed[j] = 0; |
} |
} |
else if (al->argv[i]->arg_file) |
{ |
largv = fill_args(largv, al->argv[i]->arg_file); |
} |
else |
{ |
*largv++ = al->argv[i]->arg; |
al->argv[i]->arg = 0; |
} |
} |
return largv; |
} |
static void expand_response_files(ArgList *al) |
{ |
int i, f; |
for (i=0; i<al->argc; i++) |
{ |
if (! al->argv[i]->was_quoted && al->argv[i]->arg[0] == '@') |
if ((f = _open(al->argv[i]->arg+1, O_RDONLY)) >= 0) |
{ |
char *bytes; |
int len, st_size; |
st_size = lseek(f, 0L, SEEK_END); |
lseek(f, 0L, SEEK_SET); |
if (st_size < 0) |
st_size = 0; |
bytes = (char *)c1xmalloc(st_size+1); |
len = _read(f, bytes, st_size); |
if (len < 0) |
len = 0; |
_close(f); |
/* if the last character is ^Z, remove it */ |
if (len > 0 && bytes[len-1] == 0x1a) |
len--; |
/* assume 'find -print0' if the last char is a '\0' */ |
if (len > 0 && bytes[len-1] == '\0') |
al->argv[i]->arg_file = parse_print0(bytes, len); |
else |
al->argv[i]->arg_file = parse_bytes(bytes, len, (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0); |
expand_response_files(al->argv[i]->arg_file); |
free(bytes); |
} |
} |
} |
static void expand_wildcards(ArgList *al) |
{ |
int i; |
for (i=0; i<al->argc; i++) |
{ |
if (al->argv[i]->arg_file) |
expand_wildcards(al->argv[i]->arg_file); |
else if (!(al->argv[i]->was_quoted)) |
{ |
al->argv[i]->arg_globbed = __crt0_glob_function(al->argv[i]->arg); |
} |
} |
} |
static void add_arg(const char* arg, const char* end) |
{ |
char* res; |
__crt0_argv = realloc(__crt0_argv, 4*(++__crt0_argc)); |
res = malloc(end-arg+1); |
if (!__crt0_argv || !res) _exit(1); |
__crt0_argv[__crt0_argc-1] = res; |
while (arg < end) |
{ |
if (arg[0] == '"' && arg[1] == '"') ++arg; |
*res++ = *arg++; |
} |
*res = 0; |
} |
void __crt0_setup_arguments(void) |
{ |
#if 0 |
// ¥ ¡ã¤¥¬ áâà ¤ âì 䨣ñ©... |
ArgList *arglist; |
char *argv0; |
int prepend_argv0 = 1; |
int should_expand_wildcards = 1; |
char *proxy_v = 0; |
argv0="menuet.app"; |
/* |
** Next, scan dos's command line. |
*/ |
{ |
char doscmd[128]; |
memcpy(doscmd+1,__menuet__app_param_area,128); |
arglist = parse_bytes(doscmd+1, doscmd[0] & 0x7f, |
(_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0); |
} |
/* |
** Now, expand response files |
*/ |
if (!(_crt0_startup_flags & _CRT0_FLAG_DISALLOW_RESPONSE_FILES)) |
expand_response_files(arglist); |
/* |
** Now, expand wildcards |
*/ |
if (should_expand_wildcards) |
expand_wildcards(arglist); |
__crt0_argc = prepend_argv0 + count_args(arglist); |
__crt0_argv = (char **)c1xmalloc((__crt0_argc+1) * sizeof(char *)); |
if (prepend_argv0) |
__crt0_argv[0] = argv0; |
*fill_args(__crt0_argv+prepend_argv0, arglist) = 0; |
#else |
// ... ¯à®áâ® à §¡¥àñ¬ ª®¬ ¤ãî áâபã. - diamond |
char* ptr; |
char* cur_arg=NULL; |
int bInQuote=0; |
add_arg(__menuet__app_path_area, |
__menuet__app_path_area + strlen(__menuet__app_path_area)); |
for (ptr=__menuet__app_param_area;*ptr && ptr<__menuet__app_param_area+256;ptr++) |
{ |
if (*ptr == ' ' || *ptr == '\t') |
{ |
if (cur_arg && !bInQuote) |
{ |
add_arg(cur_arg,ptr); |
cur_arg = NULL; |
} |
continue; |
} |
if (*ptr == '"') |
{ |
if (ptr[1] == '"') |
{if (!cur_arg) cur_arg=ptr;ptr++;} |
else |
{ |
if (cur_arg) |
{ |
add_arg(cur_arg,ptr); |
if (bInQuote) |
{ |
bInQuote = 0; |
cur_arg = NULL; |
continue; |
} |
} |
bInQuote = 1; |
cur_arg = ptr+1; |
} |
continue; |
} |
if (!cur_arg) cur_arg = ptr; |
} |
if (cur_arg) add_arg(cur_arg,ptr); |
#endif |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/crt1.c |
---|
0,0 → 1,49 |
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ |
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ |
#include <libc/stubs.h> |
#include <crt0.h> |
#include <string.h> |
#include <libc/internal.h> |
#include <stdlib.h> |
#include <libc/farptrgs.h> |
#include <pc.h> |
#include <libc/bss.h> |
#include <menuet/os.h> |
/* Global variables */ |
#define ds _my_ds() |
int __bss_count = 1; |
char **environ; |
int _crt0_startup_flags; /* default to zero unless app overrides them */ |
int __crt0_argc=0; |
char ** __crt0_argv=NULL; |
char * __dos_argv0; |
extern __u32 __menuet__getmemsize(void); |
extern void __main(void); |
extern int main(int, char **); |
extern void _crt0_init_mcount(void); /* For profiling */ |
void __crt0_setup_arguments(void); |
extern char __menuet__app_param_area[]; |
//void dosemu_atexit(void); |
void __crt1_startup(void) |
{ |
init_brk(); |
if(__menuet__app_param_area[0]!='\0') |
__crt0_setup_arguments(); |
dosemu_inithandles(); |
init_dir_stack(); |
// atexit(dosemu_atexit); |
__main(); |
{ |
int stat=main(__crt0_argc,__crt0_argv); |
exit(stat); |
} |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/env.c |
---|
0,0 → 1,16 |
#include<stdio.h> |
#include<stdlib.h> |
#include<string.h> |
#include<ctype.h> |
static char **SDL_env = (char **)0; |
int __libc_putenv(const char *variable) |
{ |
return -1; |
} |
char * __libc_getenv(const char *name) |
{ |
return NULL; |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/nullcall.c |
---|
0,0 → 1,14 |
struct __frame |
{ |
unsigned long ebp,edi,esi,edx,ecx,ebx,eax,eip; |
}; |
void __libc_null_call(volatile struct __frame frame) |
{ |
__libclog_printf("Bad call occured from EIP=%x\n",frame.eip); |
__libclog_printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", |
frame.eax,frame.ebx,frame.ecx,frame.edx); |
__libclog_printf("ESI=%08x EDI=%08x EBP=%08x\n", |
frame.esi,frame.edi,frame.ebp); |
_exit(1); |
} |
/programs/develop/libraries/menuetlibc/src/libc/crt0/thread.c |
---|
0,0 → 1,130 |
#include<menuet/os.h> |
#include<stdlib.h> |
#include<string.h> |
#include<menuet/sem.h> |
#include<menuet/thread.h> |
#include<assert.h> |
#define MAX_THREADS 128 |
typedef struct |
{ |
int flags; |
void (* fn_ptr)(void); |
void * thr_stack; |
int pid; |
} thread_t; |
static thread_t * thr[MAX_THREADS]; |
DECLARE_STATIC_SEM(thr_list_sem); |
static void do_thr_atexit(void); |
void init_threads(void) |
{ |
register int i; |
sem_lock(&thr_list_sem); |
for(i=0;i<MAX_THREADS;i++) thr[i]=NULL; |
sem_unlock(&thr_list_sem); |
atexit(do_thr_atexit); |
} |
int get_thread_pid(int tid) |
{ |
sem_lock(&thr_list_sem); |
if(tid>=0 && tid<MAX_THREADS && thr[tid]) |
{ |
sem_unlock(&thr_list_sem); |
return thr[tid]->pid; |
} |
sem_unlock(&thr_list_sem); |
return -1; |
} |
int get_thread_tid(int pid) |
{ |
register int i; |
sem_lock(&thr_list_sem); |
for(i=0;i<MAX_THREADS;i++) |
{ |
if(thr[i] && thr[i]->pid==pid) |
{ |
sem_unlock(&thr_list_sem); |
return i; |
} |
} |
sem_unlock(&thr_list_sem); |
return -1; |
} |
static void do_thr_atexit(void) |
{ |
register int i; |
sem_lock(&thr_list_sem); |
for(i=0;i<MAX_THREADS;i++) |
{ |
if(thr[i] && (thr[i]->flags & THR_ATEXIT)) |
{ |
__asm__ __volatile__("int $0x40"::"a"(18),"b"(2),"c"(thr[i]->pid)); |
free(thr[i]->thr_stack); |
free(thr[i]); |
thr[i]=NULL; |
} |
} |
sem_unlock(&thr_list_sem); |
} |
int create_thread(void (* fn)(void),int stacksize,int flags,void ** rstackp) |
{ |
int i; |
if(stacksize<4096) stacksize=4096; |
sem_lock(&thr_list_sem); |
for(i=0;i<MAX_THREADS;i++) |
{ |
if(!thr[i]) |
{ |
thr[i]=(thread_t *)malloc(sizeof(thread_t)); |
thr[i]->thr_stack=malloc(stacksize); |
if(!thr[i]->thr_stack) |
{ |
free(thr[i]); |
thr[i]=NULL; |
sem_unlock(&thr_list_sem); |
return -1; |
} |
thr[i]->flags=flags; |
thr[i]->fn_ptr=fn; |
__asm__ __volatile__("int $0x40":"=a"(thr[i]->pid) |
:"a"(51),"b"(1),"c"(fn),"d"(thr[i]->thr_stack+stacksize) |
); |
if(thr[i]->pid==-1) |
{ |
free(thr[i]); |
thr[i]=NULL; |
sem_unlock(&thr_list_sem); |
return -1; |
} |
sem_unlock(&thr_list_sem); |
return i; |
} |
} |
sem_unlock(&thr_list_sem); |
return -1; |
} |
void kill_thread(int tid) |
{ |
assert(tid<0); |
assert(tid>=MAX_THREADS); |
assert(get_thread_pid(tid)<0); |
assert(!thr[tid]); |
sem_lock(&thr_list_sem); |
if(thr[tid]->flags & THR_KILLER) |
{ |
thr[tid]->flags=0; |
sem_unlock(&thr_list_sem); |
do_thr_atexit(); |
exit(0); |
} |
__asm__ __volatile__("int $0x40"::"a"(18),"b"(2),"c"(thr[tid]->pid)); |
} |