make sure all work is done
[AROS.git] / test / exec / smp / master.c
blob2a86ac51d2f428961c89fdafd7c27bb34667602d
1 /*
2 Copyright © 2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/kernel.h>
12 #include <exec/tasks.h>
13 #include <exec/ports.h>
15 #include "work.h"
18 * This Task sends work out to the "Workers" to process
20 void SMPTestMaster(struct ExecBase *SysBase)
22 struct Task *thisTask = FindTask(NULL);
24 int cpunum = KrnGetCPUNumber();
26 bug("[SMP-Test:Master.%03d] %s: %s task started\n", cpunum, __func__, thisTask->tc_Node.ln_Name);
28 struct SMPMaster *workMaster = thisTask->tc_UserData;
29 struct SMPWorkMessage *workMsg;
30 struct SMPWorker *coreWorker;
32 if (workMaster)
34 IPTR msgWork = (workMaster->smpm_Width * workMaster->smpm_Height) / (256 / workMaster->smpm_WorkerCount);
35 IPTR msgNo;
38 bug("[SMP-Test:Master.%03d] %s: worker list @ 0x%p (%d workers)\n", cpunum, __func__, &workMaster->smpm_Workers, workMaster->smpm_WorkerCount);
39 bug("[SMP-Test:Master.%03d] %s: worker workload = %d\n", cpunum, __func__, msgWork);
42 for (msgNo = 0; msgNo < ((workMaster->smpm_Width * workMaster->smpm_Height)/ msgWork); msgNo++)
44 if ((workMsg = (struct SMPWorkMessage *)AllocMem(sizeof(struct SMPWorkMessage), MEMF_CLEAR)) != NULL)
46 /* prepare the work to be done ... */
47 if (workMaster->smpm_Buddha)
48 workMsg->smpwm_Type = SPMWORKTYPE_BUDDHA;
49 else
50 workMsg->smpwm_Type = SPMWORKTYPE_MANDLEBROT;
51 workMsg->smpwm_Buffer = workMaster->smpm_WorkBuffer;
52 workMsg->smpwm_Width = workMaster->smpm_Width;
53 workMsg->smpwm_Height = workMaster->smpm_Height;
54 workMsg->smpwm_Start = msgNo * msgWork;
55 workMsg->smpwm_End = workMsg->smpwm_Start + msgWork - 1;
56 if ((((workMaster->smpm_Width * workMaster->smpm_Height)/ msgWork) <= (msgNo + 1)) &&
57 (workMsg->smpwm_End < (workMaster->smpm_Width * workMaster->smpm_Height)))
58 workMsg->smpwm_End = workMaster->smpm_Width * workMaster->smpm_Height;
60 /* send out the work to an available worker... */
61 do {
62 ForeachNode(&workMaster->smpm_Workers, coreWorker)
64 if ((workMsg) && (coreWorker->smpw_Node.ln_Type == 1) && (coreWorker->smpw_MsgPort))
66 D(bug("[SMP-Test:Master.%03d] %s: Sending work @ 0x%p to worker @ 0x%p\n", cpunum, __func__, workMsg, coreWorker);)
67 coreWorker->smpw_Node.ln_Type = 0;
68 PutMsg(coreWorker->smpw_MsgPort, (struct Message *)workMsg);
69 workMsg = NULL;
70 break;
73 } while (workMsg);
78 workMaster->smpm_Master = NULL;
79 Signal(workMaster->smpm_MasterPort->mp_SigTask, SIGBREAKF_CTRL_D);
81 D(bug("[SMP-Test:Master.%03d] %s: work complete\n", cpunum, __func__);)