📄 pthread.c
字号:
#ifdef DEF_RR if (policy == SCHED_FIFO || policy == SCHED_RR) {#else if (policy == SCHED_FIFO) {#endif attr->sched = policy; return(0); } else return(EINVAL);}/*------------------------------------------------------------*//* * pthread_attr_setschedparam - set the sched param attribute */int pthread_attr_setschedparam(attr, param) pthread_attr_t *attr; struct sched_param *param;{ PTRACEIN; if (!attr || !attr->flags || !param) return(EINVAL); if (param->sched_priority >= MIN_PRIORITY && param->sched_priority <= MAX_PRIORITY) { attr->param.sched_priority = param->sched_priority; return(0); } else return(EINVAL);}/*------------------------------------------------------------*//* * pthread_attr_getscope - return contentionscope attribute in "contentionscope" */int pthread_attr_getscope(attr, contentionscope) pthread_attr_t *attr; int *contentionscope;{ PTRACEIN; if (!attr || !attr->flags || !contentionscope) return(EINVAL); *contentionscope = attr->contentionscope; return(0);}/*------------------------------------------------------------*//* * pthread_attr_getinheritsched - return inheritsched attr in "inheritsched" */int pthread_attr_getinheritsched(attr, inheritsched) pthread_attr_t *attr; int *inheritsched;{ PTRACEIN; if (!attr || !attr->flags || !inheritsched) return(EINVAL); *inheritsched = attr->inheritsched; return(0);}/*------------------------------------------------------------*//* * pthread_attr_getschedpolicy - get the sched attribute */int pthread_attr_getschedpolicy(attr, policy) pthread_attr_t *attr; int *policy;{ PTRACEIN; if (!attr || !attr->flags || !policy) return(EINVAL); *policy = attr->sched; return(0);}/*------------------------------------------------------------*//* * pthread_attr_getschedparam - return the sched param attr in "param" */int pthread_attr_getschedparam(attr, param) pthread_attr_t *attr; struct sched_param *param;{ PTRACEIN; if (!attr || !attr->flags || !param) return(EINVAL); param->sched_priority = attr->param.sched_priority; return(0);}/*------------------------------------------------------------*//* * pthread_attr_setstarttime_np - set the absolute start time */int pthread_attr_setstarttime_np(attr, tp) pthread_attr_t *attr; struct timespec *tp;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ if (!attr || !attr->flags || !tp || !ISNTIMERSET(*tp)) return(EINVAL); attr->starttime.tv_sec = tp->tv_sec; attr->starttime.tv_nsec = tp->tv_nsec; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_attr_getstarttime_np - get the absolute start time */int pthread_attr_getstarttime_np(attr, tp) pthread_attr_t *attr; struct timespec *tp;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ if (!attr || !attr->flags || !tp || !ISNTIMERSET(attr->starttime)) return(EINVAL); tp->tv_sec = attr->starttime.tv_sec; tp->tv_nsec = attr->starttime.tv_nsec; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_attr_setdeadline_np - set the absolute deadline (XOR period) */int pthread_attr_setdeadline_np(attr, tp, func) pthread_attr_t *attr; struct timespec *tp; pthread_func_t func;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ extern struct sigaction pthread_user_handler[NNSIG]; if (!attr || !attr->flags || !tp || !ISNTIMERSET(*tp) || ISNTIMERSET(attr->period)) return(EINVAL); attr->deadline.tv_sec = tp->tv_sec; attr->deadline.tv_nsec = tp->tv_nsec; sigaddset(&handlerset, TIMER_SIG); pthread_user_handler[TIMER_SIG].sa_handler = (void(*)()) func; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_attr_getdeadline_np - get the absolute deadline */int pthread_attr_getdeadline_np(attr, tp) pthread_attr_t *attr; struct timespec *tp;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ if (!attr || !attr->flags || !tp || !ISNTIMERSET(attr->deadline)) return(EINVAL); tp->tv_sec = attr->deadline.tv_sec; tp->tv_nsec = attr->deadline.tv_nsec; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_attr_setperiod_np - set the relative period (XOR deadline) */int pthread_attr_setperiod_np(attr, tp, func) pthread_attr_t *attr; struct timespec *tp; pthread_func_t func;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ extern struct sigaction pthread_user_handler[NNSIG]; if (!attr || !attr->flags || !tp || !ISNTIMERSET(*tp) || ISNTIMERSET(attr->deadline)) return(EINVAL); attr->period.tv_sec = tp->tv_sec; attr->period.tv_nsec = tp->tv_nsec; sigaddset(&handlerset, TIMER_SIG); pthread_user_handler[TIMER_SIG].sa_handler = (void(*)()) func; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_attr_getperiod_np - get the relative period */int pthread_attr_getperiod_np(attr, tp) pthread_attr_t *attr; struct timespec *tp;{ PTRACEIN;#ifndef REAL_TIME return(ENOSYS);#else /* REAL_TIME */ if (!attr || !attr->flags || !tp || !ISNTIMERSET(attr->period)) return(EINVAL); tp->tv_sec = attr->period.tv_sec; tp->tv_nsec = attr->period.tv_nsec; return(0);#endif /* REAL_TIME */}/*------------------------------------------------------------*//* * pthread_key_create - creates a new global key and spefies destructor call * returns 0 or upon error ENOMEM if name space exhausted, * EAGAIN if insufficient memory. */int pthread_key_create(key, destructor) pthread_key_t *key; void (*destructor)();{ PTRACEIN; SET_KERNEL_FLAG; if (n_keys >= _POSIX_DATAKEYS_MAX) { CLEAR_KERNEL_FLAG; return(ENOMEM); } key_destructor[n_keys] = destructor; *key = n_keys++; CLEAR_KERNEL_FLAG; return(0);}/*------------------------------------------------------------*//* * pthread_key_delete - deletes a thread-specific data key previously * returned by pthread_key_create(). */int pthread_key_delete(key) pthread_key_t key;{ PTRACEIN; if (key < 0 || key >= n_keys) { return(EINVAL); } return(0);}/*------------------------------------------------------------*//* * pthread_setspecific - associate a value with a data key for some thread * return 0 or upon error EINVAL if the key is invalid. */int pthread_setspecific(key, value) pthread_key_t key; any_t value;{ PTRACEIN; if (key < 0 || key >= n_keys) { return(EINVAL); } mac_pthread_self()->key[key] = value; return(0);}/*------------------------------------------------------------*//* * pthread_getspecific - retrieve a value from a data key for some thread * returns NULL upon error if the key is invalid. */any_t pthread_getspecific(key) pthread_key_t key;{ PTRACEIN; if (key < 0 || key >= n_keys) { return(NULL); } return mac_pthread_self()->key[key];}/*------------------------------------------------------------*//* * pthread_cleanup_push - push function on current thread's cleanup stack * and execute it with the specified argument when the thread. * Notice: pthread_cleanup_push_body() receives the address of the first * cleanup structure in an additional parameter "new". * (a) exits; * (b) is cancelled; * (c) calls pthread_cleanup_pop(0 with a non-zero argument; * (d) NOT IMPLEMENTED, CONTROVERSIAL: when a longjump reaches past the scope. */#ifdef CLEANUP_HEAPvoid pthread_cleanup_push(func, arg)#elsevoid pthread_cleanup_push_body(func, arg, new)#endif void (*func)(); any_t arg;#ifdef CLEANUP_HEAP{ pthread_cleanup_t new;#else pthread_cleanup_t new;{#endif pthread_t p = mac_pthread_self(); PTRACEIN; if (!func) { return; }#ifdef CLEANUP_HEAP if (!(new = (pthread_cleanup_t) malloc(sizeof(*new)))) return;#endif new->func = func; new->arg = arg; SET_KERNEL_FLAG; new->next = p->cleanup_top; p->cleanup_top = new; CLEAR_KERNEL_FLAG; return;}/*------------------------------------------------------------*//* * pthread_cleanup_pop - pop function off current thread's cleanup stack * and execute it with the specified argument if non-zero */#ifdef CLEANUP_HEAPvoid pthread_cleanup_pop(execute)#elsevoid pthread_cleanup_pop_body(execute)#endif int execute;{ pthread_t p = mac_pthread_self(); pthread_cleanup_t new; PTRACEIN; SET_KERNEL_FLAG; if (!(new = p->cleanup_top)) { CLEAR_KERNEL_FLAG; return; } p->cleanup_top = new->next; CLEAR_KERNEL_FLAG; if (execute) (new->func)(new->arg);#ifdef CLEANUP_HEAP free(new);#endif return;}/*------------------------------------------------------------*//* * sched_get_priority_max - inquire maximum priority value (part of .4) */int sched_get_priority_max(policy) int policy;{ PTRACEIN; switch (policy) { case SCHED_RR: case SCHED_FIFO: return(MAX_PRIORITY); break; default: set_errno(EINVAL); return(-1); }; return(MAX_PRIORITY);}/*------------------------------------------------------------*//* * sched_get_priority_min - inquire minimum priority value (part of .4) */int sched_get_priority_min(policy) int policy;{ PTRACEIN; switch (policy) { case SCHED_RR: case SCHED_FIFO: return(MIN_PRIORITY); break; default: set_errno(EINVAL); return(-1); }; return(MIN_PRIORITY);}/*------------------------------------------------------------*//* * sched_rr_get_interval - timeslice interval */int sched_rr_get_interval(pid,interval) pid_t pid; struct timespec *interval;{ PTRACEIN; if ( pid && pid != getpid() ) { return(ESRCH); } interval->tv_sec = TIME_SLICE / USEC_PER_SEC; interval->tv_nsec = (TIME_SLICE % USEC_PER_SEC) * NSEC_PER_USEC; return 0;}/*------------------------------------------------------------*//* * pthread_attr_setdetachstate - Sets the detachstate attribute in * attr object */int pthread_attr_setdetachstate(attr, detachstate) pthread_attr_t *attr; int detachstate;{ PTRACEIN; if (!attr || !attr->flags || detachstate > PTHREAD_CREATE_DETACHED || detachstate < PTHREAD_CREATE_JOINABLE) return(EINVAL); attr->detachstate = detachstate; return(0);}/*------------------------------------------------------------*//* * pthread_attr_getdetachstate - Gets the value of detachstate attribute * from attr object */int pthread_attr_getdetachstate(attr, detachstate) pthread_attr_t *attr; int *detachstate;{ PTRACEIN; if (!attr || !attr->flags || !detachstate) return(EINVAL); *detachstate = attr->detachstate; return(0);}/*------------------------------------------------------------*//* * pthread_once - The first call to this will call the init_routine() * with no arguments. Subsequent calls to pthread_once() * will not call the init_routine. */int pthread_once(once_control, init_routine) pthread_once_t *once_control; void (*init_routine)();{ PTRACEIN; SET_KERNEL_FLAG; if (!once_control || !init_routine) return EINVAL; if (!once_control->init) { once_control->init = TRUE; pthread_mutex_init(&once_control->mutex, NULL); } CLEAR_KERNEL_FLAG; pthread_mutex_lock(&once_control->mutex); if (!once_control->exec) { once_control->exec = TRUE; (*init_routine)(); } pthread_mutex_unlock(&once_control->mutex); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -