int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), int *stack_task) { int *stack_addr; int stack_size; struct rtl_thread_struct *task; long interrupt_state; pthread_attr_t default_attr; int contextid; if (!attr) { pthread_attr_init(&default_attr); attr = &default_attr; } stack_size = attr->stack_size; contextid = get_contextid(start_routine); task = (struct rtl_thread_struct *) kGetPage(); stack_addr = (int *) kGetPage(); memset((void *) stack_addr,0,stack_size); task->kmalloc_stack_bottom = stack_addr; *thread = task; //task->magic = RTL_THREAD_MAGIC; task->pending = attr->initial_state; task->blocked = 0; task->abort = 0; task->cpu = attr->cpu; task->cleanup = 0; task->resume_time = HRTIME_INFINITY; #ifdef CONFIG_RTL_SCHED_EDF task->policy = attr->policy; task->current_deadline = 0LL; #endif task->period = 0; (task->sched_param).sched_priority = (attr->sched_param).sched_priority; task->stack = (int *) (((int) stack_addr) + (stack_size-sizeof(int))); task->top_of_stack = (unsigned long)task->stack; //spark_printLong(task->top_of_stack); task->fpu_initialized = 0; task->uses_fp = attr->use_fp; task->start = (void *) start_routine; task->contextid = contextid; ((RT_TASK_IPC *) task)->sem_at = NULL; //((RT_TASK_IPC *) task)->magic = RT_TASK_IPC_MAGIC; task->user[IPC_DATA_INDEX] = task; //rtl_init_stack(task,start_routine,arg,rtl_startup); rtl_init_stack(task,stack_task + 1024 ,start_routine); add_to_task_list(task); rtl_sigaddset(&task->pending,RTL_SIGNAL_READY); return 0; }
/* FIXME Argument processing does not match behavior observed on Windows. * Stringent argument counting and processing is performed, and unrecognized * options are detected as parameters when placed after options that accept one. */ static BOOL process_arguments(int argc, WCHAR *argv[]) { static const WCHAR slashForceTerminate[] = {'/','f',0}; static const WCHAR slashImage[] = {'/','i','m',0}; static const WCHAR slashPID[] = {'/','p','i','d',0}; static const WCHAR slashHelp[] = {'/','?',0}; if (argc > 1) { int i; BOOL has_im = 0, has_pid = 0; /* Only the lone help option is recognized. */ if (argc == 2 && !strcmpW(slashHelp, argv[1])) { taskkill_message(STRING_USAGE); exit(0); } for (i = 1; i < argc; i++) { int got_im = 0, got_pid = 0; if (!strcmpiW(slashForceTerminate, argv[i])) force_termination = 1; /* Options /IM and /PID appear to behave identically, except for * the fact that they cannot be specified at the same time. */ else if ((got_im = !strcmpiW(slashImage, argv[i])) || (got_pid = !strcmpiW(slashPID, argv[i]))) { if (!argv[i + 1]) { taskkill_message_printfW(STRING_MISSING_PARAM, argv[i]); taskkill_message(STRING_USAGE); return FALSE; } if (got_im) has_im = 1; if (got_pid) has_pid = 1; if (has_im && has_pid) { taskkill_message(STRING_MUTUAL_EXCLUSIVE); taskkill_message(STRING_USAGE); return FALSE; } if (!add_to_task_list(argv[i + 1])) return FALSE; i++; } else { taskkill_message(STRING_INVALID_OPTION); taskkill_message(STRING_USAGE); return FALSE; } } } else { taskkill_message(STRING_MISSING_OPTION); taskkill_message(STRING_USAGE); return FALSE; } return TRUE; }
/* FIXME Argument processing does not match behavior observed on Windows. * Stringent argument counting and processing is performed, and unrecognized * options are detected as parameters when placed after options that accept one. */ static BOOL process_arguments(int argc, WCHAR *argv[]) { static const WCHAR opForceTerminate[] = {'f',0}; static const WCHAR opImage[] = {'i','m',0}; static const WCHAR opPID[] = {'p','i','d',0}; static const WCHAR opHelp[] = {'?',0}; static const WCHAR opTerminateChildren[] = {'t',0}; if (argc > 1) { int i; WCHAR *argdata; BOOL has_im = FALSE, has_pid = FALSE; /* Only the lone help option is recognized. */ if (argc == 2) { argdata = argv[1]; if ((*argdata == '/' || *argdata == '-') && !strcmpW(opHelp, argdata + 1)) { taskkill_message(STRING_USAGE); exit(0); } } for (i = 1; i < argc; i++) { BOOL got_im = FALSE, got_pid = FALSE; argdata = argv[i]; if (*argdata != '/' && *argdata != '-') goto invalid; argdata++; if (!strcmpiW(opTerminateChildren, argdata)) WINE_FIXME("argument T not supported\n"); if (!strcmpiW(opForceTerminate, argdata)) force_termination = TRUE; /* Options /IM and /PID appear to behave identically, except for * the fact that they cannot be specified at the same time. */ else if ((got_im = !strcmpiW(opImage, argdata)) || (got_pid = !strcmpiW(opPID, argdata))) { if (!argv[i + 1]) { taskkill_message_printfW(STRING_MISSING_PARAM, argv[i]); taskkill_message(STRING_USAGE); return FALSE; } if (got_im) has_im = TRUE; if (got_pid) has_pid = TRUE; if (has_im && has_pid) { taskkill_message(STRING_MUTUAL_EXCLUSIVE); taskkill_message(STRING_USAGE); return FALSE; } if (!add_to_task_list(argv[i + 1])) return FALSE; i++; } else { invalid: taskkill_message(STRING_INVALID_OPTION); taskkill_message(STRING_USAGE); return FALSE; } } } else { taskkill_message(STRING_MISSING_OPTION); taskkill_message(STRING_USAGE); return FALSE; } return TRUE; }