29 #ifndef COMMAND_QUEUE_MT_H 30 #define COMMAND_QUEUE_MT_H 33 #include "os/semaphore.h" 35 #include "os/memory.h" 36 #include "simple_type.h" 43 struct SyncSemaphore {
51 virtual void call()=0;
52 virtual ~CommandBase() {};
55 template<
class T,
class M>
56 struct Command0 :
public CommandBase {
61 virtual void call() { (instance->*method)(); }
64 template<
class T,
class M,
class P1>
65 struct Command1 :
public CommandBase {
71 virtual void call() { (instance->*method)(p1); }
74 template<
class T,
class M,
class P1,
class P2>
75 struct Command2 :
public CommandBase {
82 virtual void call() { (instance->*method)(p1,p2); }
85 template<
class T,
class M,
class P1,
class P2,
class P3>
86 struct Command3 :
public CommandBase {
94 virtual void call() { (instance->*method)(p1,p2,p3); }
97 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4>
98 struct Command4 :
public CommandBase {
107 virtual void call() { (instance->*method)(p1,p2,p3,p4); }
110 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5>
111 struct Command5 :
public CommandBase {
121 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
124 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6>
125 struct Command6 :
public CommandBase {
136 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
139 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7>
140 struct Command7 :
public CommandBase {
152 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
157 template<
class T,
class M,
class R>
158 struct CommandRet0 :
public CommandBase {
165 virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=
false; ; }
168 template<
class T,
class M,
class P1,
class R>
169 struct CommandRet1 :
public CommandBase {
177 virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=
false; }
180 template<
class T,
class M,
class P1,
class P2,
class R>
181 struct CommandRet2 :
public CommandBase {
190 virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=
false; ; }
193 template<
class T,
class M,
class P1,
class P2,
class P3,
class R>
194 struct CommandRet3 :
public CommandBase {
204 virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=
false; ; }
207 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class R>
208 struct CommandRet4 :
public CommandBase {
219 virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=
false; ; }
222 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class R>
223 struct CommandRet5 :
public CommandBase {
235 virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=
false; ; }
238 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class R>
239 struct CommandRet6 :
public CommandBase {
252 virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=
false; ; }
255 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7,
class R>
256 struct CommandRet7 :
public CommandBase {
270 virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=
false; ; }
277 template<
class T,
class M>
278 struct CommandSync0 :
public CommandBase {
285 virtual void call() { (instance->*method)(); sync->sem->post(); sync->in_use=
false; ; }
288 template<
class T,
class M,
class P1>
289 struct CommandSync1 :
public CommandBase {
297 virtual void call() { (instance->*method)(p1); sync->sem->post(); sync->in_use=
false; ; }
300 template<
class T,
class M,
class P1,
class P2>
301 struct CommandSync2 :
public CommandBase {
310 virtual void call() { (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=
false; ; }
313 template<
class T,
class M,
class P1,
class P2,
class P3>
314 struct CommandSync3 :
public CommandBase {
324 virtual void call() { (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=
false; ; }
327 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4>
328 struct CommandSync4 :
public CommandBase {
339 virtual void call() { (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=
false; ; }
342 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5>
343 struct CommandSync5 :
public CommandBase {
355 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=
false; ; }
358 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6>
359 struct CommandSync6 :
public CommandBase {
372 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=
false; ; }
375 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7>
376 struct CommandSync7 :
public CommandBase {
390 virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=
false; ; }
396 COMMAND_MEM_SIZE_KB=256,
397 COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
402 uint8_t command_mem[COMMAND_MEM_SIZE];
405 SyncSemaphore sync_sems[SYNC_SEMAPHORES];
414 uint32_t alloc_size=
sizeof(T)+
sizeof(uint32_t);
418 if (write_ptr < read_ptr) {
420 if ( (read_ptr-write_ptr) <= alloc_size )
422 }
else if (write_ptr >= read_ptr) {
426 if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
433 ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) <
sizeof(uint32_t), NULL );
436 uint32_t * p = (uint32_t*)&command_mem[write_ptr];
443 uint32_t * p = (uint32_t*)&command_mem[write_ptr];
445 write_ptr+=
sizeof(uint32_t);
447 T* cmd = memnew_placement( &command_mem[write_ptr], T );
448 write_ptr+=
sizeof(T);
454 T* allocate_and_lock() {
459 while ( (ret=allocate<T>())==NULL ) {
477 if (read_ptr == write_ptr )
480 uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
488 read_ptr+=
sizeof(uint32_t);
490 CommandBase *cmd =
reinterpret_cast<CommandBase*
>( &command_mem[read_ptr] );
503 void wait_for_flush();
504 SyncSemaphore* _alloc_sync_sem();
511 template<
class T,
class M>
512 void push( T * p_instance, M p_method ) {
514 Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
516 cmd->instance=p_instance;
517 cmd->method=p_method;
521 if (sync) sync->
post();
524 template<
class T,
class M,
class P1>
525 void push( T * p_instance, M p_method, P1 p1 ) {
527 Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
529 cmd->instance=p_instance;
530 cmd->method=p_method;
535 if (sync) sync->
post();
538 template<
class T,
class M,
class P1,
class P2>
539 void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
541 Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
543 cmd->instance=p_instance;
544 cmd->method=p_method;
550 if (sync) sync->
post();
553 template<
class T,
class M,
class P1,
class P2,
class P3>
554 void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
556 Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
558 cmd->instance=p_instance;
559 cmd->method=p_method;
566 if (sync) sync->
post();
569 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4>
570 void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
572 Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
574 cmd->instance=p_instance;
575 cmd->method=p_method;
583 if (sync) sync->
post();
586 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5>
587 void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
589 Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
591 cmd->instance=p_instance;
592 cmd->method=p_method;
601 if (sync) sync->
post();
604 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6>
605 void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
607 Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
609 cmd->instance=p_instance;
610 cmd->method=p_method;
620 if (sync) sync->
post();
623 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7>
624 void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
626 Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
628 cmd->instance=p_instance;
629 cmd->method=p_method;
640 if (sync) sync->
post();
645 template<
class T,
class M,
class R>
646 void push_and_ret( T * p_instance, M p_method, R* r_ret) {
648 CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
650 cmd->instance=p_instance;
651 cmd->method=p_method;
653 SyncSemaphore *ss=_alloc_sync_sem();
658 if (sync) sync->
post();
662 template<
class T,
class M,
class P1,
class R>
663 void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
665 CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
667 cmd->instance=p_instance;
668 cmd->method=p_method;
671 SyncSemaphore *ss=_alloc_sync_sem();
676 if (sync) sync->
post();
680 template<
class T,
class M,
class P1,
class P2,
class R>
681 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
683 CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
685 cmd->instance=p_instance;
686 cmd->method=p_method;
690 SyncSemaphore *ss=_alloc_sync_sem();
695 if (sync) sync->
post();
699 template<
class T,
class M,
class P1,
class P2,
class P3,
class R>
700 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
702 CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
704 cmd->instance=p_instance;
705 cmd->method=p_method;
710 SyncSemaphore *ss=_alloc_sync_sem();
715 if (sync) sync->
post();
719 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class R>
720 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
722 CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
724 cmd->instance=p_instance;
725 cmd->method=p_method;
731 SyncSemaphore *ss=_alloc_sync_sem();
736 if (sync) sync->
post();
740 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class R>
741 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
743 CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
745 cmd->instance=p_instance;
746 cmd->method=p_method;
753 SyncSemaphore *ss=_alloc_sync_sem();
758 if (sync) sync->
post();
762 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class R>
763 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
765 CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
767 cmd->instance=p_instance;
768 cmd->method=p_method;
776 SyncSemaphore *ss=_alloc_sync_sem();
781 if (sync) sync->
post();
785 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7,
class R>
786 void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
788 CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
790 cmd->instance=p_instance;
791 cmd->method=p_method;
800 SyncSemaphore *ss=_alloc_sync_sem();
805 if (sync) sync->
post();
810 template<
class T,
class M>
811 void push_and_sync( T * p_instance, M p_method) {
813 CommandSync0<T,M> * cmd = allocate_and_lock< CommandSync0<T,M> >();
815 cmd->instance=p_instance;
816 cmd->method=p_method;
818 SyncSemaphore *ss=_alloc_sync_sem();
823 if (sync) sync->
post();
827 template<
class T,
class M,
class P1>
828 void push_and_sync( T * p_instance, M p_method, P1 p1) {
830 CommandSync1<T,M,P1> * cmd = allocate_and_lock< CommandSync1<T,M,P1> >();
832 cmd->instance=p_instance;
833 cmd->method=p_method;
836 SyncSemaphore *ss=_alloc_sync_sem();
841 if (sync) sync->
post();
845 template<
class T,
class M,
class P1,
class P2>
846 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2) {
848 CommandSync2<T,M,P1,P2> * cmd = allocate_and_lock< CommandSync2<T,M,P1,P2> >();
850 cmd->instance=p_instance;
851 cmd->method=p_method;
855 SyncSemaphore *ss=_alloc_sync_sem();
860 if (sync) sync->
post();
864 template<
class T,
class M,
class P1,
class P2,
class P3>
865 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
867 CommandSync3<T,M,P1,P2,P3> * cmd = allocate_and_lock< CommandSync3<T,M,P1,P2,P3> >();
869 cmd->instance=p_instance;
870 cmd->method=p_method;
875 SyncSemaphore *ss=_alloc_sync_sem();
880 if (sync) sync->
post();
884 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4>
885 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
887 CommandSync4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< CommandSync4<T,M,P1,P2,P3,P4> >();
889 cmd->instance=p_instance;
890 cmd->method=p_method;
896 SyncSemaphore *ss=_alloc_sync_sem();
901 if (sync) sync->
post();
905 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5>
906 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
908 CommandSync5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< CommandSync5<T,M,P1,P2,P3,P4,P5> >();
910 cmd->instance=p_instance;
911 cmd->method=p_method;
918 SyncSemaphore *ss=_alloc_sync_sem();
923 if (sync) sync->
post();
927 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6>
928 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
930 CommandSync6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< CommandSync6<T,M,P1,P2,P3,P4,P5,P6> >();
932 cmd->instance=p_instance;
933 cmd->method=p_method;
941 SyncSemaphore *ss=_alloc_sync_sem();
946 if (sync) sync->
post();
950 template<
class T,
class M,
class P1,
class P2,
class P3,
class P4,
class P5,
class P6,
class P7>
951 void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7 ) {
953 CommandSync7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< CommandSync7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
955 cmd->instance=p_instance;
956 cmd->method=p_method;
965 SyncSemaphore *ss=_alloc_sync_sem();
970 if (sync) sync->
post();
974 void wait_and_flush_one() {
975 ERR_FAIL_COND(!sync);
987 bool exit = !flush_one();
Definition: command_queue_mt.h:41
virtual Error post()=0
unlock the semaphore, incrementing the value
virtual Error wait()=0
wait until semaphore has positive value, then decrement and pass
Definition: simple_type.h:41
Definition: semaphore.h:37