assert (m != NULL && thread != NULL);
assert (thread->next == NULL);
assert (thread->prev == NULL);
+ thread->ref = NULL;
thread->type = THREAD_UNUSED;
thread->hist->total_active--;
}
/* Add new read thread. */
-struct thread *
+void
funcname_thread_add_read_write (int dir, struct thread_master *m,
int (*func) (struct thread *), void *arg, int fd, struct thread **t_ptr,
debugargdef)
if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
{
pthread_mutex_unlock (&m->mtx);
- return NULL;
+ return;
}
#if defined (HAVE_POLL_CALL)
}
if (t_ptr)
- *t_ptr = thread;
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
}
pthread_mutex_unlock (&m->mtx);
-
- return thread;
}
-static struct thread *
+static void
funcname_thread_add_timer_timeval (struct thread_master *m,
int (*func) (struct thread *), int type, void *arg,
struct timeval *time_relative, struct thread **t_ptr, debugargdef)
if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
{
pthread_mutex_unlock (&m->mtx);
- return NULL;
+ return;
}
queue = ((type == THREAD_TIMER) ? m->timer : m->background);
pthread_mutex_unlock (&thread->mtx);
if (t_ptr)
- *t_ptr = thread;
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
}
pthread_mutex_unlock (&m->mtx);
-
- return thread;
}
/* Add timer event thread. */
-struct thread *
+void
funcname_thread_add_timer (struct thread_master *m,
int (*func) (struct thread *), void *arg, long timer,
struct thread **t_ptr, debugargdef)
}
/* Add timer event thread with "millisecond" resolution */
-struct thread *
+void
funcname_thread_add_timer_msec (struct thread_master *m,
int (*func) (struct thread *), void *arg, long timer,
struct thread **t_ptr, debugargdef)
trel.tv_sec = timer / 1000;
trel.tv_usec = 1000*(timer % 1000);
- return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel,
- t_ptr, debugargpass);
+ funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, &trel,
+ t_ptr, debugargpass);
}
/* Add timer event thread with "millisecond" resolution */
-struct thread *
+void
funcname_thread_add_timer_tv (struct thread_master *m,
int (*func) (struct thread *), void *arg, struct timeval *tv,
struct thread **t_ptr, debugargdef)
{
- return funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, tv,
- t_ptr, debugargpass);
+ funcname_thread_add_timer_timeval (m, func, THREAD_TIMER, arg, tv, t_ptr,
+ debugargpass);
}
/* Add a background thread, with an optional millisec delay */
-struct thread *
+void
funcname_thread_add_background (struct thread_master *m,
int (*func) (struct thread *), void *arg, long delay,
struct thread **t_ptr, debugargdef)
trel.tv_usec = 0;
}
- return funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, arg,
- &trel, t_ptr, debugargpass);
+ funcname_thread_add_timer_timeval (m, func, THREAD_BACKGROUND, arg, &trel,
+ t_ptr, debugargpass);
}
/* Add simple event thread. */
-struct thread *
+void
funcname_thread_add_event (struct thread_master *m,
int (*func) (struct thread *), void *arg, int val,
struct thread **t_ptr, debugargdef)
if (t_ptr && *t_ptr) // thread is already scheduled; don't reschedule
{
pthread_mutex_unlock (&m->mtx);
- return NULL;
+ return;
}
thread = thread_get (m, THREAD_EVENT, func, arg, debugargpass);
pthread_mutex_unlock (&thread->mtx);
if (t_ptr)
- *t_ptr = thread;
+ {
+ *t_ptr = thread;
+ thread->ref = t_ptr;
+ }
}
pthread_mutex_unlock (&m->mtx);
-
- return thread;
}
static void
assert(!"Thread should be either in queue or list or array!");
}
+ if (thread->ref)
+ *thread->ref = NULL;
+
thread_add_unuse (thread->master, thread);
done:
{
ret++;
thread_list_delete (&m->event, t);
+ if (t->ref)
+ *t->ref = NULL;
thread_add_unuse (m, t);
}
}
{
ret++;
thread_list_delete (&m->ready, t);
+ if (t->ref)
+ *t->ref = NULL;
thread_add_unuse (m, t);
}
}
if ((thread = thread_trim_head (&m->ready)) != NULL)
{
fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
pthread_mutex_unlock (&m->mtx);
return fetch;
}
if ((thread = thread_trim_head (&m->ready)) != NULL)
{
fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
pthread_mutex_unlock (&m->mtx);
return fetch;
}
if ((thread = thread_trim_head (&m->ready)) != NULL)
{
fetch = thread_run (m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
pthread_mutex_unlock (&m->mtx);
return fetch;
}
}
/* Execute thread */
-struct thread *
+void
funcname_thread_execute (struct thread_master *m,
int (*func)(struct thread *),
void *arg,
dummy.schedfrom_line = fromln;
thread_call (&dummy);
-
- return NULL;
}
/* Thread itself. */
struct thread
{
- thread_type type; /* thread type */
- thread_type add_type; /* thread type */
- struct thread *next; /* next pointer of the thread */
- struct thread *prev; /* previous pointer of the thread */
- struct thread_master *master; /* pointer to the struct thread_master. */
- int (*func) (struct thread *); /* event function */
- void *arg; /* event argument */
+ thread_type type; /* thread type */
+ thread_type add_type; /* thread type */
+ struct thread *next; /* next pointer of the thread */
+ struct thread *prev; /* previous pointer of the thread */
+ struct thread **ref; /* external reference (if given) */
+ struct thread_master *master; /* pointer to the struct thread_master */
+ int (*func) (struct thread *); /* event function */
+ void *arg; /* event argument */
union {
- int val; /* second argument of the event. */
- int fd; /* file descriptor in case of read/write. */
- struct timeval sands; /* rest of time sands value. */
+ int val; /* second argument of the event. */
+ int fd; /* file descriptor in case of r/w */
+ struct timeval sands; /* rest of time sands value. */
} u;
- int index; /* used for timers to store position in queue */
+ int index; /* queue position for timers */
struct timeval real;
- struct cpu_thread_history *hist; /* cache pointer to cpu_history */
- unsigned long yield; /* yield time in us */
- const char *funcname;
- const char *schedfrom;
- int schedfrom_line;
- pthread_mutex_t mtx;
+ struct cpu_thread_history *hist; /* cache pointer to cpu_history */
+ unsigned long yield; /* yield time in microseconds */
+ const char *funcname; /* name of thread function */
+ const char *schedfrom; /* source file thread was scheduled from */
+ int schedfrom_line; /* line number of source file */
+ pthread_mutex_t mtx; /* mutex for thread.c functions */
};
struct cpu_thread_history
extern void thread_master_free (struct thread_master *);
extern void thread_master_free_unused(struct thread_master *);
-extern struct thread *funcname_thread_add_read_write (int dir, struct thread_master *,
+extern void funcname_thread_add_read_write (int dir, struct thread_master *,
int (*)(struct thread *), void *, int, struct thread **, debugargdef);
-extern struct thread *funcname_thread_add_timer (struct thread_master *,
+extern void funcname_thread_add_timer (struct thread_master *,
int (*)(struct thread *), void *, long, struct thread **, debugargdef);
-extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
+extern void funcname_thread_add_timer_msec (struct thread_master *,
int (*)(struct thread *), void *, long, struct thread **, debugargdef);
-extern struct thread *funcname_thread_add_timer_tv (struct thread_master *,
+extern void funcname_thread_add_timer_tv (struct thread_master *,
int (*)(struct thread *), void *, struct timeval *, struct thread **, debugargdef);
-extern struct thread *funcname_thread_add_event (struct thread_master *,
+extern void funcname_thread_add_event (struct thread_master *,
int (*)(struct thread *), void *, int, struct thread **, debugargdef);
-extern struct thread *funcname_thread_add_background (struct thread_master *,
- int (*func)(struct thread *), void *arg, long milliseconds_to_delay,
- struct thread **, debugargdef);
+extern void funcname_thread_add_background (struct thread_master *,
+ int (*)(struct thread *), void *, long, struct thread **, debugargdef);
-extern struct thread *funcname_thread_execute (struct thread_master *,
+extern void funcname_thread_execute (struct thread_master *,
int (*)(struct thread *), void *, int, debugargdef);
#undef debugargdef