00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include <linux/kernel.h>
00020
#include <linux/module.h>
00021
#include <linux/errno.h>
00022
#include <linux/config.h>
00023
#include <linux/version.h>
00024
#include <asm/uaccess.h>
00025
00026
#include <rtai_schedcore.h>
00027
#include <rtai_sched.h>
00028
#include <rtai_lxrt.h>
00029
#include <rtai_bits.h>
00030
00031
MODULE_LICENSE(
"GPL");
00032
00033 #define MASK0(x) ((unsigned long *)&(x))[0]
00034 #define MASK1(x) ((unsigned long *)&(x))[1]
00035
00036 static int all_set(
BITS *bits,
unsigned long mask)
00037 {
00038
return (bits->mask & mask) == mask;
00039 }
00040
00041 static int any_set(
BITS *bits,
unsigned long mask)
00042 {
00043
return (bits->mask & mask);
00044 }
00045
00046 static int all_clr(
BITS *bits,
unsigned long mask)
00047 {
00048
return (~bits->mask & mask) == mask;
00049 }
00050
00051 static int any_clr(
BITS *bits,
unsigned long mask)
00052 {
00053
return (~bits->mask & mask);
00054 }
00055
00056 static int all_set_and_any_set(
BITS *bits,
unsigned long masks)
00057 {
00058
return (bits->mask &
MASK1(masks)) && (bits->mask &
MASK0(masks)) ==
MASK0(masks);
00059 }
00060
00061 static int all_set_and_all_clr(
BITS *bits,
unsigned long masks)
00062 {
00063
return (bits->mask &
MASK0(masks)) ==
MASK0(masks) && (~bits->mask &
MASK1(masks)) ==
MASK1(masks);
00064 }
00065
00066 static int all_set_and_any_clr(
BITS *bits,
unsigned long masks)
00067 {
00068
return (bits->mask &
MASK0(masks)) ==
MASK0(masks) && (~bits->mask &
MASK1(masks));
00069 }
00070
00071 static int any_set_and_all_clr(
BITS *bits,
unsigned long masks)
00072 {
00073
return (bits->mask &
MASK0(masks)) && (~bits->mask &
MASK1(masks)) ==
MASK1(masks);
00074 }
00075
00076 static int any_set_and_any_clr(
BITS *bits,
unsigned long masks)
00077 {
00078
return (bits->mask &
MASK0(masks)) && (~bits->mask &
MASK1(masks));
00079 }
00080
00081 static int all_clr_and_any_clr(
BITS *bits,
unsigned long masks)
00082 {
00083
return (~bits->mask &
MASK1(masks)) && (~bits->mask &
MASK0(masks)) ==
MASK0(masks);
00084 }
00085
00086 static int all_set_or_any_set(
BITS *bits,
unsigned long masks)
00087 {
00088
return (bits->mask &
MASK1(masks)) || (bits->mask &
MASK0(masks)) ==
MASK0(masks);
00089 }
00090
00091 static int all_set_or_all_clr(
BITS *bits,
unsigned long masks)
00092 {
00093
return (bits->mask &
MASK0(masks)) ==
MASK0(masks) || (~bits->mask &
MASK1(masks)) ==
MASK1(masks);
00094 }
00095
00096 static int all_set_or_any_clr(
BITS *bits,
unsigned long masks)
00097 {
00098
return (bits->mask &
MASK0(masks)) ==
MASK0(masks) || (~bits->mask &
MASK1(masks));
00099 }
00100
00101 static int any_set_or_all_clr(
BITS *bits,
unsigned long masks)
00102 {
00103
return (bits->mask &
MASK0(masks)) || (~bits->mask &
MASK1(masks)) ==
MASK1(masks);
00104 }
00105
00106 static int any_set_or_any_clr(
BITS *bits,
unsigned long masks)
00107 {
00108
return (bits->mask &
MASK0(masks)) || (~bits->mask &
MASK1(masks));
00109 }
00110
00111 static int all_clr_or_any_clr(
BITS *bits,
unsigned long masks)
00112 {
00113
return (~bits->mask &
MASK1(masks)) || (~bits->mask &
MASK0(masks)) ==
MASK0(masks);
00114 }
00115
00116 static void set_bits(
BITS *bits,
unsigned long mask)
00117 {
00118 bits->mask |= mask;
00119 }
00120
00121 static void clr_bits(
BITS *bits,
unsigned long mask)
00122 {
00123 bits->mask &= ~mask;
00124 }
00125
00126 static void set_clr_bits(
BITS *bits,
unsigned long masks)
00127 {
00128 bits->mask = (bits->mask |
MASK0(masks)) & ~
MASK1(masks);
00129 }
00130
00131 static void nop_fun(
BITS *bits,
unsigned long mask)
00132 {
00133 }
00134
00135 static int (*test_fun[])(
BITS *,
unsigned long) = {
00136
all_set,
any_set,
all_clr,
any_clr,
00137
all_set_and_any_set,
all_set_and_all_clr,
all_set_and_any_clr,
00138
any_set_and_all_clr,
any_set_and_any_clr,
00139
all_clr_and_any_clr,
00140
all_set_or_any_set,
all_set_or_all_clr,
all_set_or_any_clr,
00141
any_set_or_all_clr,
any_set_or_any_clr,
00142
all_clr_or_any_clr
00143 };
00144
00145 static void (*exec_fun[])(
BITS *,
unsigned long) = {
00146
set_bits,
clr_bits,
00147
set_clr_bits,
00148
nop_fun
00149 };
00150
00151 void rt_bits_init(
BITS *bits,
unsigned long mask)
00152 {
00153 bits->magic =
RT_BITS_MAGIC;
00154 bits->queue.prev = &(bits->queue);
00155 bits->queue.next = &(bits->queue);
00156 bits->queue.task = 0;
00157 bits->mask = mask;
00158 }
00159
00160 int rt_bits_delete(
BITS *bits)
00161 {
00162
unsigned long flags, schedmap;
00163
RT_TASK *
task;
00164 QUEUE *q;
00165
00166
if (bits->magic !=
RT_BITS_MAGIC) {
00167
return BITS_ERR;
00168 }
00169
00170 schedmap = 0;
00171 q = &bits->queue;
00172
flags = rt_global_save_flags_and_cli();
00173 bits->magic = 0;
00174
while ((q = q->next) != &bits->queue && (
task = q->task)) {
00175 rem_timed_task(
task);
00176
if (
task->state !=
RT_SCHED_READY && (
task->state &= ~(
RT_SCHED_SEMAPHORE |
RT_SCHED_DELAYED)) ==
RT_SCHED_READY) {
00177 enq_ready_task(
task);
00178
#ifdef CONFIG_SMP
00179
set_bit(
task->runnable_on_cpus & 0x1F, &schedmap);
00180
#endif
00181
}
00182 }
00183 RT_SCHEDULE_MAP(schedmap);
00184 rt_global_restore_flags(
flags);
00185
return 0;
00186 }
00187
00188 #define TEST_BUF(x, y) do { (x)->retval = (unsigned long)(y); } while (0)
00189 #define TEST_FUN(x) ((long *)((unsigned long)(x)->retval))[0]
00190 #define TEST_MASK(x) ((unsigned long *)((unsigned long)(x)->retval))[1]
00191
00192 unsigned long rt_get_bits(
BITS *bits)
00193 {
00194
return bits->mask;
00195 }
00196
00197 int rt_bits_reset(
BITS *bits,
unsigned long mask)
00198 {
00199
unsigned long flags, schedmap, oldmask;
00200
RT_TASK *
task;
00201 QUEUE *q;
00202
00203
if (bits->magic !=
RT_BITS_MAGIC) {
00204
return BITS_ERR;
00205 }
00206
00207 schedmap = 0;
00208 q = &bits->queue;
00209
flags = rt_global_save_flags_and_cli();
00210 oldmask = bits->mask;
00211 bits->mask = mask;
00212
while ((q = q->next) != &bits->queue) {
00213
dequeue_blocked(
task = q->task);
00214 rem_timed_task(
task);
00215
if (
task->state !=
RT_SCHED_READY && (
task->state &= ~(
RT_SCHED_SEMAPHORE |
RT_SCHED_DELAYED)) ==
RT_SCHED_READY) {
00216 enq_ready_task(
task);
00217
#ifdef CONFIG_SMP
00218
set_bit(
task->runnable_on_cpus & 0x1F, &schedmap);
00219
#endif
00220
}
00221 }
00222 bits->queue.prev = bits->queue.next = &bits->queue;
00223 RT_SCHEDULE_MAP(schedmap);
00224 rt_global_restore_flags(
flags);
00225
return oldmask;
00226 }
00227
00228 unsigned long rt_bits_signal(
BITS *bits,
int setfun,
unsigned long masks)
00229 {
00230
unsigned long flags, schedmap;
00231
RT_TASK *
task;
00232 QUEUE *q;
00233
00234
if (bits->magic !=
RT_BITS_MAGIC) {
00235
return BITS_ERR;
00236 }
00237
00238 schedmap = 0;
00239 q = &bits->queue;
00240
flags = rt_global_save_flags_and_cli();
00241
exec_fun[setfun](bits, masks);
00242 masks = bits->mask;
00243
while ((q = q->next) != &bits->queue) {
00244
task = q->task;
00245
if (
test_fun[
TEST_FUN(
task)](bits,
TEST_MASK(
task))) {
00246
dequeue_blocked(
task);
00247 rem_timed_task(
task);
00248
if (
task->state !=
RT_SCHED_READY && (
task->state &= ~(
RT_SCHED_SEMAPHORE |
RT_SCHED_DELAYED)) ==
RT_SCHED_READY) {
00249 enq_ready_task(
task);
00250
#ifdef CONFIG_SMP
00251
set_bit(
task->runnable_on_cpus & 0x1F, &schedmap);
00252
#endif
00253
}
00254 }
00255 }
00256 RT_SCHEDULE_MAP(schedmap);
00257 rt_global_restore_flags(
flags);
00258
return masks;
00259 }
00260
00261 int _rt_bits_wait(
BITS *bits,
int testfun,
unsigned long testmasks,
int exitfun,
unsigned long exitmasks,
unsigned long *resulting_mask,
int space)
00262 {
00263
RT_TASK *rt_current;
00264
unsigned long flags, mask;
00265
00266
if (bits->magic !=
RT_BITS_MAGIC) {
00267
return BITS_ERR;
00268 }
00269
00270
flags = rt_global_save_flags_and_cli();
00271
if (!
test_fun[testfun](bits, testmasks)) {
00272
long bits_test[2];
00273 rt_current = RT_CURRENT;
00274
TEST_BUF(rt_current, bits_test);
00275
TEST_FUN(rt_current) = testfun;
00276
TEST_MASK(rt_current) = testmasks;
00277 rt_current->state |=
RT_SCHED_SEMAPHORE;
00278 rem_ready_current(rt_current);
00279
enqueue_blocked(rt_current, &bits->queue, 1);
00280
rt_schedule();
00281 mask = bits->mask;
00282
if (rt_current->blocked_on || bits->magic !=
RT_BITS_MAGIC) {
00283 rt_current->prio_passed_to = NOTHING;
00284 rt_global_restore_flags(
flags);
00285
return BITS_ERR;
00286 }
00287 }
else {
00288 mask = bits->mask;
00289 }
00290
exec_fun[exitfun](bits, exitmasks);
00291 rt_global_restore_flags(
flags);
00292
if (resulting_mask) {
00293
if (space) {
00294 *resulting_mask = mask;
00295 }
else {
00296 rt_copy_to_user(resulting_mask, &mask,
sizeof(mask));
00297 }
00298 }
00299
return 0;
00300 }
00301
00302 int _rt_bits_wait_if(
BITS *bits,
int testfun,
unsigned long testmasks,
int exitfun,
unsigned long exitmasks,
unsigned long *resulting_mask,
int space)
00303 {
00304
unsigned long flags, mask;
00305
00306
if (bits->magic !=
RT_BITS_MAGIC) {
00307
return BITS_ERR;
00308 }
00309
00310
flags = rt_global_save_flags_and_cli();
00311 mask = bits->mask;
00312
if (
test_fun[testfun](bits, testmasks)) {
00313
exec_fun[exitfun](bits, exitmasks);
00314 rt_global_restore_flags(
flags);
00315
return 1;
00316 }
00317 rt_global_restore_flags(
flags);
00318
if (resulting_mask) {
00319
if (space) {
00320 *resulting_mask = mask;
00321 }
else {
00322 rt_copy_to_user(resulting_mask, &mask,
sizeof(mask));
00323 }
00324 }
00325
return 0;
00326 }
00327
00328 int _rt_bits_wait_until(
BITS *bits,
int testfun,
unsigned long testmasks,
int exitfun,
unsigned long exitmasks,
RTIME time,
unsigned long *resulting_mask,
int space)
00329 {
00330
RT_TASK *rt_current;
00331
unsigned long flags, mask;
00332
00333
if (bits->magic !=
RT_BITS_MAGIC) {
00334
return BITS_ERR;
00335 }
00336
00337
flags = rt_global_save_flags_and_cli();
00338
if (!
test_fun[testfun](bits, testmasks)) {
00339
long bits_test[2];
00340 rt_current = RT_CURRENT;
00341
TEST_BUF(rt_current, bits_test);
00342
TEST_FUN(rt_current) = testfun;
00343
TEST_MASK(rt_current) = testmasks;
00344 rt_current->blocked_on = &bits->queue;
00345
if ((rt_current->resume_time = time) > get_time()) {
00346 rt_current->state |= (
RT_SCHED_SEMAPHORE |
RT_SCHED_DELAYED);
00347 rem_ready_current(rt_current);
00348
enqueue_blocked(rt_current, &bits->queue, 1);
00349 enq_timed_task(rt_current);
00350
rt_schedule();
00351 }
else {
00352 rt_current->queue.prev = rt_current->queue.next = &rt_current->queue;
00353 }
00354 mask = bits->mask;
00355
if (bits->magic !=
RT_BITS_MAGIC) {
00356 rt_current->prio_passed_to = NOTHING;
00357 rt_global_restore_flags(
flags);
00358
return BITS_ERR;
00359 }
else if (rt_current->blocked_on) {
00360
dequeue_blocked(rt_current);
00361 rt_global_restore_flags(
flags);
00362
return BITS_TIMOUT;
00363 }
00364 }
else {
00365 mask = bits->mask;
00366 }
00367
exec_fun[exitfun](bits, exitmasks);
00368 rt_global_restore_flags(
flags);
00369
if (resulting_mask) {
00370
if (space) {
00371 *resulting_mask = mask;
00372 }
else {
00373 rt_copy_to_user(resulting_mask, &mask,
sizeof(mask));
00374 }
00375 }
00376
return 0;
00377 }
00378
00379 int _rt_bits_wait_timed(
BITS *bits,
int testfun,
unsigned long testmasks,
int exitfun,
unsigned long exitmasks,
RTIME delay,
unsigned long *resulting_mask,
int space)
00380 {
00381
return _rt_bits_wait_until(bits, testfun, testmasks, exitfun, exitmasks, get_time() + delay, resulting_mask, space);
00382 }
00383
00384
00385
00386
#include <rtai_registry.h>
00387
00388 BITS *
rt_named_bits_init(
const char *bits_name,
unsigned long mask)
00389 {
00390
BITS *bits;
00391
unsigned long name;
00392
00393
if ((bits =
rt_get_adr(name =
nam2num(bits_name)))) {
00394
return bits;
00395 }
00396
if ((bits =
rt_malloc(
sizeof(
SEM)))) {
00397
rt_bits_init(bits, mask);
00398
if (
rt_register(name, bits,
IS_BIT, 0)) {
00399
return bits;
00400 }
00401
rt_bits_delete(bits);
00402 }
00403
rt_free(bits);
00404
return (
BITS *)0;
00405 }
00406
00407 int rt_named_bits_delete(
BITS *bits)
00408 {
00409
if (!
rt_bits_delete(bits)) {
00410
rt_free(bits);
00411 }
00412
return rt_drg_on_adr(bits);
00413 }
00414
00415 void *
rt_bits_init_u(
unsigned long name,
unsigned long mask)
00416 {
00417
BITS *bits;
00418
if (
rt_get_adr(name)) {
00419
return NULL;
00420 }
00421
if ((bits =
rt_malloc(
sizeof(
BITS)))) {
00422
rt_bits_init(bits, mask);
00423
if (
rt_register(name, bits,
IS_BIT, current)) {
00424
return bits;
00425 }
else {
00426
rt_free(bits);
00427 }
00428 }
00429
return NULL;
00430 }
00431
00432 int rt_bits_delete_u(
BITS *bits)
00433 {
00434
if (
rt_bits_delete(bits)) {
00435
return -EFAULT;
00436 }
00437
rt_free(bits);
00438
return rt_drg_on_adr(bits);
00439 }
00440
00441
00442
00443 struct rt_native_fun_entry
rt_bits_entries[] = {
00444 { { 0,
rt_bits_init_u },
BITS_INIT },
00445 { { 0,
rt_bits_delete_u },
BITS_DELETE },
00446 { { 0,
rt_named_bits_init },
NAMED_BITS_INIT },
00447 { { 0,
rt_named_bits_delete },
NAMED_BITS_DELETE },
00448 { { 1,
rt_get_bits },
BITS_GET },
00449 { { 1,
rt_bits_reset },
BITS_RESET },
00450 { { 1,
rt_bits_signal },
BITS_SIGNAL },
00451 { { 1,
_rt_bits_wait },
BITS_WAIT },
00452 { { 1,
_rt_bits_wait_if },
BITS_WAIT_IF },
00453 { { 1,
_rt_bits_wait_until },
BITS_WAIT_UNTIL },
00454 { { 1,
_rt_bits_wait_timed },
BITS_WAIT_TIMED },
00455 { { 0, 0 }, 000 }
00456 };
00457
00458
extern int set_rt_fun_entries(
struct rt_native_fun_entry *entry);
00459
extern void reset_rt_fun_entries(
struct rt_native_fun_entry *entry);
00460
00461 int __rtai_bits_init(
void)
00462 {
00463
return set_rt_fun_entries(
rt_bits_entries);
00464 }
00465
00466 void __rtai_bits_exit(
void)
00467 {
00468
reset_rt_fun_entries(
rt_bits_entries);
00469 }
00470
00471
#ifndef CONFIG_RTAI_BITS_BUILTIN
00472
module_init(__rtai_bits_init);
00473
module_exit(__rtai_bits_exit);
00474
#endif
00475
00476
#ifdef CONFIG_KBUILD
00477
EXPORT_SYMBOL(rt_bits_init);
00478
EXPORT_SYMBOL(rt_bits_delete);
00479
EXPORT_SYMBOL(rt_get_bits);
00480
EXPORT_SYMBOL(rt_bits_reset);
00481
EXPORT_SYMBOL(rt_bits_signal);
00482
EXPORT_SYMBOL(_rt_bits_wait);
00483
EXPORT_SYMBOL(_rt_bits_wait_if);
00484
EXPORT_SYMBOL(_rt_bits_wait_until);
00485
EXPORT_SYMBOL(_rt_bits_wait_timed);
00486
EXPORT_SYMBOL(rt_named_bits_init);
00487
EXPORT_SYMBOL(rt_named_bits_delete);
00488
EXPORT_SYMBOL(rt_bits_init_u);
00489
EXPORT_SYMBOL(rt_bits_delete_u);
00490
#endif