1 | /******************************************************************* |
---|
2 | * Computer Algebra System SINGULAR |
---|
3 | * |
---|
4 | * tmult.cc: p_Mult_nn with pthreads - experimental |
---|
5 | * |
---|
6 | *******************************************************************/ |
---|
7 | #ifdef HAVE_CONFIG_H |
---|
8 | #include "singularconfig.h" |
---|
9 | #endif /* HAVE_CONFIG_H */ |
---|
10 | #include <kernel/mod2.h> |
---|
11 | #include <kernel/structs.h> |
---|
12 | #include <kernel/numbers.h> |
---|
13 | #include <kernel/polys.h> |
---|
14 | #include <libpolys/coeffs/longrat.h> |
---|
15 | #ifdef SI_THREADS |
---|
16 | #include <pthread.h> |
---|
17 | #include <stdlib.h> |
---|
18 | #include <stdio.h> |
---|
19 | |
---|
20 | #define NUM_THREADS 8 |
---|
21 | #define THREAD_MIN_LENGTH 10*NUM_THREADS |
---|
22 | |
---|
23 | struct p_Mult_nn_thread_data |
---|
24 | { |
---|
25 | int thread_id; |
---|
26 | poly p; |
---|
27 | number n; |
---|
28 | ring r; |
---|
29 | }; |
---|
30 | |
---|
31 | |
---|
32 | void* p_Mult_nn_doMult(void *threadarg) |
---|
33 | { |
---|
34 | struct p_Mult_nn_thread_data *my_data; |
---|
35 | my_data = (struct p_Mult_nn_thread_data *) threadarg; |
---|
36 | //long taskid = my_data->thread_id; |
---|
37 | poly p = my_data->p; |
---|
38 | number n = my_data->n; |
---|
39 | ring r = my_data->r; |
---|
40 | while (1) |
---|
41 | { |
---|
42 | //if (p==NULL) return NULL; |
---|
43 | if (p==NULL) pthread_exit(NULL); |
---|
44 | nlInpMult(pGetCoeff(p), n,r); |
---|
45 | for (int i=0;i<NUM_THREADS;i++) |
---|
46 | { |
---|
47 | pIter(p); |
---|
48 | if (p==NULL) pthread_exit(NULL); |
---|
49 | //if (p==NULL) return NULL; |
---|
50 | } |
---|
51 | } |
---|
52 | return NULL; |
---|
53 | } |
---|
54 | |
---|
55 | static inline int pLengthOrMore(poly p, int m) |
---|
56 | { |
---|
57 | int l; |
---|
58 | for(l=0;(p!=NULL) && (l<=m); l++) pIter(p); |
---|
59 | return l; |
---|
60 | } |
---|
61 | |
---|
62 | extern "C" poly p_Mult_nn__FieldQ_LengthGeneral_OrdGeneral(poly,const number,const ring); |
---|
63 | |
---|
64 | poly p_Mult_nn_pthread(poly p, const number n, const ring r) |
---|
65 | { |
---|
66 | if (p==NULL) return NULL; |
---|
67 | poly q=p; |
---|
68 | if ((nlSize(n)>2) && (pLengthOrMore(q,THREAD_MIN_LENGTH)>=THREAD_MIN_LENGTH)) |
---|
69 | { |
---|
70 | pthread_t threads[NUM_THREADS]; |
---|
71 | struct p_Mult_nn_thread_data thread_data_array[NUM_THREADS]; |
---|
72 | pthread_attr_t attr; |
---|
73 | /* Initialize and set thread detached attribute */ |
---|
74 | pthread_attr_init(&attr); |
---|
75 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); |
---|
76 | |
---|
77 | int rc; |
---|
78 | int t; |
---|
79 | for(t=0; t<NUM_THREADS; t++) |
---|
80 | { |
---|
81 | //printf("In main: creating thread %ld\n", t); |
---|
82 | thread_data_array[t].thread_id = t; |
---|
83 | thread_data_array[t].p = p; |
---|
84 | thread_data_array[t].n = n; |
---|
85 | thread_data_array[t].r = r; |
---|
86 | //p_Mult_nn_doMult(&(thread_data_array[t])); |
---|
87 | rc = pthread_create(&threads[t], &attr, p_Mult_nn_doMult, |
---|
88 | (void *) &thread_data_array[t]); |
---|
89 | if (rc) |
---|
90 | { |
---|
91 | printf("ERROR; return code from pthread_create() is %d\n", rc); |
---|
92 | exit(-1); |
---|
93 | } |
---|
94 | pIter(p); |
---|
95 | if (p==NULL) break; |
---|
96 | } |
---|
97 | /* Free attribute and wait for the other threads */ |
---|
98 | pthread_attr_destroy(&attr); |
---|
99 | for(t=NUM_THREADS-1; t>=0; t--) |
---|
100 | { |
---|
101 | void *status; |
---|
102 | |
---|
103 | rc = pthread_join(threads[t], &status); |
---|
104 | if (rc) |
---|
105 | { |
---|
106 | printf("ERROR; return code from pthread_join() is %d\n", rc); |
---|
107 | exit(-1); |
---|
108 | } |
---|
109 | } |
---|
110 | |
---|
111 | return q; |
---|
112 | } |
---|
113 | else |
---|
114 | { |
---|
115 | return p_Mult_nn__FieldQ_LengthGeneral_OrdGeneral(p,n,r); |
---|
116 | } |
---|
117 | } |
---|
118 | #endif |
---|