Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4972 → Rev 4973

/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));
}