freebsd compat. layer: remove arbitrary limit on number of created threads available in taskqueue_start_threads.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21077 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -13,8 +13,6 @@
|
||||
#include <compat/sys/taskqueue.h>
|
||||
#include <compat/sys/haiku-module.h>
|
||||
|
||||
#define MAX_TASKQUEUE_THREADS 2
|
||||
|
||||
struct taskqueue {
|
||||
char tq_name[64];
|
||||
mutex tq_mutex;
|
||||
@@ -24,7 +22,8 @@ struct taskqueue {
|
||||
int tq_fast;
|
||||
int32 tq_spinlock;
|
||||
sem_id tq_sem;
|
||||
thread_id tq_threads[MAX_TASKQUEUE_THREADS];
|
||||
thread_id *tq_threads;
|
||||
thread_id tq_thread_storage;
|
||||
int tq_threadcount;
|
||||
};
|
||||
|
||||
@@ -42,17 +41,10 @@ _taskqueue_create(const char *name, int mflags, int fast,
|
||||
|
||||
tq->tq_fast = fast;
|
||||
|
||||
tq->tq_sem = create_sem(0, tq->tq_name);
|
||||
if (tq->tq_sem < B_OK) {
|
||||
free(tq);
|
||||
return tq->tq_sem;
|
||||
}
|
||||
|
||||
if (fast) {
|
||||
tq->tq_spinlock = 0;
|
||||
} else {
|
||||
if (mutex_init(&tq->tq_mutex, name) < B_OK) {
|
||||
delete_sem(tq->tq_sem);
|
||||
free(tq);
|
||||
return NULL;
|
||||
}
|
||||
@@ -63,6 +55,8 @@ _taskqueue_create(const char *name, int mflags, int fast,
|
||||
tq->tq_enqueue = enqueue;
|
||||
tq->tq_arg = context;
|
||||
|
||||
tq->tq_sem = -1;
|
||||
tq->tq_threads = NULL;
|
||||
tq->tq_threadcount = 0;
|
||||
|
||||
return tq;
|
||||
@@ -108,9 +102,15 @@ tq_handle_thread(void *data)
|
||||
cpu_status cpu_state;
|
||||
struct task *t;
|
||||
int pending;
|
||||
sem_id sem;
|
||||
|
||||
/* just a synchronization point */
|
||||
tq_lock(tq, &cpu_state);
|
||||
sem = tq->tq_sem;
|
||||
tq_unlock(tq, cpu_state);
|
||||
|
||||
while (1) {
|
||||
status_t status = acquire_sem(tq->tq_sem);
|
||||
status_t status = acquire_sem(sem);
|
||||
if (status < B_OK)
|
||||
break;
|
||||
|
||||
@@ -137,8 +137,24 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
||||
if (count == 0)
|
||||
return -1;
|
||||
|
||||
if (count > MAX_TASKQUEUE_THREADS)
|
||||
panic("_taskqueue_start_threads, too many threads requested");
|
||||
if (tq->tq_threads != NULL)
|
||||
return -1;
|
||||
|
||||
if (count == 1) {
|
||||
tq->tq_threads = &tq->tq_thread_storage;
|
||||
} else {
|
||||
tq->tq_threads = malloc(sizeof(thread_id) * count);
|
||||
if (tq->tq_threads == NULL)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
tq->tq_sem = create_sem(0, tq->tq_name);
|
||||
if (tq->tq_sem < B_OK) {
|
||||
if (count > 1)
|
||||
free(tq->tq_threads);
|
||||
tq->tq_threads = NULL;
|
||||
return tq->tq_sem;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
tq->tq_threads[i] = spawn_kernel_thread(tq_handle_thread, tq->tq_name,
|
||||
@@ -147,6 +163,10 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
||||
status_t status = tq->tq_threads[i];
|
||||
for (j = 0; j < i; j++)
|
||||
kill_thread(tq->tq_threads[j]);
|
||||
if (count > 1)
|
||||
free(tq->tq_threads);
|
||||
tq->tq_threads = NULL;
|
||||
delete_sem(tq->tq_sem);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -164,10 +184,10 @@ int
|
||||
taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
||||
const char *format, ...)
|
||||
{
|
||||
/* we assume that start_threads is called in a sane place, and
|
||||
* thus don't lock. This is mostly due to the fact that if the
|
||||
* TQ is 'fast', locking it disables interrupts... and then we
|
||||
* can't create semaphores, threads and bananas. */
|
||||
/* we assume that start_threads is called in a sane place, and thus
|
||||
* don't need to be locked. This is mostly due to the fact that if
|
||||
* the TQ is 'fast', locking the TQ disables interrupts... and then
|
||||
* we can't create semaphores, threads and bananas. */
|
||||
|
||||
/* cpu_status state; */
|
||||
char name[64];
|
||||
@@ -201,6 +221,9 @@ taskqueue_free(struct taskqueue *tq)
|
||||
status_t status;
|
||||
wait_for_thread(tq->tq_threads[i], &status);
|
||||
}
|
||||
|
||||
if (tq->tq_threadcount > 1)
|
||||
free(tq->tq_threads);
|
||||
}
|
||||
|
||||
free(tq);
|
||||
@@ -214,7 +237,7 @@ taskqueue_drain(struct taskqueue *tq, struct task *task)
|
||||
|
||||
tq_lock(tq, &status);
|
||||
if (task->ta_pending != 0)
|
||||
panic("unimplemented, taskqueue drain");
|
||||
UNIMPLEMENTED();
|
||||
tq_unlock(tq, status);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user