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